diff --git a/sys/amd64/ia32/ia32_syscall.c b/sys/amd64/ia32/ia32_syscall.c index 0cdec6f71ae7..92249f98752a 100644 --- a/sys/amd64/ia32/ia32_syscall.c +++ b/sys/amd64/ia32/ia32_syscall.c @@ -110,7 +110,7 @@ ia32_fetch_syscall_args(struct thread *td, struct syscall_args *sa) struct proc *p; struct trapframe *frame; caddr_t params; - u_int32_t args[8]; + u_int32_t args[8], tmp; int error, i; p = td->td_proc; @@ -126,7 +126,10 @@ ia32_fetch_syscall_args(struct thread *td, struct syscall_args *sa) /* * Code is first argument, followed by actual args. */ - sa->code = fuword32(params); + error = fueword32(params, &tmp); + if (error == -1) + return (EFAULT); + sa->code = tmp; params += sizeof(int); } else if (sa->code == SYS___syscall) { /* @@ -135,7 +138,10 @@ ia32_fetch_syscall_args(struct thread *td, struct syscall_args *sa) * We use a 32-bit fetch in case params is not * aligned. */ - sa->code = fuword32(params); + error = fueword32(params, &tmp); + if (error == -1) + return (EFAULT); + sa->code = tmp; params += sizeof(quad_t); } if (p->p_sysent->sv_mask) diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index 8ec949f9d803..5ea062ea3686 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -1832,16 +1832,21 @@ freebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap) { int error, name[CTL_MAXNAME]; size_t j, oldlen; + uint32_t tmp; if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) return (EINVAL); error = copyin(uap->name, name, uap->namelen * sizeof(int)); if (error) return (error); - if (uap->oldlenp) - oldlen = fuword32(uap->oldlenp); - else + if (uap->oldlenp) { + error = fueword32(uap->oldlenp, &tmp); + oldlen = tmp; + } else { oldlen = 0; + } + if (error != 0) + return (EFAULT); error = userland_sysctl(td, name, uap->namelen, uap->old, &oldlen, 1, uap->new, uap->newlen, &j, SCTL_MASK32); diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c index 1d0d104edad1..84d6ec38fb71 100644 --- a/sys/i386/i386/trap.c +++ b/sys/i386/i386/trap.c @@ -1059,6 +1059,7 @@ cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa) struct proc *p; struct trapframe *frame; caddr_t params; + long tmp; int error; p = td->td_proc; @@ -1074,14 +1075,20 @@ cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa) /* * Code is first argument, followed by actual args. */ - sa->code = fuword(params); + error = fueword(params, &tmp); + if (error == -1) + return (EFAULT); + sa->code = tmp; params += sizeof(int); } else if (sa->code == SYS___syscall) { /* * Like syscall, but code is a quad, so as to maintain * quad alignment for the rest of the arguments. */ - sa->code = fuword(params); + error = fueword(params, &tmp); + if (error == -1) + return (EFAULT); + sa->code = tmp; params += sizeof(quad_t); } diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 09212c8ef807..45d4c6f81764 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1091,7 +1091,7 @@ int exec_copyin_args(struct image_args *args, char *fname, enum uio_seg segflg, char **argv, char **envv) { - char *argp, *envp; + u_long argp, envp; int error; size_t length; @@ -1127,13 +1127,17 @@ exec_copyin_args(struct image_args *args, char *fname, /* * extract arguments first */ - while ((argp = (caddr_t) (intptr_t) fuword(argv++))) { - if (argp == (caddr_t) -1) { + for (;;) { + error = fueword(argv++, &argp); + if (error == -1) { error = EFAULT; goto err_exit; } - if ((error = copyinstr(argp, args->endp, - args->stringspace, &length))) { + if (argp == 0) + break; + error = copyinstr((void *)(uintptr_t)argp, args->endp, + args->stringspace, &length); + if (error != 0) { if (error == ENAMETOOLONG) error = E2BIG; goto err_exit; @@ -1149,13 +1153,17 @@ exec_copyin_args(struct image_args *args, char *fname, * extract environment strings */ if (envv) { - while ((envp = (caddr_t)(intptr_t)fuword(envv++))) { - if (envp == (caddr_t)-1) { + for (;;) { + error = fueword(envv++, &envp); + if (error == -1) { error = EFAULT; goto err_exit; } - if ((error = copyinstr(envp, args->endp, - args->stringspace, &length))) { + if (envp == 0) + break; + error = copyinstr((void *)(uintptr_t)envp, + args->endp, args->stringspace, &length); + if (error != 0) { if (error == ENAMETOOLONG) error = E2BIG; goto err_exit; diff --git a/sys/kern/vfs_acl.c b/sys/kern/vfs_acl.c index 93626fb2e77f..e9361e5726d0 100644 --- a/sys/kern/vfs_acl.c +++ b/sys/kern/vfs_acl.c @@ -148,6 +148,7 @@ acl_copyin(void *user_acl, struct acl *kernel_acl, acl_type_t type) static int acl_copyout(struct acl *kernel_acl, void *user_acl, acl_type_t type) { + uint32_t am; int error; struct oldacl old; @@ -162,8 +163,11 @@ acl_copyout(struct acl *kernel_acl, void *user_acl, acl_type_t type) break; default: - if (fuword32((char *)user_acl + - offsetof(struct acl, acl_maxcnt)) != ACL_MAX_ENTRIES) + error = fueword32((char *)user_acl + + offsetof(struct acl, acl_maxcnt), &am); + if (error == -1) + return (EFAULT); + if (am != ACL_MAX_ENTRIES) return (EINVAL); error = copyout(kernel_acl, user_acl, sizeof(*kernel_acl)); diff --git a/sys/net/if_spppsubr.c b/sys/net/if_spppsubr.c index 9dc55c5ba12c..c0f8e39c3963 100644 --- a/sys/net/if_spppsubr.c +++ b/sys/net/if_spppsubr.c @@ -5060,7 +5060,8 @@ sppp_params(struct sppp *sp, u_long cmd, void *data) * Check the cmd word first before attempting to fetch all the * data. */ - if ((subcmd = fuword(ifr->ifr_data)) == -1) { + rv = fueword(ifr->ifr_data, &subcmd); + if (rv == -1) { rv = EFAULT; goto quit; }