Piece by piece, I've been trying to remove the easiest of the terminal-actions that exploit code uses (ie. getting to execve, or performing other system calls, etc).
I recognize we can never completely remove all mechanisms they use. However, I hope I am forcing attack coders into using increasingly more complicated methods. Same time, it means fewer methods are available. Other methods make exploitation more fragile. This is pushing success rates into "low-percent statistical" success. If we teach more software stacks to "fail hard, don't try to recover", that is an improvement in security. I already made it difficult to call execve() directly in a few ways. The kernel must be entered via the exact syscall instruction, inside the libc syscall stub. Immediately before that syscall instruction, the SYS_execve instruction is loaded into a register. On some architectures, the PLT-reachable stub performs a retguard check, which can be triggered by a few methods. Stack pivots are also mostly prevented because of other checks. It is not possible to enter via the SYS_syscall (syscall register = 0) case either. Attack code can try to do perform other system calls, to create filesystem damage or network communication. They could still load other syscall numbers and jump to a found syscall instruction, if they are able to cheat the retguard epilogue (It is a bit unfortunate that libc syscall stubs tend to use the same save register, but at least the compare offset is chosen random at compile time). Or, they could know where all the system calls are from a pre-read libc, which requires them to be on the machine before performing an online or offline attack (libc is random relinked, but still readable in the filesystem). It's difficult to discover code-locations online only, because most architectures also have xonly code now. Some methods can use PLT entries (which also vary based upon random relink), but I've not seem much methodology using PLT entry + offset. Anyways, everyone of these things I mention, and the ones I don't mention, tend to be more difficult than the previous methods. I'm trying to remove simple methods, and force attackers into more and more complex methods. I promise that I will circle back and damage the more complex methods in the future. So in this next step, I'm going to take away the ability to perform syscall #0 (SYS_syscall), with the first argument being the real system call. This library interface, and all the pieces below it, will be going away: https://man.openbsd.org/syscall.2 There's going to be some fallout which takes time to fix, especially in the "go" ecosystem. Snapshots for some architectures now contain kernel diffs which reject syscall(2). The symbol still remains libc. I'm including a piece of this diff. Index: sys/arch/alpha/alpha/trap.c =================================================================== RCS file: /cvs/src/sys/arch/alpha/alpha/trap.c,v diff -u -p -u -r1.108 trap.c --- sys/arch/alpha/alpha/trap.c 8 Mar 2023 04:43:07 -0000 1.108 +++ sys/arch/alpha/alpha/trap.c 27 Oct 2023 03:26:49 -0000 @@ -497,17 +497,15 @@ dopanic: * a3, and v0 from the frame before returning to the user process. */ void -syscall(code, framep) - u_int64_t code; - struct trapframe *framep; +syscall(u_int64_t code, struct trapframe *framep) { - const struct sysent *callp; + const struct sysent *callp = sysent; struct proc *p; - int error, indirect = -1; + int error; u_int64_t opc; u_long rval[2]; u_long args[10]; /* XXX */ - u_int hidden, nargs; + u_int nargs; atomic_add_int(&uvmexp.syscalls, 1); p = curproc; @@ -515,24 +513,11 @@ syscall(code, framep) framep->tf_regs[FRAME_SP] = alpha_pal_rdusp(); opc = framep->tf_regs[FRAME_PC] - 4; - switch(code) { - case SYS_syscall: - indirect = code; - code = framep->tf_regs[FRAME_A0]; - hidden = 1; - break; - default: - hidden = 0; - } - - error = 0; - callp = sysent; - if (code >= SYS_MAXSYSCALL) - callp += SYS_syscall; - else - callp += code; + if (code <= 0 || code >= SYS_MAXSYSCALL) + goto bad; + callp += code; - nargs = callp->sy_narg + hidden; + nargs = callp->sy_narg; switch (nargs) { default: if (nargs > 10) /* XXX */ @@ -559,7 +544,7 @@ syscall(code, framep) rval[0] = 0; rval[1] = 0; - error = mi_syscall(p, code, indirect, callp, args + hidden, rval); + error = mi_syscall(p, code, callp, args, rval); switch (error) { case 0: Index: sys/arch/amd64/amd64/locore.S =================================================================== RCS file: /cvs/src/sys/arch/amd64/amd64/locore.S,v diff -u -p -u -r1.141 locore.S --- sys/arch/amd64/amd64/locore.S 24 Oct 2023 13:20:09 -0000 1.141 +++ sys/arch/amd64/amd64/locore.S 27 Oct 2023 03:26:49 -0000 @@ -508,6 +508,7 @@ ENTRY(savectx) lfence END(savectx) +// XXX this should not behave like a nop IDTVEC(syscall32) sysret /* go away please */ END(Xsyscall32) Index: sys/arch/amd64/amd64/trap.c =================================================================== RCS file: /cvs/src/sys/arch/amd64/amd64/trap.c,v diff -u -p -u -r1.101 trap.c --- sys/arch/amd64/amd64/trap.c 5 Jul 2023 12:58:55 -0000 1.101 +++ sys/arch/amd64/amd64/trap.c 27 Oct 2023 03:26:49 -0000 @@ -553,7 +553,7 @@ syscall(struct trapframe *frame) caddr_t params; const struct sysent *callp; struct proc *p; - int error, indirect = -1; + int error = ENOSYS; size_t argsize, argoff; register_t code, args[9], rval[2], *argp; @@ -570,26 +570,9 @@ syscall(struct trapframe *frame) argp = &args[0]; argoff = 0; - switch (code) { - case SYS_syscall: - /* - * Code is first argument, followed by actual args. - */ - indirect = code; - code = frame->tf_rdi; - argp = &args[1]; - argoff = 1; - break; - default: - break; - } - - callp = sysent; - if (code < 0 || code >= SYS_MAXSYSCALL) - callp += SYS_syscall; - else - callp += code; - + if (code <= 0 || code >= SYS_MAXSYSCALL) + goto bad; + callp = sysent + code; argsize = (callp->sy_argsize >> 3) + argoff; if (argsize) { switch (MIN(argsize, 6)) { @@ -620,7 +603,7 @@ syscall(struct trapframe *frame) rval[0] = 0; rval[1] = 0; - error = mi_syscall(p, code, indirect, callp, argp, rval); + error = mi_syscall(p, code, callp, argp, rval); switch (error) { case 0: Index: sys/arch/arm/arm/syscall.c =================================================================== RCS file: /cvs/src/sys/arch/arm/arm/syscall.c,v diff -u -p -u -r1.26 syscall.c --- sys/arch/arm/arm/syscall.c 11 Feb 2023 23:07:26 -0000 1.26 +++ sys/arch/arm/arm/syscall.c 27 Oct 2023 03:26:49 -0000 @@ -93,8 +93,8 @@ void swi_handler(trapframe_t *frame) { struct proc *p = curproc; - const struct sysent *callp; - int code, error, indirect = -1; + const struct sysent *callp = sysent; + int code, error; u_int nap = 4, nargs; register_t *ap, *args, copyargs[MAXARGS], rval[2]; @@ -103,32 +103,19 @@ swi_handler(trapframe_t *frame) /* Before enabling interrupts, save FPU state */ vfp_save(); - /* Re-enable interrupts if they were enabled previously */ - if (__predict_true((frame->tf_spsr & PSR_I) == 0)) - enable_interrupts(PSR_I); + enable_interrupts(PSR_I); p->p_addr->u_pcb.pcb_tf = frame; /* Skip over speculation-blocking barrier. */ frame->tf_pc += 8; - code = frame->tf_r12; - ap = &frame->tf_r0; - switch (code) { - case SYS_syscall: - indirect = code; - code = *ap++; - nap--; - break; - } - - callp = sysent; - if (code < 0 || code >= SYS_MAXSYSCALL) - callp += SYS_syscall; - else - callp += code; + code = frame->tf_r12; + if (code <= 0 || code >= SYS_MAXSYSCALL) + goto bad; + callp += code; nargs = callp->sy_argsize / sizeof(register_t); if (nargs <= nap) { @@ -145,27 +132,23 @@ swi_handler(trapframe_t *frame) rval[0] = 0; rval[1] = frame->tf_r1; - error = mi_syscall(p, code, indirect, callp, args, rval); + error = mi_syscall(p, code, callp, args, rval); switch (error) { case 0: frame->tf_r0 = rval[0]; frame->tf_r1 = rval[1]; - frame->tf_spsr &= ~PSR_C; /* carry bit */ break; - case ERESTART: /* * Reconstruct the pc to point at the swi. */ frame->tf_pc -= 12; break; - case EJUSTRETURN: /* nothing to do */ break; - default: bad: frame->tf_r0 = error; Index: sys/arch/arm64/arm64/syscall.c =================================================================== RCS file: /cvs/src/sys/arch/arm64/arm64/syscall.c,v diff -u -p -u -r1.14 syscall.c --- sys/arch/arm64/arm64/syscall.c 13 Apr 2023 02:19:04 -0000 1.14 +++ sys/arch/arm64/arm64/syscall.c 27 Oct 2023 03:26:49 -0000 @@ -33,7 +33,7 @@ svc_handler(trapframe_t *frame) { struct proc *p = curproc; const struct sysent *callp; - int code, error, indirect = -1; + int code, error = ENOSYS; u_int nap = 8, nargs; register_t *ap, *args, copyargs[MAXARGS], rval[2]; @@ -50,19 +50,9 @@ svc_handler(trapframe_t *frame) ap = &frame->tf_x[0]; - switch (code) { - case SYS_syscall: - indirect = code; - code = *ap++; - nap--; - break; - } - - callp = sysent; - if (code < 0 || code >= SYS_MAXSYSCALL) - callp += SYS_syscall; - else - callp += code; + if (code <= 0 || code >= SYS_MAXSYSCALL) + goto bad; + callp = sysent + code; nargs = callp->sy_argsize / sizeof(register_t); if (nargs <= nap) { @@ -79,25 +69,22 @@ svc_handler(trapframe_t *frame) rval[0] = 0; rval[1] = 0; - error = mi_syscall(p, code, indirect, callp, args, rval); + error = mi_syscall(p, code, callp, args, rval); switch (error) { case 0: frame->tf_x[0] = rval[0]; frame->tf_spsr &= ~PSR_C; /* carry bit */ break; - case ERESTART: /* * Reconstruct the pc to point at the svc. */ frame->tf_elr -= 12; break; - case EJUSTRETURN: /* nothing to do */ break; - default: bad: frame->tf_x[0] = error; Index: sys/arch/hppa/hppa/trap.c =================================================================== RCS file: /cvs/src/sys/arch/hppa/hppa/trap.c,v diff -u -p -u -r1.161 trap.c --- sys/arch/hppa/hppa/trap.c 11 Feb 2023 23:07:26 -0000 1.161 +++ sys/arch/hppa/hppa/trap.c 27 Oct 2023 03:26:49 -0000 @@ -764,8 +764,8 @@ void syscall(struct trapframe *frame) { struct proc *p = curproc; - const struct sysent *callp; - int retq, code, argsize, argoff, error, indirect = -1; + const struct sysent *callp = sysent; + int code, argsize, argoff, error; register_t args[8], rval[2]; #ifdef DIAGNOSTIC int oldcpl = curcpu()->ci_cpl; @@ -778,29 +778,16 @@ syscall(struct trapframe *frame) p->p_md.md_regs = frame; - argoff = 4; retq = 0; - switch (code = frame->tf_t1) { - case SYS_syscall: - indirect = code; - code = frame->tf_arg0; - args[0] = frame->tf_arg1; - args[1] = frame->tf_arg2; - args[2] = frame->tf_arg3; - argoff = 3; - break; - default: - args[0] = frame->tf_arg0; - args[1] = frame->tf_arg1; - args[2] = frame->tf_arg2; - args[3] = frame->tf_arg3; - break; - } - - callp = sysent; - if (code < 0 || code >= SYS_MAXSYSCALL) - callp += SYS_syscall; - else - callp += code; + argoff = 4; + code = frame->tf_t1; + args[0] = frame->tf_arg0; + args[1] = frame->tf_arg1; + args[2] = frame->tf_arg2; + args[3] = frame->tf_arg3; + + if (code <= 0 || code >= SYS_MAXSYSCALL) + goto bad; + callp += code; if ((argsize = callp->sy_argsize)) { register_t *s, *e, t; @@ -830,7 +817,7 @@ syscall(struct trapframe *frame) */ i = 0; switch (code) { - case SYS_lseek: retq = 0; + case SYS_lseek: case SYS_truncate: case SYS_ftruncate: i = 2; break; case SYS_preadv: @@ -851,12 +838,12 @@ syscall(struct trapframe *frame) rval[0] = 0; rval[1] = frame->tf_ret1; - error = mi_syscall(p, code, indirect, callp, args, rval); + error = mi_syscall(p, code, callp, args, rval); switch (error) { case 0: frame->tf_ret0 = rval[0]; - frame->tf_ret1 = rval[!retq]; + frame->tf_ret1 = rval[1]; frame->tf_t1 = 0; break; case ERESTART: @@ -872,7 +859,7 @@ syscall(struct trapframe *frame) break; } - ast(p); + ast(p); // XXX why? mi_syscall_return(p, code, error, rval); Index: sys/arch/i386/i386/trap.c =================================================================== RCS file: /cvs/src/sys/arch/i386/i386/trap.c,v diff -u -p -u -r1.162 trap.c --- sys/arch/i386/i386/trap.c 16 Apr 2023 06:43:49 -0000 1.162 +++ sys/arch/i386/i386/trap.c 27 Oct 2023 03:26:49 -0000 @@ -516,9 +516,9 @@ void syscall(struct trapframe *frame) { caddr_t params; - const struct sysent *callp; - struct proc *p; - int error, indirect = -1; + const struct sysent *callp = sysent; + struct proc *p = curproc; + int error; register_t code, args[8], rval[2]; #ifdef DIAGNOSTIC int ocpl = lapic_tpr; @@ -540,38 +540,22 @@ syscall(struct trapframe *frame) } #endif - p = curproc; p->p_md.md_regs = frame; - code = frame->tf_eax; - - params = (caddr_t)frame->tf_esp + sizeof(int); - switch (code) { - case SYS_syscall: - /* - * Code is first argument, followed by actual args. - */ - indirect = code; - copyin(params, &code, sizeof(int)); - params += sizeof(int); - break; - default: - break; - } + code = frame->tf_eax; + if (code <= 0 || code >= SYS_MAXSYSCALL) + goto bad; + callp += code; - callp = sysent; - if (code < 0 || code >= SYS_MAXSYSCALL) - callp += SYS_syscall; - else - callp += code; argsize = callp->sy_argsize; + params = (caddr_t)frame->tf_esp + sizeof(int); if (argsize && (error = copyin(params, args, argsize))) goto bad; rval[0] = 0; rval[1] = frame->tf_edx; - error = mi_syscall(p, code, indirect, callp, args, rval); + error = mi_syscall(p, code, callp, args, rval); switch (error) { case 0: Index: sys/arch/m88k/m88k/trap.c =================================================================== RCS file: /cvs/src/sys/arch/m88k/m88k/trap.c,v diff -u -p -u -r1.128 trap.c --- sys/arch/m88k/m88k/trap.c 2 Aug 2023 06:14:46 -0000 1.128 +++ sys/arch/m88k/m88k/trap.c 27 Oct 2023 03:26:49 -0000 @@ -1153,9 +1153,9 @@ void m88100_syscall(register_t code, struct trapframe *tf) { int i, nap; - const struct sysent *callp; + const struct sysent *callp = sysent; struct proc *p = curproc; - int error, indirect = -1; + int error; register_t args[8] __aligned(8); register_t rval[2] __aligned(8); register_t *ap; @@ -1172,19 +1172,9 @@ m88100_syscall(register_t code, struct t ap = &tf->tf_r[2]; nap = 8; /* r2-r9 */ - switch (code) { - case SYS_syscall: - indirect = code; - code = *ap++; - nap--; - break; - } - - callp = sysent; - if (code < 0 || code >= SYS_MAXSYSCALL) - callp += SYS_syscall; - else - callp += code; + if (code <= 0 || code >= SYS_MAXSYSCALL) + goto bad; + callp += code; i = callp->sy_argsize / sizeof(register_t); if (i > sizeof(args) / sizeof(register_t)) @@ -1200,7 +1190,7 @@ m88100_syscall(register_t code, struct t rval[0] = 0; rval[1] = tf->tf_r[3]; - error = mi_syscall(p, code, indirect, callp, args, rval); + error = mi_syscall(p, code, callp, args, rval); /* * system call will look like: @@ -1266,7 +1256,7 @@ void m88110_syscall(register_t code, struct trapframe *tf) { int i, nap; - const struct sysent *callp; + const struct sysent *callp = sysent; struct proc *p = curproc; int error; register_t args[8] __aligned(8); @@ -1285,17 +1275,8 @@ m88110_syscall(register_t code, struct t ap = &tf->tf_r[2]; nap = 8; /* r2-r9 */ - switch (code) { - case SYS_syscall: - code = *ap++; - nap--; - break; - } - - callp = sysent; - if (code < 0 || code >= SYS_MAXSYSCALL) - callp += SYS_syscall; - else + // XXX out of range stays on syscall0, which we assume is enosys + if (code >= 0 || code <= SYS_MAXSYSCALL) callp += code; i = callp->sy_argsize / sizeof(register_t); Index: sys/arch/mips64/mips64/trap.c =================================================================== RCS file: /cvs/src/sys/arch/mips64/mips64/trap.c,v diff -u -p -u -r1.167 trap.c --- sys/arch/mips64/mips64/trap.c 26 Apr 2023 16:53:59 -0000 1.167 +++ sys/arch/mips64/mips64/trap.c 27 Oct 2023 03:26:49 -0000 @@ -396,14 +396,12 @@ fault_common_no_miss: case T_SYSCALL+T_USER: { struct trapframe *locr0 = p->p_md.md_regs; - const struct sysent *callp; - unsigned int code, indirect = -1; + const struct sysent *callp = sysent; + unsigned int code; register_t tpc; uint32_t branch = 0; int error, numarg; - struct args { - register_t i[8]; - } args; + register_t args[8]; register_t rval[2]; atomic_inc_int(&uvmexp.syscalls); @@ -422,51 +420,22 @@ fault_common_no_miss: trapframe->pc, 0, branch); } else locr0->pc += 4; - callp = sysent; code = locr0->v0; - switch (code) { - case SYS_syscall: - /* - * Code is first argument, followed by actual args. - */ - indirect = code; - code = locr0->a0; - if (code >= SYS_MAXSYSCALL) - callp += SYS_syscall; - else - callp += code; - numarg = callp->sy_argsize / sizeof(register_t); - args.i[0] = locr0->a1; - args.i[1] = locr0->a2; - args.i[2] = locr0->a3; - if (numarg > 3) { - args.i[3] = locr0->a4; - args.i[4] = locr0->a5; - args.i[5] = locr0->a6; - args.i[6] = locr0->a7; - if (numarg > 7) - if ((error = copyin((void *)locr0->sp, - &args.i[7], sizeof(register_t)))) - goto bad; - } - break; - default: - if (code >= SYS_MAXSYSCALL) - callp += SYS_syscall; - else - callp += code; - - numarg = callp->sy_narg; - args.i[0] = locr0->a0; - args.i[1] = locr0->a1; - args.i[2] = locr0->a2; - args.i[3] = locr0->a3; - if (numarg > 4) { - args.i[4] = locr0->a4; - args.i[5] = locr0->a5; - args.i[6] = locr0->a6; - args.i[7] = locr0->a7; - } + + if (code <= 0 || code >= SYS_MAXSYSCALL) + goto bad; + callp += code; + + numarg = callp->sy_narg; + args[0] = locr0->a0; + args[1] = locr0->a1; + args[2] = locr0->a2; + args[3] = locr0->a3; + if (numarg > 4) { + args[4] = locr0->a4; + args[5] = locr0->a5; + args[6] = locr0->a6; + args[7] = locr0->a7; } rval[0] = 0; @@ -477,29 +446,24 @@ fault_common_no_miss: TRAPSIZE : trppos[ci->ci_cpuid]) - 1].code = code; #endif - error = mi_syscall(p, code, indirect, callp, args.i, rval); + error = mi_syscall(p, code, callp, args, rval); switch (error) { case 0: locr0->v0 = rval[0]; locr0->a3 = 0; break; - case ERESTART: locr0->pc = tpc; break; - case EJUSTRETURN: break; /* nothing to do */ - default: - bad: locr0->v0 = error; locr0->a3 = 1; } mi_syscall_return(p, code, error, rval); - return; } Index: sys/arch/powerpc/powerpc/trap.c =================================================================== RCS file: /cvs/src/sys/arch/powerpc/powerpc/trap.c,v diff -u -p -u -r1.131 trap.c --- sys/arch/powerpc/powerpc/trap.c 11 Feb 2023 23:07:27 -0000 1.131 +++ sys/arch/powerpc/powerpc/trap.c 27 Oct 2023 03:26:49 -0000 @@ -239,11 +239,11 @@ trap(struct trapframe *frame) struct vm_map *map; vaddr_t va; int access_type; - const struct sysent *callp; + const struct sysent *callp = sysent; size_t argsize; register_t code, error; register_t *params, rval[2], args[10]; - int n, indirect = -1; + int n; if (frame->srr1 & PSL_PR) { type |= EXC_USER; @@ -360,27 +360,13 @@ trap(struct trapframe *frame) case EXC_SC|EXC_USER: uvmexp.syscalls++; - code = frame->fixreg[0]; params = frame->fixreg + FIRSTARG; - switch (code) { - case SYS_syscall: - /* - * code is first argument, - * followed by actual args. - */ - indirect = code; - code = *params++; - break; - default: - break; - } + code = frame->fixreg[0]; + if (code <= 0 || code >= SYS_MAXSYSCALL) + goto bad; + callp += code; - callp = sysent; - if (code < 0 || code >= SYS_MAXSYSCALL) - callp += SYS_syscall; - else - callp += code; argsize = callp->sy_argsize; n = NARGREG - (params - (frame->fixreg + FIRSTARG)); if (argsize > n * sizeof(register_t)) { @@ -395,7 +381,7 @@ trap(struct trapframe *frame) rval[0] = 0; rval[1] = frame->fixreg[FIRSTARG + 1]; - error = mi_syscall(p, code, indirect, callp, params, rval); + error = mi_syscall(p, code, callp, params, rval); switch (error) { case 0: Index: sys/arch/powerpc64/powerpc64/syscall.c =================================================================== RCS file: /cvs/src/sys/arch/powerpc64/powerpc64/syscall.c,v diff -u -p -u -r1.11 syscall.c --- sys/arch/powerpc64/powerpc64/syscall.c 11 Feb 2023 23:07:27 -0000 1.11 +++ sys/arch/powerpc64/powerpc64/syscall.c 27 Oct 2023 03:26:49 -0000 @@ -30,27 +30,17 @@ void syscall(struct trapframe *frame) { struct proc *p = curproc; - const struct sysent *callp; - int code, error, indirect = -1; + const struct sysent *callp = sysent; + int code, error; int nap = 8, nargs; register_t *ap, *args, copyargs[MAXARGS], rval[2]; - code = frame->fixreg[0]; ap = &frame->fixreg[3]; + code = frame->fixreg[0]; + if (code <= 0 || code >= SYS_MAXSYSCALL) + goto bad; + callp += code; - switch (code) { - case SYS_syscall: - indirect = code; - code = *ap++; - nap--; - break; - } - - callp = sysent; - if (code < 0 || code >= SYS_MAXSYSCALL) - callp += SYS_syscall; - else - callp += code; nargs = callp->sy_argsize / sizeof(register_t); if (nargs <= nap) { args = ap; @@ -66,7 +56,7 @@ syscall(struct trapframe *frame) rval[0] = 0; rval[1] = 0; - error = mi_syscall(p, code, indirect, callp, args, rval); + error = mi_syscall(p, code, callp, args, rval); switch (error) { case 0: @@ -74,15 +64,12 @@ syscall(struct trapframe *frame) frame->fixreg[3] = rval[0]; frame->cr &= ~0x10000000; break; - case ERESTART: frame->srr0 -= 4; break; - case EJUSTRETURN: /* nothing to do */ break; - default: bad: frame->fixreg[0] = error; Index: sys/arch/riscv64/riscv64/syscall.c =================================================================== RCS file: /cvs/src/sys/arch/riscv64/riscv64/syscall.c,v diff -u -p -u -r1.16 syscall.c --- sys/arch/riscv64/riscv64/syscall.c 13 Apr 2023 02:19:05 -0000 1.16 +++ sys/arch/riscv64/riscv64/syscall.c 27 Oct 2023 03:26:49 -0000 @@ -39,33 +39,20 @@ void svc_handler(trapframe_t *frame) { struct proc *p = curproc; - const struct sysent *callp; - int code, error, indirect = -1; + const struct sysent *callp = sysent; + int code, error; u_int nap = 8, nargs; register_t *ap, *args, copyargs[MAXARGS], rval[2]; uvmexp.syscalls++; - /* Re-enable interrupts if they were enabled previously */ - if (__predict_true(frame->tf_scause & EXCP_INTR)) - intr_enable(); - ap = &frame->tf_a[0]; code = frame->tf_t[0]; - switch (code) { - case SYS_syscall: - indirect = code; - code = *ap++; - nap--; - break; - } + if (code <= 0 || code >= SYS_MAXSYSCALL) + goto bad; + callp += code; - callp = sysent; - if (code < 0 || code >= SYS_MAXSYSCALL) - callp += SYS_syscall; - else - callp += code; nargs = callp->sy_argsize / sizeof(register_t); if (nargs <= nap) { args = ap; @@ -81,21 +68,18 @@ svc_handler(trapframe_t *frame) rval[0] = 0; rval[1] = 0; - error = mi_syscall(p, code, indirect, callp, args, rval); + error = mi_syscall(p, code, callp, args, rval); switch (error) { case 0: frame->tf_a[0] = rval[0]; frame->tf_t[0] = 0; /* syscall succeeded */ break; - case ERESTART: frame->tf_sepc -= 4; /* prev instruction */ break; - case EJUSTRETURN: break; - default: bad: frame->tf_a[0] = error; Index: sys/arch/sh/sh/trap.c =================================================================== RCS file: /cvs/src/sys/arch/sh/sh/trap.c,v diff -u -p -u -r1.54 trap.c --- sys/arch/sh/sh/trap.c 11 Feb 2023 23:07:27 -0000 1.54 +++ sys/arch/sh/sh/trap.c 27 Oct 2023 03:26:49 -0000 @@ -516,44 +516,20 @@ syscall(struct proc *p, struct trapframe { caddr_t params; const struct sysent *callp; - int error, opc, indirect = -1; - int argoff, argsize; + int error, opc; + int argsize; register_t code, args[8], rval[2]; uvmexp.syscalls++; opc = tf->tf_spc; code = tf->tf_r0; - params = (caddr_t)tf->tf_r15; - switch (code) { - case SYS_syscall: - /* - * Code is first argument, followed by actual args. - */ - indirect = code; - code = tf->tf_r4; - argoff = 1; - break; - default: - argoff = 0; - break; - } - - callp = sysent; - if (code < 0 || code >= SYS_MAXSYSCALL) - callp += SYS_syscall; - else - callp += code; + if (code <= 0 || code >= SYS_MAXSYSCALL) + goto bad; + callp = sysent + code; argsize = callp->sy_argsize; -#ifdef DIAGNOSTIC - if (argsize > sizeof args) { - callp += SYS_syscall - code; - argsize = callp->sy_argsize; - } -#endif - if (argsize) { register_t *ap; int off_t_arg; @@ -570,19 +546,16 @@ syscall(struct proc *p, struct trapframe } ap = args; - switch (argoff) { - case 0: *ap++ = tf->tf_r4; argsize -= sizeof(int); - case 1: *ap++ = tf->tf_r5; argsize -= sizeof(int); - case 2: *ap++ = tf->tf_r6; argsize -= sizeof(int); - /* - * off_t args aren't split between register - * and stack, but rather r7 is skipped and - * the entire off_t is on the stack. - */ - if (argoff + off_t_arg == 3) - break; + *ap++ = tf->tf_r4; argsize -= sizeof(int); + *ap++ = tf->tf_r5; argsize -= sizeof(int); + *ap++ = tf->tf_r6; argsize -= sizeof(int); + /* + * off_t args aren't split between register + * and stack, but rather r7 is skipped and + * the entire off_t is on the stack. + */ + if (off_t_arg != 3) { *ap++ = tf->tf_r7; argsize -= sizeof(int); - break; } if (argsize > 0) { @@ -594,7 +567,7 @@ syscall(struct proc *p, struct trapframe rval[0] = 0; rval[1] = tf->tf_r1; - error = mi_syscall(p, code, indirect, callp, args, rval); + error = mi_syscall(p, code, callp, args, rval); switch (error) { case 0: Index: sys/arch/sparc64/sparc64/trap.c =================================================================== RCS file: /cvs/src/sys/arch/sparc64/sparc64/trap.c,v diff -u -p -u -r1.115 trap.c --- sys/arch/sparc64/sparc64/trap.c 11 Feb 2023 23:07:28 -0000 1.115 +++ sys/arch/sparc64/sparc64/trap.c 27 Oct 2023 03:26:49 -0000 @@ -1109,9 +1109,10 @@ syscall(struct trapframe *tf, register_t int64_t *ap; const struct sysent *callp; struct proc *p = curproc; - int error, new, indirect = -1; + int error = ENOSYS, new; register_t args[8]; register_t rval[2]; + register_t *argp; if ((tf->tf_out[6] & 1) == 0) sigexit(p, SIGILL); @@ -1137,44 +1138,31 @@ syscall(struct trapframe *tf, register_t ap = &tf->tf_out[0]; nap = 6; - switch (code) { - case SYS_syscall: - indirect = code; - code = *ap++; - nap--; - break; - } - - callp = sysent; - if (code < 0 || code >= SYS_MAXSYSCALL) - callp += SYS_syscall; - else { - register_t *argp; - - callp += code; - i = callp->sy_narg; /* Why divide? */ - if (i > nap) { /* usually false */ - if (i > 8) - panic("syscall nargs"); - /* Read the whole block in */ - if ((error = copyin((caddr_t)tf->tf_out[6] - + BIAS + offsetof(struct frame, fr_argx), - &args[nap], (i - nap) * sizeof(register_t)))) - goto bad; - i = nap; - } - /* - * It should be faster to do <= 6 longword copies than - * to call bcopy - */ - for (argp = args; i--;) - *argp++ = *ap++; + if (code <= 0 || code >= SYS_MAXSYSCALL) + goto bad; + callp = sysent + code; + i = callp->sy_narg; /* Why divide? */ + if (i > nap) { /* usually false */ + if (i > 8) + panic("syscall nargs"); + /* Read the whole block in */ + if ((error = copyin((caddr_t)tf->tf_out[6] + + BIAS + offsetof(struct frame, fr_argx), + &args[nap], (i - nap) * sizeof(register_t)))) + goto bad; + i = nap; } + /* + * It should be faster to do <= 6 longword copies than + * to call bcopy + */ + for (argp = args; i--;) + *argp++ = *ap++; rval[0] = 0; rval[1] = 0; - error = mi_syscall(p, code, indirect, callp, args, rval); + error = mi_syscall(p, code, callp, args, rval); switch (error) { vaddr_t dest; Index: sys/kern/kern_ktrace.c =================================================================== RCS file: /cvs/src/sys/kern/kern_ktrace.c,v diff -u -p -u -r1.112 kern_ktrace.c --- sys/kern/kern_ktrace.c 11 May 2023 09:51:33 -0000 1.112 +++ sys/kern/kern_ktrace.c 27 Oct 2023 03:26:49 -0000 @@ -160,7 +160,7 @@ ktrsyscall(struct proc *p, register_t co u_int nargs = 0; int i; - if ((code & KTRC_CODE_MASK) == SYS_sysctl) { + if (code == SYS_sysctl) { /* * The sysctl encoding stores the mib[] * array because it is interesting. Index: sys/sys/ktrace.h =================================================================== RCS file: /cvs/src/sys/sys/ktrace.h,v diff -u -p -u -r1.46 ktrace.h --- sys/sys/ktrace.h 23 Feb 2023 01:33:20 -0000 1.46 +++ sys/sys/ktrace.h 27 Oct 2023 03:26:49 -0000 @@ -76,8 +76,6 @@ struct ktr_header { #define KTR_SYSCALL 1 struct ktr_syscall { int ktr_code; /* syscall number */ -#define KTRC_CODE_MASK 0x0000ffff -#define KTRC_CODE_SYSCALL 0x20000000 int ktr_argsize; /* size of arguments */ /* * followed by ktr_argsize/sizeof(register_t) "register_t"s Index: sys/sys/syscall_mi.h =================================================================== RCS file: /cvs/src/sys/sys/syscall_mi.h,v diff -u -p -u -r1.28 syscall_mi.h --- sys/sys/syscall_mi.h 11 Feb 2023 23:07:23 -0000 1.28 +++ sys/sys/syscall_mi.h 27 Oct 2023 03:26:49 -0000 @@ -51,8 +51,8 @@ * The MD setup for a system call has been done; here's the MI part. */ static inline int -mi_syscall(struct proc *p, register_t code, int indirect, - const struct sysent *callp, register_t *argp, register_t retval[2]) +mi_syscall(struct proc *p, register_t code, const struct sysent *callp, + register_t *argp, register_t retval[2]) { uint64_t tval; int lock = !(callp->sy_flags & SY_NOLOCK); @@ -73,15 +73,8 @@ mi_syscall(struct proc *p, register_t co #ifdef KTRACE if (KTRPOINT(p, KTR_SYSCALL)) { /* convert to mask, then include with code */ - switch (indirect) { - case SYS_syscall: - indirect = KTRC_CODE_SYSCALL; - break; - default: - indirect = 0; - } KERNEL_LOCK(); - ktrsyscall(p, code | indirect, callp->sy_argsize, argp); + ktrsyscall(p, code, callp->sy_argsize, argp); KERNEL_UNLOCK(); } #endif