more fixes for Opteron ia32 siginfo interface
PATCH 1/1 more fixes for Opteron ia32 siginfo interface
Andi and Andrew,
This patch should fix all the remaining Opteron ia32 siginfo_t issues in 2.6.0. It has been only lightly tested: posix timer tests, a small sigqueue(2) test that I wrote, and part of ltp, all compiled in ia32 mode.
Patch is against 2.6.0 as 2.6.1-rc1 does not compile under Opteron.
ChangeLog:
o Base is 2.6.0 with Andi Kleen's x86_64-2.6.0-1.bz2 patch.
o import Andrew Morton's 2.6.1-rc1 ia32_copy_siginfo_to_user changes.
o add final missing bits to ia32_copy_siginfo_to_user.
o insert missing timer union into siginfo_t32.
o remove siginfo64to32, use ia32_copy_siginfo_to_user instead.
o rewrite siginfo32to64 as ia32_copy_siginfo_from_user, simplify.
o fix possible data leak in sys32_rt_sigtimedwait.
Pick and choose whatever you like from this.
Regards,
Joe
arch/x86_64/ia32/ia32_signal.c | 49 ++++++++++++++------- arch/x86_64/ia32/sys_ia32.c | 95 +++-------------------------------------- include/asm-x86_64/ia32.h | 10 +++- 3 files changed, 51 insertions(+), 103 deletions(-)
arch/x86_64/ia32/ia32_signal.c +34 -15
@@ -44,10 +44,10 @@ asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);void signal_fault (struct pt_regs *regs,void *frame,char *where); -static int ia32_copy_siginfo_to_user (siginfo_t32 *to,siginfo_t *from) +int ia32_copy_siginfo_to_user (siginfo_t32 __user *to,siginfo_t *from) {int err; -if (!access_ok (VERIFY_WRITE , to,sizeof (siginfo_t))) +if (!access_ok (VERIFY_WRITE , to,sizeof (siginfo_t32)))return -EFAULT ;/* If you change siginfo_t structure, please make sure that
@@ -55,20 +55,18 @@It should never copy any pad contained in the structure to avoid security leaks, but must copy the generic 3 ints plus the relevant union member. */ - + + err =__put_user (from->si_signo, &to->si_signo); + err |=__put_user (from->si_errno, &to->si_errno); + err |=__put_user (from->si_code, &to->si_code); +if (from->si_code <0 ) { - err =__put_user (from->si_signo, &to->si_signo); - err |=__put_user (from->si_errno, &to->si_errno); - err |=__put_user (from->si_code, &to->si_code); - err |=__put_user (from->_sifields._rt._pid, &to->_sifields._rt._pid); - err |=__put_user (from->_sifields._rt._uid, &to->_sifields._rt._uid); - err |=__put_user ((u32 )(u64 )from->_sifields._rt._sigval.sival_ptr, - &to->_sifields._rt._sigval.sival_ptr); + err |=__put_user (from->si_pid, &to->si_pid); + err |=__put_user (from->si_uid, &to->si_uid); + err |=__put_user ((u32 )(u64 )from->si_ptr, &to->si_ptr); }else { - err =__put_user (from->si_signo, &to->si_signo); - err |=__put_user (from->si_errno, &to->si_errno); - err |=__put_user (from->si_code, &to->si_code); -/* First 32bits of unions are always present. */ +/* First 32bits of unions are always present: +* si_pid === si_band === si_tid === si_addr(LS half) */ err |=__put_user (from->si_pid, &to->si_pid);switch (from->si_code >>16 ) {case __SI_FAULT >>16 :
@@ -78,18 +76,39 @@ err |=__put_user (from->si_stime, &to->si_stime); err |=__put_user (from->si_status, &to->si_status);default : +case __SI_KILL >>16 : err |=__put_user (from->si_uid, &to->si_uid);break ;case __SI_POLL >>16 : - err |=__put_user (from->si_band, &to->si_band); err |=__put_user (from->si_fd, &to->si_fd);break ; +case __SI_TIMER >>16 : + err |=__put_user (from->si_overrun, &to->si_overrun); + err |=__put_user ((u32 )(u64 )from->si_ptr, &to->si_ptr); +break ;/* case __SI_RT: This is not generated by the kernel as of now. */ } }return err; } +int ia32_copy_siginfo_from_user (siginfo_t *to,siginfo_t32 __user *from) +{ +int err; +if (!access_ok (VERIFY_READ , from,sizeof (siginfo_t32))) +return -EFAULT ; + + err =__get_user (to->si_signo, &from->si_signo); + err |=__get_user (to->si_errno, &from->si_errno); + err |=__get_user (to->si_code, &from->si_code); + + err |=__get_user (to->si_pid, &from->si_pid); + err |=__get_user (to->si_uid, &from->si_uid); + err |=__get_user ((u32 )(u64 )to->si_ptr, &from->si_ptr); + +return err; +} +asmlinkage long sys32_sigsuspend (int history0,int history1,old_sigset_t mask,struct pt_regs regs) {
arch/x86_64/ia32/sys_ia32.c +9 -86
127 lines not on this page · raw message
include/asm-x86_64/ia32.h +8 -2
@@ -100,8 +100,11 @@/* POSIX.1b timers */ struct { -unsigned int _timer1; -unsigned int _timer2; +int _tid;/* timer id */ +int _overrun;/* overrun count */ +sigval_t32 _sigval;/* same as below */ +int _sys_private;/* not to be passed to user */ +int _overrun_incr;/* amount to add to overrun */ } _timer;/* POSIX.1b signals */
@@ -164,9 +167,12 @@#ifdef __KERNEL__struct user_desc ; +struct siginfo_t ;int do_get_thread_area (struct thread_struct *t,struct user_desc *u_info);int do_set_thread_area (struct thread_struct *t,struct user_desc *u_info);int ia32_child_tls (struct task_struct *p,struct pt_regs *childregs); +int ia32_copy_siginfo_from_user (siginfo_t *to,siginfo_t32 __user *from); +int ia32_copy_siginfo_to_user (siginfo_t32 __user *to,siginfo_t *from);#endif #endif /* !CONFIG_IA32_SUPPORT */
Quoted 6 lines · On Tue, 6 Jan 2004 11:28:18 -0500 Joe Korty <[email protected]> wrote:
Andi and Andrew,
This patch should fix all the remaining Opteron ia32
siginfo_tissues in 2.6.0. It has been only lightly tested: posix timer tests, a small sigqueue(2) test that I wrote, and part of ltp, all compiled in ia32 mode.
I applied the patch. Some hunks in ia32_signal.c rejected, but I merged them by hand (and fixed the indentation in the comments)
Thanks,
-Andi