Module Name: src Committed By: isaki Date: Fri Jan 3 05:54:07 UTC 2025
Modified Files: src/sys/arch/m68k/fpe: fpu_fstore.c Log Message: m68k/fpe: Check an illegal mod/reg before decoding it. This avoids a kernel panic if an instruction has illegal mod/reg bits like FMOVE.X FPn,#imm (Of course normally assemblers never emit these). XXX Other instructions probably need such treatment... To generate a diff of this commit: cvs rdiff -u -r1.15 -r1.16 src/sys/arch/m68k/fpe/fpu_fstore.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/m68k/fpe/fpu_fstore.c diff -u src/sys/arch/m68k/fpe/fpu_fstore.c:1.15 src/sys/arch/m68k/fpe/fpu_fstore.c:1.16 --- src/sys/arch/m68k/fpe/fpu_fstore.c:1.15 Fri Jan 3 05:42:50 2025 +++ src/sys/arch/m68k/fpe/fpu_fstore.c Fri Jan 3 05:54:07 2025 @@ -1,4 +1,4 @@ -/* $NetBSD: fpu_fstore.c,v 1.15 2025/01/03 05:42:50 isaki Exp $ */ +/* $NetBSD: fpu_fstore.c,v 1.16 2025/01/03 05:54:07 isaki Exp $ */ /* * Copyright (c) 1995 Ken Nakata @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: fpu_fstore.c,v 1.15 2025/01/03 05:42:50 isaki Exp $"); +__KERNEL_RCSID(0, "$NetBSD: fpu_fstore.c,v 1.16 2025/01/03 05:54:07 isaki Exp $"); #include <sys/types.h> #include <sys/signal.h> @@ -49,6 +49,7 @@ fpu_emul_fstore(struct fpemu *fe, struct int word1, sig; int regnum; int format; + int modreg; uint32_t buf[3]; #if DEBUG_FPE @@ -88,8 +89,17 @@ fpu_emul_fstore(struct fpemu *fe, struct fe->fe_fpsr &= ~FPSR_EXCP; - /* Get effective address. (modreg=opcode&077) */ - sig = fpu_decode_ea(frame, insn, &insn->is_ea, insn->is_opcode); + /* Check an illegal mod/reg */ + modreg = insn->is_opcode & 077; + if ((modreg >> 3) == 1/*An*/ || modreg >= 072/*PCrel and #imm*/) { +#if DEBUG_FPE + printf(" fpu_emul_fstore: illegal modreg=0%o\n", modreg); +#endif + return SIGILL; + } + + /* Get effective address. */ + sig = fpu_decode_ea(frame, insn, &insn->is_ea, modreg); if (sig) { #if DEBUG_FPE printf(" fpu_emul_fstore: failed in decode_ea sig=%d\n", sig);