diff options
| -rw-r--r-- | arch/x86_64/ia32/ia32_signal.c | 11 | ||||
| -rw-r--r-- | arch/x86_64/ia32/ia32entry.S | 4 | ||||
| -rw-r--r-- | arch/x86_64/ia32/ipc32.c | 4 | ||||
| -rw-r--r-- | arch/x86_64/ia32/sys_ia32.c | 109 | ||||
| -rw-r--r-- | include/asm-x86_64/ia32.h | 16 |
5 files changed, 41 insertions, 103 deletions
diff --git a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c index a638bc480cff..4fb327c5aa62 100644 --- a/arch/x86_64/ia32/ia32_signal.c +++ b/arch/x86_64/ia32/ia32_signal.c @@ -22,6 +22,7 @@ #include <linux/unistd.h> #include <linux/stddef.h> #include <linux/personality.h> +#include <linux/compat.h> #include <asm/ucontext.h> #include <asm/uaccess.h> #include <asm/i387.h> @@ -134,7 +135,7 @@ struct sigframe int sig; struct sigcontext_ia32 sc; struct _fpstate_ia32 fpstate; - unsigned int extramask[_IA32_NSIG_WORDS-1]; + unsigned int extramask[_COMPAT_NSIG_WORDS-1]; char retcode[8]; }; @@ -237,7 +238,7 @@ asmlinkage long sys32_sigreturn(struct pt_regs regs) if (verify_area(VERIFY_READ, frame, sizeof(*frame))) goto badframe; if (__get_user(set.sig[0], &frame->sc.oldmask) - || (_IA32_NSIG_WORDS > 1 + || (_COMPAT_NSIG_WORDS > 1 && __copy_from_user((((char *) &set.sig) + 4), &frame->extramask, sizeof(frame->extramask)))) goto badframe; @@ -373,7 +374,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) } void ia32_setup_frame(int sig, struct k_sigaction *ka, - sigset32_t *set, struct pt_regs * regs) + compat_sigset_t *set, struct pt_regs * regs) { struct sigframe *frame; int err = 0; @@ -399,7 +400,7 @@ void ia32_setup_frame(int sig, struct k_sigaction *ka, if (err) goto give_sigsegv; - if (_IA32_NSIG_WORDS > 1) { + if (_COMPAT_NSIG_WORDS > 1) { err |= __copy_to_user(frame->extramask, &set->sig[1], sizeof(frame->extramask)); } @@ -460,7 +461,7 @@ give_sigsegv: } void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, - sigset32_t *set, struct pt_regs * regs) + compat_sigset_t *set, struct pt_regs * regs) { struct rt_sigframe *frame; int err = 0; diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S index f6b55b53a7a1..ae59a84040a5 100644 --- a/arch/x86_64/ia32/ia32entry.S +++ b/arch/x86_64/ia32/ia32entry.S @@ -273,7 +273,7 @@ ia32_sys_call_table: .quad sys_setreuid16 /* 70 */ .quad sys_setregid16 .quad stub32_sigsuspend - .quad sys32_sigpending + .quad compat_sys_sigpending .quad sys_sethostname .quad sys32_setrlimit /* 75 */ .quad sys32_old_getrlimit /* old_getrlimit */ @@ -326,7 +326,7 @@ ia32_sys_call_table: .quad sys32_modify_ldt .quad sys32_adjtimex .quad sys32_mprotect /* 125 */ - .quad sys32_sigprocmask + .quad compat_sys_sigprocmask .quad sys32_module_warning /* create_module */ .quad sys_init_module .quad sys_delete_module diff --git a/arch/x86_64/ia32/ipc32.c b/arch/x86_64/ia32/ipc32.c index c5700dc87b36..d8d4fed117f5 100644 --- a/arch/x86_64/ia32/ipc32.c +++ b/arch/x86_64/ia32/ipc32.c @@ -626,9 +626,7 @@ static long semtimedop32(int semid, struct sembuf *sb, return -E2BIG; if (!access_ok(VERIFY_READ, sb, nsops * sizeof(struct sembuf))) return -EFAULT; - if (ts32 && - (get_user(ts.tv_sec, &ts32->tv_sec) || - __get_user(ts.tv_nsec, &ts32->tv_nsec))) + if (ts32 && get_compat_timespec(&ts, ts32)) return -EFAULT; set_fs(KERNEL_DS); diff --git a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c index 1730df54c52a..ee12fd5a8847 100644 --- a/arch/x86_64/ia32/sys_ia32.c +++ b/arch/x86_64/ia32/sys_ia32.c @@ -276,10 +276,10 @@ sys32_rt_sigaction(int sig, struct sigaction32 *act, { struct k_sigaction new_ka, old_ka; int ret; - sigset32_t set32; + compat_sigset_t set32; /* XXX: Don't preclude handling different sized sigset_t's. */ - if (sigsetsize != sizeof(sigset32_t)) + if (sigsetsize != sizeof(compat_sigset_t)) return -EINVAL; if (act) { @@ -287,10 +287,10 @@ sys32_rt_sigaction(int sig, struct sigaction32 *act, __get_user((long)new_ka.sa.sa_handler, &act->sa_handler) || __get_user(new_ka.sa.sa_flags, &act->sa_flags) || __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer)|| - __copy_from_user(&set32, &act->sa_mask, sizeof(sigset32_t))) + __copy_from_user(&set32, &act->sa_mask, sizeof(compat_sigset_t))) return -EFAULT; - /* FIXME: here we rely on _IA32_NSIG_WORS to be >= than _NSIG_WORDS << 1 */ + /* FIXME: here we rely on _COMPAT_NSIG_WORS to be >= than _NSIG_WORDS << 1 */ switch (_NSIG_WORDS) { case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6] | (((long)set32.sig[7]) << 32); @@ -306,7 +306,7 @@ sys32_rt_sigaction(int sig, struct sigaction32 *act, ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); if (!ret && oact) { - /* FIXME: here we rely on _IA32_NSIG_WORS to be >= than _NSIG_WORDS << 1 */ + /* FIXME: here we rely on _COMPAT_NSIG_WORS to be >= than _NSIG_WORDS << 1 */ switch (_NSIG_WORDS) { case 4: set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32); @@ -325,7 +325,7 @@ sys32_rt_sigaction(int sig, struct sigaction32 *act, __put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) || __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer) || __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || - __copy_to_user(&oact->sa_mask, &set32, sizeof(sigset32_t))) + __copy_to_user(&oact->sa_mask, &set32, sizeof(compat_sigset_t))) return -EFAULT; } @@ -339,7 +339,7 @@ sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *o int ret; if (act) { - old_sigset32_t mask; + compat_old_sigset_t mask; if (verify_area(VERIFY_READ, act, sizeof(*act)) || __get_user((long)new_ka.sa.sa_handler, &act->sa_handler) || @@ -368,16 +368,16 @@ extern asmlinkage long sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset size_t sigsetsize); asmlinkage long -sys32_rt_sigprocmask(int how, sigset32_t *set, sigset32_t *oset, +sys32_rt_sigprocmask(int how, compat_sigset_t *set, compat_sigset_t *oset, unsigned int sigsetsize) { sigset_t s; - sigset32_t s32; + compat_sigset_t s32; int ret; mm_segment_t old_fs = get_fs(); if (set) { - if (copy_from_user (&s32, set, sizeof(sigset32_t))) + if (copy_from_user (&s32, set, sizeof(compat_sigset_t))) return -EFAULT; switch (_NSIG_WORDS) { case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32); @@ -398,7 +398,7 @@ sys32_rt_sigprocmask(int how, sigset32_t *set, sigset32_t *oset, case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1]; case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0]; } - if (copy_to_user (oset, &s32, sizeof(sigset32_t))) + if (copy_to_user (oset, &s32, sizeof(compat_sigset_t))) return -EFAULT; } return 0; @@ -1219,55 +1219,18 @@ sys32_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec *interval) set_fs (KERNEL_DS); ret = sys_sched_rr_get_interval(pid, &t); set_fs (old_fs); - if (verify_area(VERIFY_WRITE, interval, sizeof(struct compat_timespec)) || - __put_user (t.tv_sec, &interval->tv_sec) || - __put_user (t.tv_nsec, &interval->tv_nsec)) + if (put_compat_timespec(&t, interval)) return -EFAULT; return ret; } -extern asmlinkage long sys_sigprocmask(int how, old_sigset_t *set, - old_sigset_t *oset); - -asmlinkage long -sys32_sigprocmask(int how, old_sigset32_t *set, old_sigset32_t *oset) -{ - old_sigset_t s; - int ret; - mm_segment_t old_fs = get_fs(); - - if (set && get_user (s, set)) return -EFAULT; - set_fs (KERNEL_DS); - ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL); - set_fs (old_fs); - if (ret) return ret; - if (oset && put_user (s, oset)) return -EFAULT; - return 0; -} - -extern asmlinkage long sys_sigpending(old_sigset_t *set); - -asmlinkage long -sys32_sigpending(old_sigset32_t *set) -{ - old_sigset_t s; - int ret; - mm_segment_t old_fs = get_fs(); - - set_fs (KERNEL_DS); - ret = sys_sigpending(&s); - set_fs (old_fs); - if (put_user (s, set)) return -EFAULT; - return ret; -} - extern asmlinkage long sys_rt_sigpending(sigset_t *set, size_t sigsetsize); asmlinkage long -sys32_rt_sigpending(sigset32_t *set, compat_size_t sigsetsize) +sys32_rt_sigpending(compat_sigset_t *set, compat_size_t sigsetsize) { sigset_t s; - sigset32_t s32; + compat_sigset_t s32; int ret; mm_segment_t old_fs = get_fs(); @@ -1281,7 +1244,7 @@ sys32_rt_sigpending(sigset32_t *set, compat_size_t sigsetsize) case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1]; case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0]; } - if (copy_to_user (set, &s32, sizeof(sigset32_t))) + if (copy_to_user (set, &s32, sizeof(compat_sigset_t))) return -EFAULT; } return ret; @@ -1369,18 +1332,18 @@ sys_rt_sigtimedwait(const sigset_t *uthese, siginfo_t *uinfo, const struct timespec *uts, size_t sigsetsize); asmlinkage long -sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo, +sys32_rt_sigtimedwait(compat_sigset_t *uthese, siginfo_t32 *uinfo, struct compat_timespec *uts, compat_size_t sigsetsize) { sigset_t s; - sigset32_t s32; + compat_sigset_t s32; struct timespec t; int ret; mm_segment_t old_fs = get_fs(); siginfo_t info; siginfo_t32 info32; - if (copy_from_user (&s32, uthese, sizeof(sigset32_t))) + if (copy_from_user (&s32, uthese, sizeof(compat_sigset_t))) return -EFAULT; switch (_NSIG_WORDS) { case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32); @@ -1388,14 +1351,11 @@ sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo, case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32); case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32); } - if (uts) { - if (verify_area(VERIFY_READ, uts, sizeof(struct compat_timespec)) || - __get_user (t.tv_sec, &uts->tv_sec) || - __get_user (t.tv_nsec, &uts->tv_nsec)) - return -EFAULT; - } + if (uts && get_compat_timespec(&t, uts)) + return -EFAULT; set_fs (KERNEL_DS); - ret = sys_rt_sigtimedwait(&s, &info, &t, sigsetsize); + ret = sys_rt_sigtimedwait(&s, uinfo ? &info : NULL, uts ? &t : NULL, + sigsetsize); set_fs (old_fs); if (ret >= 0 && uinfo) { if (copy_to_user (uinfo, siginfo64to32(&info32, &info), @@ -2248,20 +2208,13 @@ sys32_futex(unsigned long uaddr, int op, int val, struct compat_timespec *utime3 mm_segment_t oldfs = get_fs(); int err; - if (utime32) { - if (verify_area(VERIFY_READ, utime32, sizeof(*utime32))) - return -EFAULT; - - if (__get_user(t.tv_sec, &utime32->tv_sec) || - __get_user(t.tv_nsec, &utime32->tv_nsec)) - return -EFAULT; - - } + if (utime32 && get_compat_timespec(&t, utime32)) + return -EFAULT; /* the set_fs is safe because futex doesn't use the seg limit for valid page checking of uaddr. */ set_fs(KERNEL_DS); - err = sys_futex(uaddr, op, val, &t); + err = sys_futex(uaddr, op, val, utime32 ? &t : NULL); set_fs(oldfs); return err; } @@ -2340,22 +2293,18 @@ asmlinkage long sys32_io_getevents(aio_context_t ctx_id, { long ret; mm_segment_t oldfs; - struct timespec t32; + struct timespec t; /* Harden against bogus ptrace */ if (nr >= 0xffffffff || !access_ok(VERIFY_WRITE, events, nr * sizeof(struct io_event))) return -EFAULT; - if (timeout && - (get_user(t32.tv_sec, &timeout->tv_sec) || - __get_user(t32.tv_nsec, &timeout->tv_nsec))) + if (timeout && get_compat_timespec(&t, timeout)) return -EFAULT; oldfs = get_fs(); set_fs(KERNEL_DS); - ret = sys_io_getevents(ctx_id,min_nr,nr,events,timeout ? &t32 : NULL); + ret = sys_io_getevents(ctx_id,min_nr,nr,events,timeout ? &t : NULL); set_fs(oldfs); - if (timeout && - (__put_user(t32.tv_sec, &timeout->tv_sec) || - __put_user(t32.tv_nsec, &timeout->tv_nsec))) + if (timeout && put_compat_timespec(&t, timeout)) return -EFAULT; return ret; } diff --git a/include/asm-x86_64/ia32.h b/include/asm-x86_64/ia32.h index c39a426062ee..99ba044a735e 100644 --- a/include/asm-x86_64/ia32.h +++ b/include/asm-x86_64/ia32.h @@ -26,28 +26,18 @@ struct ia32_flock64 { #include <asm/sigcontext32.h> /* signal.h */ -#define _IA32_NSIG 64 -#define _IA32_NSIG_BPW 32 -#define _IA32_NSIG_WORDS (_IA32_NSIG / _IA32_NSIG_BPW) - -typedef struct { - unsigned int sig[_IA32_NSIG_WORDS]; -} sigset32_t; - struct sigaction32 { unsigned int sa_handler; /* Really a pointer, but need to deal with 32 bits */ unsigned int sa_flags; unsigned int sa_restorer; /* Another 32 bit pointer */ - sigset32_t sa_mask; /* A 32 bit mask */ + compat_sigset_t sa_mask; /* A 32 bit mask */ }; -typedef unsigned int old_sigset32_t; /* at least 32 bits */ - struct old_sigaction32 { unsigned int sa_handler; /* Really a pointer, but need to deal with 32 bits */ - old_sigset32_t sa_mask; /* A 32 bit mask */ + compat_old_sigset_t sa_mask; /* A 32 bit mask */ unsigned int sa_flags; unsigned int sa_restorer; /* Another 32 bit pointer */ }; @@ -63,7 +53,7 @@ struct ucontext_ia32 { unsigned int uc_link; stack_ia32_t uc_stack; struct sigcontext_ia32 uc_mcontext; - sigset32_t uc_sigmask; /* mask last for extensibility */ + compat_sigset_t uc_sigmask; /* mask last for extensibility */ }; /* This matches struct stat64 in glibc2.2, hence the absolutely |
