Theo de Raadt <dera...@openbsd.org> wrote:

> 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).
> 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.

Replacement diff that works on more architectures.  (The story here
is that a kernel-only diff without the userland diff requires a different
kind of range check, because syscalls.master cannot be changed to make
the 0th entry enosys, because the generated .h files will break libc
build.  So I refactored rapidly, and forgot 'error = ENOSYS' on a few
architectures..)

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 16:16:57 -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 = ENOSYS;
        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 16:16: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 = ENOSYS;
        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 16:16:38 -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 = ENOSYS;
        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 16:12:24 -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 = ENOSYS;
        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 16:16:29 -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 = ENOSYS;
        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 16:16:20 -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;
+               int error = ENOSYS, numarg;
+               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 16:16:07 -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 code, error = ENOSYS;
        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 16:15:52 -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 = ENOSYS;
        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 16:15:43 -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 = ENOSYS;
        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 16:15:38 -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 = ENOSYS, 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

Reply via email to