On Tue, 5 Apr 2005 14:03:12 +0100 Matthew Wilcox <[EMAIL PROTECTED]> wrote: > > Umm. I think you've just discovered a bug in ARM and MIPS. I don't see > any code in glibc for handling the 4-argument version of sys_shmat. > Russell, Ralf, could you comment?
OK, assuming that using the 4 argument version of sys_shmat as a system call, here is another version of the patch (not tested) for comment. we now have sys_shmat, ipc_shmat and do_shmat :-) -- Cheers, Stephen Rothwell [EMAIL PROTECTED] http://www.canb.auug.org.au/~sfr/ diff -ruNp linus/arch/alpha/kernel/osf_sys.c linus-compat_sys_ipc.3/arch/alpha/kernel/osf_sys.c --- linus/arch/alpha/kernel/osf_sys.c 2005-03-14 13:07:08.000000000 +1100 +++ linus-compat_sys_ipc.3/arch/alpha/kernel/osf_sys.c 2005-04-05 15:39:55.000000000 +1000 @@ -457,22 +457,6 @@ osf_getdomainname(char __user *name, int return 0; } -asmlinkage long -osf_shmat(int shmid, void __user *shmaddr, int shmflg) -{ - unsigned long raddr; - long err; - - err = do_shmat(shmid, shmaddr, shmflg, &raddr); - - /* - * This works because all user-level addresses are - * non-negative longs! - */ - return err ? err : (long)raddr; -} - - /* * The following stuff should move into a header file should it ever * be labeled "officially supported." Right now, there is just enough diff -ruNp linus/arch/alpha/kernel/systbls.S linus-compat_sys_ipc.3/arch/alpha/kernel/systbls.S --- linus/arch/alpha/kernel/systbls.S 2004-09-16 21:51:57.000000000 +1000 +++ linus-compat_sys_ipc.3/arch/alpha/kernel/systbls.S 2005-04-05 15:39:41.000000000 +1000 @@ -227,7 +227,7 @@ sys_call_table: .quad sys_semop .quad osf_utsname .quad sys_lchown - .quad osf_shmat + .quad sys_shmat .quad sys_shmctl /* 210 */ .quad sys_shmdt .quad sys_shmget diff -ruNp linus/arch/arm/kernel/sys_arm.c linus-compat_sys_ipc.3/arch/arm/kernel/sys_arm.c --- linus/arch/arm/kernel/sys_arm.c 2005-03-17 14:08:05.000000000 +1100 +++ linus-compat_sys_ipc.3/arch/arm/kernel/sys_arm.c 2005-04-06 13:35:51.000000000 +1000 @@ -212,13 +212,9 @@ asmlinkage int sys_ipc(uint call, int fi case SHMAT: switch (version) { - default: { - ulong raddr; - ret = do_shmat(first, (char __user *)ptr, second, &raddr); - if (ret) - return ret; - return put_user(raddr, (ulong __user *)third); - } + default: + return ipc_shmat(first, ptr, second, + (unsigned long __user *)third); case 1: /* Of course, we don't support iBCS2! */ return -EINVAL; } @@ -234,18 +230,6 @@ asmlinkage int sys_ipc(uint call, int fi } } -asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg, - unsigned long __user *addr) -{ - unsigned long ret; - long err; - - err = do_shmat(shmid, shmaddr, shmflg, &ret); - if (err == 0) - err = put_user(ret, addr); - return err; -} - /* Fork a new task - this creates a new program thread. * This is called indirectly via a small wrapper */ diff -ruNp linus/arch/arm26/kernel/sys_arm.c linus-compat_sys_ipc.3/arch/arm26/kernel/sys_arm.c --- linus/arch/arm26/kernel/sys_arm.c 2005-01-04 17:05:27.000000000 +1100 +++ linus-compat_sys_ipc.3/arch/arm26/kernel/sys_arm.c 2005-04-06 13:36:36.000000000 +1000 @@ -210,13 +210,9 @@ asmlinkage int sys_ipc (uint call, int f case SHMAT: switch (version) { - default: { - ulong raddr; - ret = do_shmat (first, (char *) ptr, second, &raddr); - if (ret) - return ret; - return put_user (raddr, (ulong *) third); - } + default: + return ipc_shmat(first, ptr, second, + (unsigned long __user *)third); case 1: /* iBCS2 emulator entry point */ if (!segment_eq(get_fs(), get_ds())) return -EINVAL; diff -ruNp linus/arch/cris/kernel/sys_cris.c linus-compat_sys_ipc.3/arch/cris/kernel/sys_cris.c --- linus/arch/cris/kernel/sys_cris.c 2004-06-04 07:19:00.000000000 +1000 +++ linus-compat_sys_ipc.3/arch/cris/kernel/sys_cris.c 2005-04-06 13:36:47.000000000 +1000 @@ -154,13 +154,9 @@ asmlinkage int sys_ipc (uint call, int f case MSGCTL: return sys_msgctl (first, second, (struct msqid_ds __user *) ptr); - case SHMAT: { - ulong raddr; - ret = do_shmat (first, (char __user *) ptr, second, &raddr); - if (ret) - return ret; - return put_user (raddr, (ulong __user *) third); - } + case SHMAT: + return ipc_shmat(first, ptr, second, + (unsigned long __user *)third); case SHMDT: return sys_shmdt ((char __user *)ptr); case SHMGET: diff -ruNp linus/arch/frv/kernel/sys_frv.c linus-compat_sys_ipc.3/arch/frv/kernel/sys_frv.c --- linus/arch/frv/kernel/sys_frv.c 2005-01-06 12:05:05.000000000 +1100 +++ linus-compat_sys_ipc.3/arch/frv/kernel/sys_frv.c 2005-04-06 13:38:50.000000000 +1000 @@ -188,13 +188,9 @@ asmlinkage long sys_ipc(unsigned long ca case SHMAT: switch (version) { - default: { - ulong raddr; - ret = do_shmat (first, (char __user *) ptr, second, &raddr); - if (ret) - return ret; - return put_user (raddr, (ulong __user *) third); - } + default: + return ipc_shmat(first, ptr, second, + (unsigned long __user *)third); case 1: /* iBCS2 emulator entry point */ if (!segment_eq(get_fs(), get_ds())) return -EINVAL; diff -ruNp linus/arch/h8300/kernel/sys_h8300.c linus-compat_sys_ipc.3/arch/h8300/kernel/sys_h8300.c --- linus/arch/h8300/kernel/sys_h8300.c 2004-03-16 08:12:17.000000000 +1100 +++ linus-compat_sys_ipc.3/arch/h8300/kernel/sys_h8300.c 2005-04-06 13:36:56.000000000 +1000 @@ -236,16 +236,8 @@ asmlinkage int sys_ipc (uint call, int f if (call <= SHMCTL) switch (call) { case SHMAT: - switch (version) { - default: { - ulong raddr; - ret = do_shmat (first, (char *) ptr, - second, &raddr); - if (ret) - return ret; - return put_user (raddr, (ulong *) third); - } - } + return ipc_shmat(first, ptr, second, + (unsigned long __user *)third); case SHMDT: return sys_shmdt ((char *)ptr); case SHMGET: diff -ruNp linus/arch/i386/kernel/sys_i386.c linus-compat_sys_ipc.3/arch/i386/kernel/sys_i386.c --- linus/arch/i386/kernel/sys_i386.c 2004-07-26 05:20:35.000000000 +1000 +++ linus-compat_sys_ipc.3/arch/i386/kernel/sys_i386.c 2005-04-06 13:37:06.000000000 +1000 @@ -131,7 +131,7 @@ asmlinkage int old_select(struct sel_arg asmlinkage int sys_ipc (uint call, int first, int second, int third, void __user *ptr, long fifth) { - int version, ret; + int version; version = call >> 16; /* hack for backward compatibility */ call &= 0xffff; @@ -183,13 +183,9 @@ asmlinkage int sys_ipc (uint call, int f case SHMAT: switch (version) { - default: { - ulong raddr; - ret = do_shmat (first, (char __user *) ptr, second, &raddr); - if (ret) - return ret; - return put_user (raddr, (ulong __user *) third); - } + default: + return ipc_shmat(first, ptr, second, + (unsigned long __user *)third); case 1: /* iBCS2 emulator entry point */ if (!segment_eq(get_fs(), get_ds())) return -EINVAL; diff -ruNp linus/arch/ia64/kernel/entry.S linus-compat_sys_ipc.3/arch/ia64/kernel/entry.S --- linus/arch/ia64/kernel/entry.S 2005-02-04 04:10:36.000000000 +1100 +++ linus-compat_sys_ipc.3/arch/ia64/kernel/entry.S 2005-04-05 16:15:31.000000000 +1000 @@ -1417,7 +1417,7 @@ sys_call_table: data8 sys_msgrcv data8 sys_msgctl data8 sys_shmget - data8 ia64_shmat + data8 sys_shmat data8 sys_shmdt // 1115 data8 sys_shmctl data8 sys_syslog diff -ruNp linus/arch/ia64/kernel/sys_ia64.c linus-compat_sys_ipc.3/arch/ia64/kernel/sys_ia64.c --- linus/arch/ia64/kernel/sys_ia64.c 2005-02-04 04:10:36.000000000 +1100 +++ linus-compat_sys_ipc.3/arch/ia64/kernel/sys_ia64.c 2005-04-05 16:15:16.000000000 +1000 @@ -93,20 +93,6 @@ sys_getpagesize (void) } asmlinkage unsigned long -ia64_shmat (int shmid, void __user *shmaddr, int shmflg) -{ - unsigned long raddr; - int retval; - - retval = do_shmat(shmid, shmaddr, shmflg, &raddr); - if (retval < 0) - return retval; - - force_successful_syscall_return(); - return raddr; -} - -asmlinkage unsigned long ia64_brk (unsigned long brk) { unsigned long rlim, retval, newbrk, oldbrk; diff -ruNp linus/arch/m32r/kernel/sys_m32r.c linus-compat_sys_ipc.3/arch/m32r/kernel/sys_m32r.c --- linus/arch/m32r/kernel/sys_m32r.c 2005-03-14 13:07:08.000000000 +1100 +++ linus-compat_sys_ipc.3/arch/m32r/kernel/sys_m32r.c 2005-04-06 13:38:46.000000000 +1000 @@ -168,17 +168,9 @@ asmlinkage int sys_ipc(uint call, int fi case MSGCTL: return sys_msgctl (first, second, (struct msqid_ds __user *) ptr); - case SHMAT: { - ulong raddr; - - if (!access_ok(VERIFY_WRITE, (ulong __user *) third, - sizeof(ulong))) - return -EFAULT; - ret = do_shmat (first, (char __user *) ptr, second, &raddr); - if (ret) - return ret; - return put_user (raddr, (ulong __user *) third); - } + case SHMAT: + return ipc_shmat(first, ptr, second, + (unsigned long __user *)third); case SHMDT: return sys_shmdt ((char __user *)ptr); case SHMGET: diff -ruNp linus/arch/m68k/kernel/sys_m68k.c linus-compat_sys_ipc.3/arch/m68k/kernel/sys_m68k.c --- linus/arch/m68k/kernel/sys_m68k.c 2004-05-12 07:28:08.000000000 +1000 +++ linus-compat_sys_ipc.3/arch/m68k/kernel/sys_m68k.c 2005-04-06 13:37:11.000000000 +1000 @@ -237,16 +237,8 @@ asmlinkage int sys_ipc (uint call, int f if (call <= SHMCTL) switch (call) { case SHMAT: - switch (version) { - default: { - ulong raddr; - ret = do_shmat (first, (char *) ptr, - second, &raddr); - if (ret) - return ret; - return put_user (raddr, (ulong *) third); - } - } + return ipc_shmat(first, ptr, second, + (unsigned long __user *)third); case SHMDT: return sys_shmdt ((char *)ptr); case SHMGET: diff -ruNp linus/arch/mips/kernel/syscall.c linus-compat_sys_ipc.3/arch/mips/kernel/syscall.c --- linus/arch/mips/kernel/syscall.c 2005-02-04 04:10:36.000000000 +1100 +++ linus-compat_sys_ipc.3/arch/mips/kernel/syscall.c 2005-04-06 13:37:38.000000000 +1000 @@ -349,13 +349,9 @@ asmlinkage int sys_ipc (uint call, int f case SHMAT: switch (version) { - default: { - ulong raddr; - ret = do_shmat (first, (char *) ptr, second, &raddr); - if (ret) - return ret; - return put_user (raddr, (ulong *) third); - } + default: + return ipc_shmat(first, ptr, second, + (unsigned logn __user *)third); case 1: /* iBCS2 emulator entry point */ if (!segment_eq(get_fs(), get_ds())) return -EINVAL; @@ -374,22 +370,6 @@ asmlinkage int sys_ipc (uint call, int f } /* - * Native ABI that is O32 or N64 version - */ -asmlinkage long sys_shmat(int shmid, char __user *shmaddr, - int shmflg, unsigned long *addr) -{ - unsigned long raddr; - int err; - - err = do_shmat(shmid, shmaddr, shmflg, &raddr); - if (err) - return err; - - return put_user(raddr, addr); -} - -/* * No implemented yet ... */ asmlinkage int sys_cachectl(char *addr, int nbytes, int op) diff -ruNp linus/arch/parisc/kernel/sys_parisc.c linus-compat_sys_ipc.3/arch/parisc/kernel/sys_parisc.c --- linus/arch/parisc/kernel/sys_parisc.c 2005-03-10 04:08:58.000000000 +1100 +++ linus-compat_sys_ipc.3/arch/parisc/kernel/sys_parisc.c 2005-04-05 15:41:29.000000000 +1000 @@ -161,17 +161,6 @@ asmlinkage unsigned long sys_mmap(unsign } } -long sys_shmat_wrapper(int shmid, char __user *shmaddr, int shmflag) -{ - unsigned long raddr; - int r; - - r = do_shmat(shmid, shmaddr, shmflag, &raddr); - if (r < 0) - return r; - return raddr; -} - /* Fucking broken ABI */ #ifdef CONFIG_64BIT diff -ruNp linus/arch/parisc/kernel/syscall_table.S linus-compat_sys_ipc.3/arch/parisc/kernel/syscall_table.S --- linus/arch/parisc/kernel/syscall_table.S 2005-01-16 07:07:51.000000000 +1100 +++ linus-compat_sys_ipc.3/arch/parisc/kernel/syscall_table.S 2005-04-05 15:43:04.000000000 +1000 @@ -297,7 +297,7 @@ ENTRY_DIFF(msgrcv) ENTRY_SAME(msgget) /* 190 */ ENTRY_SAME(msgctl) - ENTRY_SAME(shmat_wrapper) + ENTRY_SAME(shmat) ENTRY_SAME(shmdt) ENTRY_SAME(shmget) ENTRY_SAME(shmctl) /* 195 */ diff -ruNp linus/arch/ppc/kernel/syscalls.c linus-compat_sys_ipc.3/arch/ppc/kernel/syscalls.c --- linus/arch/ppc/kernel/syscalls.c 2005-03-14 13:07:08.000000000 +1100 +++ linus-compat_sys_ipc.3/arch/ppc/kernel/syscalls.c 2005-04-06 13:37:44.000000000 +1000 @@ -114,18 +114,10 @@ sys_ipc (uint call, int first, int secon case MSGCTL: ret = sys_msgctl (first, second, (struct msqid_ds __user *) ptr); break; - case SHMAT: { - ulong raddr; - - if ((ret = access_ok(VERIFY_WRITE, (ulong __user *) third, - sizeof(ulong)) ? 0 : -EFAULT)) - break; - ret = do_shmat (first, (char __user *) ptr, second, &raddr); - if (ret) - break; - ret = put_user (raddr, (ulong __user *) third); + case SHMAT: + ret = ipc_shmat(first, ptr, second, + (unsigned long __user *)third); break; - } case SHMDT: ret = sys_shmdt ((char __user *)ptr); break; diff -ruNp linus/arch/ppc64/kernel/syscalls.c linus-compat_sys_ipc.3/arch/ppc64/kernel/syscalls.c --- linus/arch/ppc64/kernel/syscalls.c 2005-03-29 16:06:36.000000000 +1000 +++ linus-compat_sys_ipc.3/arch/ppc64/kernel/syscalls.c 2005-04-06 13:37:50.000000000 +1000 @@ -125,15 +125,10 @@ sys_ipc (uint call, int first, unsigned break; case SHMAT: switch (version) { - default: { - ulong raddr; - ret = do_shmat(first, (char __user *) ptr, - (int)second, &raddr); - if (ret) - break; - ret = put_user (raddr, (ulong __user *) third); + default: + ret = ipc_shmat(first, ptr, second, + (unsigned long __user *)third); break; - } case 1: /* iBCS2 emulator entry point */ ret = -EINVAL; if (!segment_eq(get_fs(), get_ds())) diff -ruNp linus/arch/s390/kernel/sys_s390.c linus-compat_sys_ipc.3/arch/s390/kernel/sys_s390.c --- linus/arch/s390/kernel/sys_s390.c 2005-02-11 13:05:29.000000000 +1100 +++ linus-compat_sys_ipc.3/arch/s390/kernel/sys_s390.c 2005-04-06 13:37:55.000000000 +1000 @@ -187,15 +187,9 @@ asmlinkage long sys_ipc(uint call, int f return sys_msgctl(first, (int)second, (struct msqid_ds __user *)ptr); - case SHMAT: { - ulong raddr; - ret = do_shmat(first, (char __user *)ptr, - (int)second, &raddr); - if (ret) - return ret; - return put_user (raddr, (ulong __user *) third); - break; - } + case SHMAT: + return ipc_shmat(first, ptr, second, + (unsigned long __user *)third); case SHMDT: return sys_shmdt ((char __user *)ptr); case SHMGET: diff -ruNp linus/arch/sh/kernel/sys_sh.c linus-compat_sys_ipc.3/arch/sh/kernel/sys_sh.c --- linus/arch/sh/kernel/sys_sh.c 2004-03-25 08:30:37.000000000 +1100 +++ linus-compat_sys_ipc.3/arch/sh/kernel/sys_sh.c 2005-04-06 13:38:03.000000000 +1000 @@ -225,14 +225,9 @@ asmlinkage int sys_ipc(uint call, int fi switch (call) { case SHMAT: switch (version) { - default: { - ulong raddr; - ret = do_shmat (first, (char __user *) ptr, - second, &raddr); - if (ret) - return ret; - return put_user (raddr, (ulong __user *) third); - } + default: + return ipc_shmat(first, ptr, second, + (unsigned long __user *)third); case 1: /* iBCS2 emulator entry point */ if (!segment_eq(get_fs(), get_ds())) return -EINVAL; diff -ruNp linus/arch/sh64/kernel/sys_sh64.c linus-compat_sys_ipc.3/arch/sh64/kernel/sys_sh64.c --- linus/arch/sh64/kernel/sys_sh64.c 2005-03-09 06:08:28.000000000 +1100 +++ linus-compat_sys_ipc.3/arch/sh64/kernel/sys_sh64.c 2005-04-06 13:38:41.000000000 +1000 @@ -245,14 +245,9 @@ asmlinkage int sys_ipc(uint call, int fi switch (call) { case SHMAT: switch (version) { - default: { - ulong raddr; - ret = do_shmat (first, (char __user *) ptr, - second, &raddr); - if (ret) - return ret; - return put_user (raddr, (ulong __user *) third); - } + default: + return ipc_shmat(first, ptr, second, + (unsigned long __user *)third); case 1: /* iBCS2 emulator entry point */ if (!segment_eq(get_fs(), get_ds())) return -EINVAL; @@ -283,18 +278,3 @@ asmlinkage int sys_uname(struct old_utsn up_read(&uts_sem); return err?-EFAULT:0; } - -/* Copy from mips version */ -asmlinkage long sys_shmatcall(int shmid, char __user *shmaddr, - int shmflg) -{ - unsigned long raddr; - int err; - - err = do_shmat(shmid, shmaddr, shmflg, &raddr); - if (err) - return err; - - err = raddr; - return err; -} diff -ruNp linus/arch/sh64/kernel/syscalls.S linus-compat_sys_ipc.3/arch/sh64/kernel/syscalls.S --- linus/arch/sh64/kernel/syscalls.S 2005-03-09 06:08:28.000000000 +1100 +++ linus-compat_sys_ipc.3/arch/sh64/kernel/syscalls.S 2005-04-05 15:34:10.000000000 +1000 @@ -268,7 +268,7 @@ sys_call_table: .long sys_msgrcv .long sys_msgget .long sys_msgctl - .long sys_shmatcall + .long sys_shmat .long sys_shmdt /* 245 */ .long sys_shmget .long sys_shmctl diff -ruNp linus/arch/sparc/kernel/sys_sparc.c linus-compat_sys_ipc.3/arch/sparc/kernel/sys_sparc.c --- linus/arch/sparc/kernel/sys_sparc.c 2005-03-14 13:07:08.000000000 +1100 +++ linus-compat_sys_ipc.3/arch/sparc/kernel/sys_sparc.c 2005-04-06 13:38:10.000000000 +1000 @@ -185,17 +185,10 @@ asmlinkage int sys_ipc (uint call, int f switch (call) { case SHMAT: switch (version) { - case 0: default: { - ulong raddr; - err = do_shmat (first, (char __user *) ptr, second, &raddr); - if (err) - goto out; - err = -EFAULT; - if (put_user (raddr, (ulong __user *) third)) - goto out; - err = 0; + case 0: default: + err = ipc_shmat(first, ptr, second, + (unsigned long __user *)third); goto out; - } case 1: /* iBCS2 emulator entry point */ err = -EINVAL; goto out; diff -ruNp linus/arch/sparc64/kernel/sys_sparc.c linus-compat_sys_ipc.3/arch/sparc64/kernel/sys_sparc.c --- linus/arch/sparc64/kernel/sys_sparc.c 2005-02-11 13:05:29.000000000 +1100 +++ linus-compat_sys_ipc.3/arch/sparc64/kernel/sys_sparc.c 2005-04-06 13:38:14.000000000 +1000 @@ -259,14 +259,9 @@ asmlinkage long sys_ipc(unsigned int cal } if (call <= SHMCTL) { switch (call) { - case SHMAT: { - ulong raddr; - err = do_shmat(first, ptr, (int)second, &raddr); - if (!err) { - if (put_user(raddr, - (ulong __user *) third)) - err = -EFAULT; - } + case SHMAT: + err = ipc_shmat(first, ptr, second, + (unsigned long __user *)third); goto out; } case SHMDT: diff -ruNp linus/arch/um/include/sysdep-x86_64/syscalls.h linus-compat_sys_ipc.3/arch/um/include/sysdep-x86_64/syscalls.h --- linus/arch/um/include/sysdep-x86_64/syscalls.h 2005-04-01 05:09:16.000000000 +1000 +++ linus-compat_sys_ipc.3/arch/um/include/sysdep-x86_64/syscalls.h 2005-04-05 15:44:11.000000000 +1000 @@ -26,7 +26,6 @@ extern syscall_handler_t *ia32_sys_call_ extern long old_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff); -extern syscall_handler_t wrap_sys_shmat; extern syscall_handler_t sys_modify_ldt; extern syscall_handler_t sys_arch_prctl; @@ -36,7 +35,7 @@ extern syscall_handler_t sys_arch_prctl; [ __NR_mincore ] = (syscall_handler_t *) sys_mincore, \ [ __NR_madvise ] = (syscall_handler_t *) sys_madvise, \ [ __NR_shmget ] = (syscall_handler_t *) sys_shmget, \ - [ __NR_shmat ] = (syscall_handler_t *) wrap_sys_shmat, \ + [ __NR_shmat ] = (syscall_handler_t *) sys_shmat, \ [ __NR_shmctl ] = (syscall_handler_t *) sys_shmctl, \ [ __NR_semop ] = (syscall_handler_t *) sys_semop, \ [ __NR_semget ] = (syscall_handler_t *) sys_semget, \ diff -ruNp linus/arch/um/sys-i386/syscalls.c linus-compat_sys_ipc.3/arch/um/sys-i386/syscalls.c --- linus/arch/um/sys-i386/syscalls.c 2005-03-14 13:07:08.000000000 +1100 +++ linus-compat_sys_ipc.3/arch/um/sys-i386/syscalls.c 2005-04-06 13:38:22.000000000 +1000 @@ -143,13 +143,9 @@ long sys_ipc (uint call, int first, int case SHMAT: switch (version) { - default: { - ulong raddr; - ret = do_shmat (first, (char *) ptr, second, &raddr); - if (ret) - return ret; - return put_user (raddr, (ulong *) third); - } + default: + return ipc_shmat(first, ptr, second, + (unsigned long __user *)third); case 1: /* iBCS2 emulator entry point */ if (!segment_eq(get_fs(), get_ds())) return -EINVAL; diff -ruNp linus/arch/um/sys-x86_64/syscalls.c linus-compat_sys_ipc.3/arch/um/sys-x86_64/syscalls.c --- linus/arch/um/sys-x86_64/syscalls.c 2005-03-14 13:07:08.000000000 +1100 +++ linus-compat_sys_ipc.3/arch/um/sys-x86_64/syscalls.c 2005-04-05 15:45:51.000000000 +1000 @@ -14,13 +14,6 @@ #include "asm/prctl.h" /* XXX This should get the constants from libc */ #include "choose-mode.h" -asmlinkage long wrap_sys_shmat(int shmid, char __user *shmaddr, int shmflg) -{ - unsigned long raddr; - - return do_shmat(shmid, shmaddr, shmflg, &raddr) ?: (long) raddr; -} - #ifdef CONFIG_MODE_TT extern int modify_ldt(int func, void *ptr, unsigned long bytecount); diff -ruNp linus/arch/v850/kernel/syscalls.c linus-compat_sys_ipc.3/arch/v850/kernel/syscalls.c --- linus/arch/v850/kernel/syscalls.c 2005-03-14 13:07:08.000000000 +1100 +++ linus-compat_sys_ipc.3/arch/v850/kernel/syscalls.c 2005-04-06 13:38:36.000000000 +1000 @@ -101,18 +101,10 @@ sys_ipc (uint call, int first, int secon break; case SHMAT: switch (version) { - default: { - ulong raddr; - - if ((ret = access_ok(VERIFY_WRITE, (ulong*) third, - sizeof(ulong)) ? 0 : -EFAULT)) - break; - ret = do_shmat (first, (char *) ptr, second, &raddr); - if (ret) - break; - ret = put_user (raddr, (ulong *) third); + default: + ret = ipc_shmat(first, ptr, second, + (unsigned long __user *)third); break; - } case 1: /* iBCS2 emulator entry point */ if (!segment_eq(get_fs(), get_ds())) break; diff -ruNp linus/arch/x86_64/kernel/sys_x86_64.c linus-compat_sys_ipc.3/arch/x86_64/kernel/sys_x86_64.c --- linus/arch/x86_64/kernel/sys_x86_64.c 2005-04-01 05:09:16.000000000 +1000 +++ linus-compat_sys_ipc.3/arch/x86_64/kernel/sys_x86_64.c 2005-04-05 15:46:08.000000000 +1000 @@ -152,12 +152,6 @@ asmlinkage long sys_uname(struct new_uts return err ? -EFAULT : 0; } -asmlinkage long wrap_sys_shmat(int shmid, char __user *shmaddr, int shmflg) -{ - unsigned long raddr; - return do_shmat(shmid,shmaddr,shmflg,&raddr) ?: (long)raddr; -} - asmlinkage long sys_time64(long __user * tloc) { struct timeval now; diff -ruNp linus/include/asm-x86_64/unistd.h linus-compat_sys_ipc.3/include/asm-x86_64/unistd.h --- linus/include/asm-x86_64/unistd.h 2005-04-01 05:09:17.000000000 +1000 +++ linus-compat_sys_ipc.3/include/asm-x86_64/unistd.h 2005-04-05 15:46:35.000000000 +1000 @@ -76,7 +76,7 @@ __SYSCALL(__NR_madvise, sys_madvise) #define __NR_shmget 29 __SYSCALL(__NR_shmget, sys_shmget) #define __NR_shmat 30 -__SYSCALL(__NR_shmat, wrap_sys_shmat) +__SYSCALL(__NR_shmat, sys_shmat) #define __NR_shmctl 31 __SYSCALL(__NR_shmctl, sys_shmctl) diff -ruNp linus/include/linux/shm.h linus-compat_sys_ipc.3/include/linux/shm.h --- linus/include/linux/shm.h 2004-08-25 07:48:22.000000000 +1000 +++ linus-compat_sys_ipc.3/include/linux/shm.h 2005-04-06 13:41:30.000000000 +1000 @@ -95,12 +95,20 @@ struct shmid_kernel /* private to the ke #ifdef CONFIG_SYSVIPC long do_shmat(int shmid, char __user *shmaddr, int shmflg, unsigned long *addr); +long ipc_shmat(int shmid, char __user *shmaddr, int shmflg, + unsigned long __user *addr); #else static inline long do_shmat(int shmid, char __user *shmaddr, int shmflg, unsigned long *addr) { return -ENOSYS; } + +static inline long ipc_shmat(int shmid, char __user *shmaddr, + int shmflg, unsigned long __user *addr) +{ + return -ENOSYS; +} #endif #endif /* __KERNEL__ */ diff -ruNp linus/include/linux/syscalls.h linus-compat_sys_ipc.3/include/linux/syscalls.h --- linus/include/linux/syscalls.h 2005-01-05 17:06:08.000000000 +1100 +++ linus-compat_sys_ipc.3/include/linux/syscalls.h 2005-04-06 13:39:42.000000000 +1000 @@ -456,8 +456,7 @@ asmlinkage long sys_semctl(int semid, in asmlinkage long sys_semtimedop(int semid, struct sembuf __user *sops, unsigned nsops, const struct timespec __user *timeout); -asmlinkage long sys_shmat(int shmid, char __user *shmaddr, - int shmflg, unsigned long __user *addr); +asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg); asmlinkage long sys_shmget(key_t key, size_t size, int flag); asmlinkage long sys_shmdt(char __user *shmaddr); asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf); diff -ruNp linus/ipc/shm.c linus-compat_sys_ipc.3/ipc/shm.c --- linus/ipc/shm.c 2005-03-18 04:08:16.000000000 +1100 +++ linus-compat_sys_ipc.3/ipc/shm.c 2005-04-06 13:42:38.000000000 +1000 @@ -28,6 +28,7 @@ #include <linux/security.h> #include <linux/syscalls.h> #include <linux/audit.h> +#include <linux/ptrace.h> /* for force_successful_syscall_return() */ #include <asm/uaccess.h> #include "util.h" @@ -772,6 +773,40 @@ out: } /* + * Attach a shared memory segment. This version of the system + * call returns the attached address through the last parameter. + */ +long ipc_shmat(int shmid, char __user *shmaddr, int shmflg, + unsigned long __user *addr) +{ + ulong raddr; + long ret; + + if (!access_ok(VERIFY_WRITE, addr, sizeof(*addr))) + return -EFAULT; + ret = do_shmat(shmid, shmaddr, shmflg, &raddr); + if (ret == 0) + ret = __put_user(raddr, addr); + return ret; +} + +/* + * Attach a shared memory segment. This version of the system + * call returns the attached address as its return value + */ +asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg) +{ + ulong raddr; + long ret; + + ret = do_shmat(shmid, shmaddr, shmflg, &raddr); + if (ret < 0) + return ret; + force_successful_syscall_return(); + return raddr; +} + +/* * detach and kill segment if marked destroyed. * The work is done in shm_close. */ diff -ruNp linus/kernel/sys_ni.c linus-compat_sys_ipc.3/kernel/sys_ni.c --- linus/kernel/sys_ni.c 2005-03-29 16:06:38.000000000 +1000 +++ linus-compat_sys_ipc.3/kernel/sys_ni.c 2005-04-06 13:43:03.000000000 +1000 @@ -52,6 +52,7 @@ cond_syscall(sys_msgsnd); cond_syscall(sys_msgrcv); cond_syscall(sys_msgctl); cond_syscall(sys_shmget); +cond_syscall(sys_shmat); cond_syscall(sys_shmdt); cond_syscall(sys_shmctl); cond_syscall(sys_mq_open);
pgp2JfRf8XTrT.pgp
Description: PGP signature
