From: Arnd Bergmann - handle SIGEV_THREAD - don't try to convert u_attr in sys_mq_open if !O_CREAT - handle __SI_MESGQ in copy_siginfo_to_user32 (still missing for ppc64 and parisc) --- 25-akpm/arch/ia64/ia32/ia32_signal.c | 7 ++++++- 25-akpm/arch/mips/kernel/signal32.c | 7 ++++++- 25-akpm/arch/s390/kernel/compat_signal.c | 5 ++++- 25-akpm/arch/sparc64/kernel/signal32.c | 7 ++++++- 25-akpm/arch/x86_64/ia32/ia32_signal.c | 6 +++++- 25-akpm/ipc/compat_mq.c | 13 ++++++++++++- 6 files changed, 39 insertions(+), 6 deletions(-) diff -puN arch/ia64/ia32/ia32_signal.c~more-fixups-for-compat_mq arch/ia64/ia32/ia32_signal.c --- 25/arch/ia64/ia32/ia32_signal.c~more-fixups-for-compat_mq 2004-04-10 14:54:55.418844448 -0700 +++ 25-akpm/arch/ia64/ia32/ia32_signal.c 2004-04-10 14:54:55.434842016 -0700 @@ -114,7 +114,12 @@ copy_siginfo_from_user32 (siginfo_t *to, err |= __get_user(to->si_band, &from->si_band); err |= __get_user(to->si_fd, &from->si_fd); break; - /* case __SI_RT: This is not generated by the kernel as of now. */ + case __SI_RT: /* This is not generated by the kernel as of now. */ + case __SI_MESGQ: + err |= __get_user(to->si_pid, &from->si_pid); + err |= __get_user(to->si_uid, &from->si_uid); + err |= __get_user(to->si_int, &from->si_int); + break; } } return err; diff -puN arch/mips/kernel/signal32.c~more-fixups-for-compat_mq arch/mips/kernel/signal32.c --- 25/arch/mips/kernel/signal32.c~more-fixups-for-compat_mq 2004-04-10 14:54:55.419844296 -0700 +++ 25-akpm/arch/mips/kernel/signal32.c 2004-04-10 14:54:55.434842016 -0700 @@ -358,7 +358,12 @@ static int copy_siginfo_to_user32(siginf err |= __put_user(from->si_band, &to->si_band); err |= __put_user(from->si_fd, &to->si_fd); break; - /* case __SI_RT: This is not generated by the kernel as of now. */ + case __SI_RT: /* This is not generated by the kernel as of now. */ + case __SI_MESGQ: + err |= __put_user(from->si_pid, &to->si_pid); + err |= __put_user(from->si_uid, &to->si_uid); + err |= __put_user(from->si_int, &to->si_int); + break; } } return err; diff -puN arch/s390/kernel/compat_signal.c~more-fixups-for-compat_mq arch/s390/kernel/compat_signal.c --- 25/arch/s390/kernel/compat_signal.c~more-fixups-for-compat_mq 2004-04-10 14:54:55.422843840 -0700 +++ 25-akpm/arch/s390/kernel/compat_signal.c 2004-04-10 14:54:55.435841864 -0700 @@ -74,6 +74,10 @@ int copy_siginfo_to_user32(siginfo_t32 * err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); else { switch (from->si_code >> 16) { + case __SI_RT: /* This is not generated by the kernel as of now. */ + case __SI_MESGQ: + err |= __put_user(from->si_int, &to->si_int); + /* fallthrough */ case __SI_KILL >> 16: err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); @@ -96,7 +100,6 @@ int copy_siginfo_to_user32(siginfo_t32 * break; default: break; - /* case __SI_RT: This is not generated by the kernel as of now. */ } } return err; diff -puN arch/sparc64/kernel/signal32.c~more-fixups-for-compat_mq arch/sparc64/kernel/signal32.c --- 25/arch/sparc64/kernel/signal32.c~more-fixups-for-compat_mq 2004-04-10 14:54:55.425843384 -0700 +++ 25-akpm/arch/sparc64/kernel/signal32.c 2004-04-10 14:54:55.436841712 -0700 @@ -129,7 +129,12 @@ int copy_siginfo_to_user32(siginfo_t32 _ err |= __put_user(from->si_trapno, &to->si_trapno); err |= __put_user((long)from->si_addr, &to->si_addr); break; - /* case __SI_RT: This is not generated by the kernel as of now. */ + case __SI_RT: /* This is not generated by the kernel as of now. */ + case __SI_MESGQ: + err |= __put_user(from->si_pid, &to->si_pid); + err |= __put_user(from->si_uid, &to->si_uid); + err |= __put_user(from->si_int, &to->si_int); + break; } } return err; diff -puN arch/x86_64/ia32/ia32_signal.c~more-fixups-for-compat_mq arch/x86_64/ia32/ia32_signal.c --- 25/arch/x86_64/ia32/ia32_signal.c~more-fixups-for-compat_mq 2004-04-10 14:54:55.427843080 -0700 +++ 25-akpm/arch/x86_64/ia32/ia32_signal.c 2004-04-10 14:54:55.437841560 -0700 @@ -85,7 +85,11 @@ int ia32_copy_siginfo_to_user(siginfo_t3 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. */ + case __SI_RT: /* This is not generated by the kernel as of now. */ + case __SI_MESGQ: + err |= __put_user(from->si_uid, &to->si_uid); + err |= __put_user(from->si_int, &to->si_int); + break; } } return err; diff -puN ipc/compat_mq.c~more-fixups-for-compat_mq ipc/compat_mq.c --- 25/ipc/compat_mq.c~more-fixups-for-compat_mq 2004-04-10 14:54:55.429842776 -0700 +++ 25-akpm/ipc/compat_mq.c 2004-04-10 14:54:55.432842320 -0700 @@ -55,7 +55,7 @@ asmlinkage long compat_sys_mq_open(const char *name; long ret; - if (!u_attr) + if ((oflag & O_CREAT) == 0 || !u_attr) return sys_mq_open(u_name, oflag, mode, 0); if (get_compat_mq_attr(&attr, u_attr)) @@ -139,6 +139,8 @@ asmlinkage long compat_sys_mq_notify(mqd { mm_segment_t oldfs; struct sigevent notification; + char cookie[NOTIFY_COOKIE_LEN]; + compat_uptr_t u_cookie; long ret; if (!u_notification) @@ -147,6 +149,15 @@ asmlinkage long compat_sys_mq_notify(mqd if (get_compat_sigevent(¬ification, u_notification)) return -EFAULT; + if (notification.sigev_notify == SIGEV_THREAD) { + u_cookie = (compat_uptr_t)notification.sigev_value.sival_int; + if (copy_from_user(cookie, compat_ptr(u_cookie), + NOTIFY_COOKIE_LEN)) { + return -EFAULT; + } + notification.sigev_value.sival_ptr = cookie; + } + oldfs = get_fs(); set_fs(KERNEL_DS); ret = sys_mq_notify(mqdes, ¬ification); _