diff options
| -rw-r--r-- | arch/Kconfig | 3 | ||||
| -rw-r--r-- | arch/mips/Kconfig | 1 | ||||
| -rw-r--r-- | arch/powerpc/Kconfig | 1 | ||||
| -rw-r--r-- | arch/s390/Kconfig | 1 | ||||
| -rw-r--r-- | arch/sparc/Kconfig | 1 | ||||
| -rw-r--r-- | arch/tile/include/asm/compat.h | 11 | ||||
| -rw-r--r-- | arch/tile/kernel/compat.c | 43 | ||||
| -rw-r--r-- | arch/x86/Kconfig | 1 | ||||
| -rw-r--r-- | include/linux/compat.h | 12 | ||||
| -rw-r--r-- | ipc/compat.c | 70 |
10 files changed, 83 insertions, 61 deletions
diff --git a/arch/Kconfig b/arch/Kconfig index 4f55c736be11..b37f8f3ffa54 100644 --- a/arch/Kconfig +++ b/arch/Kconfig | |||
| @@ -199,4 +199,7 @@ config HAVE_CMPXCHG_LOCAL | |||
| 199 | config HAVE_CMPXCHG_DOUBLE | 199 | config HAVE_CMPXCHG_DOUBLE |
| 200 | bool | 200 | bool |
| 201 | 201 | ||
| 202 | config ARCH_WANT_OLD_COMPAT_IPC | ||
| 203 | bool | ||
| 204 | |||
| 202 | source "kernel/gcov/Kconfig" | 205 | source "kernel/gcov/Kconfig" |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 5ab6e89603c5..4bbbb40f352a 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
| @@ -2456,6 +2456,7 @@ config MIPS32_COMPAT | |||
| 2456 | config COMPAT | 2456 | config COMPAT |
| 2457 | bool | 2457 | bool |
| 2458 | depends on MIPS32_COMPAT | 2458 | depends on MIPS32_COMPAT |
| 2459 | select ARCH_WANT_OLD_COMPAT_IPC | ||
| 2459 | default y | 2460 | default y |
| 2460 | 2461 | ||
| 2461 | config SYSVIPC_COMPAT | 2462 | config SYSVIPC_COMPAT |
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 1919634a9b32..48ab0bb38924 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
| @@ -152,6 +152,7 @@ config COMPAT | |||
| 152 | bool | 152 | bool |
| 153 | default y if PPC64 | 153 | default y if PPC64 |
| 154 | select COMPAT_BINFMT_ELF | 154 | select COMPAT_BINFMT_ELF |
| 155 | select ARCH_WANT_OLD_COMPAT_IPC | ||
| 155 | 156 | ||
| 156 | config SYSVIPC_COMPAT | 157 | config SYSVIPC_COMPAT |
| 157 | bool | 158 | bool |
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 6d99a5fcc090..0ff53e350092 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
| @@ -218,6 +218,7 @@ config COMPAT | |||
| 218 | prompt "Kernel support for 31 bit emulation" | 218 | prompt "Kernel support for 31 bit emulation" |
| 219 | depends on 64BIT | 219 | depends on 64BIT |
| 220 | select COMPAT_BINFMT_ELF | 220 | select COMPAT_BINFMT_ELF |
| 221 | select ARCH_WANT_OLD_COMPAT_IPC | ||
| 221 | help | 222 | help |
| 222 | Select this option if you want to enable your system kernel to | 223 | Select this option if you want to enable your system kernel to |
| 223 | handle system-calls from ELF binaries for 31 bit ESA. This option | 224 | handle system-calls from ELF binaries for 31 bit ESA. This option |
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index ca5580e4d813..64e1a8e7cab3 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig | |||
| @@ -576,6 +576,7 @@ config COMPAT | |||
| 576 | depends on SPARC64 | 576 | depends on SPARC64 |
| 577 | default y | 577 | default y |
| 578 | select COMPAT_BINFMT_ELF | 578 | select COMPAT_BINFMT_ELF |
| 579 | select ARCH_WANT_OLD_COMPAT_IPC | ||
| 579 | 580 | ||
| 580 | config SYSVIPC_COMPAT | 581 | config SYSVIPC_COMPAT |
| 581 | bool | 582 | bool |
diff --git a/arch/tile/include/asm/compat.h b/arch/tile/include/asm/compat.h index bf95f55b82b0..4b4b28969a65 100644 --- a/arch/tile/include/asm/compat.h +++ b/arch/tile/include/asm/compat.h | |||
| @@ -242,17 +242,6 @@ long compat_sys_fallocate(int fd, int mode, | |||
| 242 | long compat_sys_sched_rr_get_interval(compat_pid_t pid, | 242 | long compat_sys_sched_rr_get_interval(compat_pid_t pid, |
| 243 | struct compat_timespec __user *interval); | 243 | struct compat_timespec __user *interval); |
| 244 | 244 | ||
| 245 | /* Versions of compat functions that differ from generic Linux. */ | ||
| 246 | struct compat_msgbuf; | ||
| 247 | long tile_compat_sys_msgsnd(int msqid, | ||
| 248 | struct compat_msgbuf __user *msgp, | ||
| 249 | size_t msgsz, int msgflg); | ||
| 250 | long tile_compat_sys_msgrcv(int msqid, | ||
| 251 | struct compat_msgbuf __user *msgp, | ||
| 252 | size_t msgsz, long msgtyp, int msgflg); | ||
| 253 | long tile_compat_sys_ptrace(compat_long_t request, compat_long_t pid, | ||
| 254 | compat_long_t addr, compat_long_t data); | ||
| 255 | |||
| 256 | /* Tilera Linux syscalls that don't have "compat" versions. */ | 245 | /* Tilera Linux syscalls that don't have "compat" versions. */ |
| 257 | #define compat_sys_flush_cache sys_flush_cache | 246 | #define compat_sys_flush_cache sys_flush_cache |
| 258 | 247 | ||
diff --git a/arch/tile/kernel/compat.c b/arch/tile/kernel/compat.c index bf5e9d70266c..d67459b9ac2a 100644 --- a/arch/tile/kernel/compat.c +++ b/arch/tile/kernel/compat.c | |||
| @@ -16,7 +16,6 @@ | |||
| 16 | #define __SYSCALL_COMPAT | 16 | #define __SYSCALL_COMPAT |
| 17 | 17 | ||
| 18 | #include <linux/compat.h> | 18 | #include <linux/compat.h> |
| 19 | #include <linux/msg.h> | ||
| 20 | #include <linux/syscalls.h> | 19 | #include <linux/syscalls.h> |
| 21 | #include <linux/kdev_t.h> | 20 | #include <linux/kdev_t.h> |
| 22 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
| @@ -95,52 +94,10 @@ long compat_sys_sched_rr_get_interval(compat_pid_t pid, | |||
| 95 | return ret; | 94 | return ret; |
| 96 | } | 95 | } |
| 97 | 96 | ||
| 98 | /* | ||
| 99 | * The usual compat_sys_msgsnd() and _msgrcv() seem to be assuming | ||
| 100 | * some different calling convention than our normal 32-bit tile code. | ||
| 101 | */ | ||
| 102 | |||
| 103 | /* Already defined in ipc/compat.c, but we need it here. */ | ||
| 104 | struct compat_msgbuf { | ||
| 105 | compat_long_t mtype; | ||
| 106 | char mtext[1]; | ||
| 107 | }; | ||
| 108 | |||
| 109 | long tile_compat_sys_msgsnd(int msqid, | ||
| 110 | struct compat_msgbuf __user *msgp, | ||
| 111 | size_t msgsz, int msgflg) | ||
| 112 | { | ||
| 113 | compat_long_t mtype; | ||
| 114 | |||
| 115 | if (get_user(mtype, &msgp->mtype)) | ||
| 116 | return -EFAULT; | ||
| 117 | return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg); | ||
| 118 | } | ||
| 119 | |||
| 120 | long tile_compat_sys_msgrcv(int msqid, | ||
| 121 | struct compat_msgbuf __user *msgp, | ||
| 122 | size_t msgsz, long msgtyp, int msgflg) | ||
| 123 | { | ||
| 124 | long err, mtype; | ||
| 125 | |||
| 126 | err = do_msgrcv(msqid, &mtype, msgp->mtext, msgsz, msgtyp, msgflg); | ||
| 127 | if (err < 0) | ||
| 128 | goto out; | ||
| 129 | |||
| 130 | if (put_user(mtype, &msgp->mtype)) | ||
| 131 | err = -EFAULT; | ||
| 132 | out: | ||
| 133 | return err; | ||
| 134 | } | ||
| 135 | |||
| 136 | /* Provide the compat syscall number to call mapping. */ | 97 | /* Provide the compat syscall number to call mapping. */ |
| 137 | #undef __SYSCALL | 98 | #undef __SYSCALL |
| 138 | #define __SYSCALL(nr, call) [nr] = (call), | 99 | #define __SYSCALL(nr, call) [nr] = (call), |
| 139 | 100 | ||
| 140 | /* The generic versions of these don't work for Tile. */ | ||
| 141 | #define compat_sys_msgrcv tile_compat_sys_msgrcv | ||
| 142 | #define compat_sys_msgsnd tile_compat_sys_msgsnd | ||
| 143 | |||
| 144 | /* See comments in sys.c */ | 101 | /* See comments in sys.c */ |
| 145 | #define compat_sys_fadvise64_64 sys32_fadvise64_64 | 102 | #define compat_sys_fadvise64_64 sys32_fadvise64_64 |
| 146 | #define compat_sys_readahead sys32_readahead | 103 | #define compat_sys_readahead sys32_readahead |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 5bed94e189fa..cde163dc6058 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
| @@ -2178,6 +2178,7 @@ config IA32_AOUT | |||
| 2178 | config COMPAT | 2178 | config COMPAT |
| 2179 | def_bool y | 2179 | def_bool y |
| 2180 | depends on IA32_EMULATION | 2180 | depends on IA32_EMULATION |
| 2181 | select ARCH_WANT_OLD_COMPAT_IPC | ||
| 2181 | 2182 | ||
| 2182 | config COMPAT_FOR_U64_ALIGNMENT | 2183 | config COMPAT_FOR_U64_ALIGNMENT |
| 2183 | def_bool COMPAT | 2184 | def_bool COMPAT |
diff --git a/include/linux/compat.h b/include/linux/compat.h index 7e05fcee75a1..35c2dbf2448a 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h | |||
| @@ -224,6 +224,7 @@ struct compat_sysinfo; | |||
| 224 | struct compat_sysctl_args; | 224 | struct compat_sysctl_args; |
| 225 | struct compat_kexec_segment; | 225 | struct compat_kexec_segment; |
| 226 | struct compat_mq_attr; | 226 | struct compat_mq_attr; |
| 227 | struct compat_msgbuf; | ||
| 227 | 228 | ||
| 228 | extern void compat_exit_robust_list(struct task_struct *curr); | 229 | extern void compat_exit_robust_list(struct task_struct *curr); |
| 229 | 230 | ||
| @@ -234,13 +235,22 @@ asmlinkage long | |||
| 234 | compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr, | 235 | compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr, |
| 235 | compat_size_t __user *len_ptr); | 236 | compat_size_t __user *len_ptr); |
| 236 | 237 | ||
| 238 | #ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC | ||
| 237 | long compat_sys_semctl(int first, int second, int third, void __user *uptr); | 239 | long compat_sys_semctl(int first, int second, int third, void __user *uptr); |
| 238 | long compat_sys_msgsnd(int first, int second, int third, void __user *uptr); | 240 | long compat_sys_msgsnd(int first, int second, int third, void __user *uptr); |
| 239 | long compat_sys_msgrcv(int first, int second, int msgtyp, int third, | 241 | long compat_sys_msgrcv(int first, int second, int msgtyp, int third, |
| 240 | int version, void __user *uptr); | 242 | int version, void __user *uptr); |
| 241 | long compat_sys_msgctl(int first, int second, void __user *uptr); | ||
| 242 | long compat_sys_shmat(int first, int second, compat_uptr_t third, int version, | 243 | long compat_sys_shmat(int first, int second, compat_uptr_t third, int version, |
| 243 | void __user *uptr); | 244 | void __user *uptr); |
| 245 | #else | ||
| 246 | long compat_sys_semctl(int semid, int semnum, int cmd, int arg); | ||
| 247 | long compat_sys_msgsnd(int msqid, struct compat_msgbuf __user *msgp, | ||
| 248 | size_t msgsz, int msgflg); | ||
| 249 | long compat_sys_msgrcv(int msqid, struct compat_msgbuf __user *msgp, | ||
| 250 | size_t msgsz, long msgtyp, int msgflg); | ||
| 251 | long compat_sys_shmat(int shmid, compat_uptr_t shmaddr, int shmflg); | ||
| 252 | #endif | ||
| 253 | long compat_sys_msgctl(int first, int second, void __user *uptr); | ||
| 244 | long compat_sys_shmctl(int first, int second, void __user *uptr); | 254 | long compat_sys_shmctl(int first, int second, void __user *uptr); |
| 245 | long compat_sys_semtimedop(int semid, struct sembuf __user *tsems, | 255 | long compat_sys_semtimedop(int semid, struct sembuf __user *tsems, |
| 246 | unsigned nsems, const struct compat_timespec __user *timeout); | 256 | unsigned nsems, const struct compat_timespec __user *timeout); |
diff --git a/ipc/compat.c b/ipc/compat.c index 845a28738d3a..a6df704f521e 100644 --- a/ipc/compat.c +++ b/ipc/compat.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <linux/msg.h> | 27 | #include <linux/msg.h> |
| 28 | #include <linux/shm.h> | 28 | #include <linux/shm.h> |
| 29 | #include <linux/syscalls.h> | 29 | #include <linux/syscalls.h> |
| 30 | #include <linux/ptrace.h> | ||
| 30 | 31 | ||
| 31 | #include <linux/mutex.h> | 32 | #include <linux/mutex.h> |
| 32 | #include <asm/uaccess.h> | 33 | #include <asm/uaccess.h> |
| @@ -117,6 +118,7 @@ extern int sem_ctls[]; | |||
| 117 | 118 | ||
| 118 | static inline int compat_ipc_parse_version(int *cmd) | 119 | static inline int compat_ipc_parse_version(int *cmd) |
| 119 | { | 120 | { |
| 121 | #ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC | ||
| 120 | int version = *cmd & IPC_64; | 122 | int version = *cmd & IPC_64; |
| 121 | 123 | ||
| 122 | /* this is tricky: architectures that have support for the old | 124 | /* this is tricky: architectures that have support for the old |
| @@ -128,6 +130,10 @@ static inline int compat_ipc_parse_version(int *cmd) | |||
| 128 | *cmd &= ~IPC_64; | 130 | *cmd &= ~IPC_64; |
| 129 | #endif | 131 | #endif |
| 130 | return version; | 132 | return version; |
| 133 | #else | ||
| 134 | /* With the asm-generic APIs, we always use the 64-bit versions. */ | ||
| 135 | return IPC_64; | ||
| 136 | #endif | ||
| 131 | } | 137 | } |
| 132 | 138 | ||
| 133 | static inline int __get_compat_ipc64_perm(struct ipc64_perm *p64, | 139 | static inline int __get_compat_ipc64_perm(struct ipc64_perm *p64, |
| @@ -232,10 +238,9 @@ static inline int put_compat_semid_ds(struct semid64_ds *s, | |||
| 232 | return err; | 238 | return err; |
| 233 | } | 239 | } |
| 234 | 240 | ||
| 235 | long compat_sys_semctl(int first, int second, int third, void __user *uptr) | 241 | static long do_compat_semctl(int first, int second, int third, u32 pad) |
| 236 | { | 242 | { |
| 237 | union semun fourth; | 243 | union semun fourth; |
| 238 | u32 pad; | ||
| 239 | int err, err2; | 244 | int err, err2; |
| 240 | struct semid64_ds s64; | 245 | struct semid64_ds s64; |
| 241 | struct semid64_ds __user *up64; | 246 | struct semid64_ds __user *up64; |
| @@ -243,10 +248,6 @@ long compat_sys_semctl(int first, int second, int third, void __user *uptr) | |||
| 243 | 248 | ||
| 244 | memset(&s64, 0, sizeof(s64)); | 249 | memset(&s64, 0, sizeof(s64)); |
| 245 | 250 | ||
| 246 | if (!uptr) | ||
| 247 | return -EINVAL; | ||
| 248 | if (get_user(pad, (u32 __user *) uptr)) | ||
| 249 | return -EFAULT; | ||
| 250 | if ((third & (~IPC_64)) == SETVAL) | 251 | if ((third & (~IPC_64)) == SETVAL) |
| 251 | fourth.val = (int) pad; | 252 | fourth.val = (int) pad; |
| 252 | else | 253 | else |
| @@ -305,6 +306,18 @@ long compat_sys_semctl(int first, int second, int third, void __user *uptr) | |||
| 305 | return err; | 306 | return err; |
| 306 | } | 307 | } |
| 307 | 308 | ||
| 309 | #ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC | ||
| 310 | long compat_sys_semctl(int first, int second, int third, void __user *uptr) | ||
| 311 | { | ||
| 312 | u32 pad; | ||
| 313 | |||
| 314 | if (!uptr) | ||
| 315 | return -EINVAL; | ||
| 316 | if (get_user(pad, (u32 __user *) uptr)) | ||
| 317 | return -EFAULT; | ||
| 318 | return do_compat_semctl(first, second, third, pad); | ||
| 319 | } | ||
| 320 | |||
| 308 | long compat_sys_msgsnd(int first, int second, int third, void __user *uptr) | 321 | long compat_sys_msgsnd(int first, int second, int third, void __user *uptr) |
| 309 | { | 322 | { |
| 310 | struct compat_msgbuf __user *up = uptr; | 323 | struct compat_msgbuf __user *up = uptr; |
| @@ -353,6 +366,37 @@ long compat_sys_msgrcv(int first, int second, int msgtyp, int third, | |||
| 353 | out: | 366 | out: |
| 354 | return err; | 367 | return err; |
| 355 | } | 368 | } |
| 369 | #else | ||
| 370 | long compat_sys_semctl(int semid, int semnum, int cmd, int arg) | ||
| 371 | { | ||
| 372 | return do_compat_semctl(semid, semnum, cmd, arg); | ||
| 373 | } | ||
| 374 | |||
| 375 | long compat_sys_msgsnd(int msqid, struct compat_msgbuf __user *msgp, | ||
| 376 | size_t msgsz, int msgflg) | ||
| 377 | { | ||
| 378 | compat_long_t mtype; | ||
| 379 | |||
| 380 | if (get_user(mtype, &msgp->mtype)) | ||
| 381 | return -EFAULT; | ||
| 382 | return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg); | ||
| 383 | } | ||
| 384 | |||
| 385 | long compat_sys_msgrcv(int msqid, struct compat_msgbuf __user *msgp, | ||
| 386 | size_t msgsz, long msgtyp, int msgflg) | ||
| 387 | { | ||
| 388 | long err, mtype; | ||
| 389 | |||
| 390 | err = do_msgrcv(msqid, &mtype, msgp->mtext, msgsz, msgtyp, msgflg); | ||
| 391 | if (err < 0) | ||
| 392 | goto out; | ||
| 393 | |||
| 394 | if (put_user(mtype, &msgp->mtype)) | ||
| 395 | err = -EFAULT; | ||
| 396 | out: | ||
| 397 | return err; | ||
| 398 | } | ||
| 399 | #endif | ||
| 356 | 400 | ||
| 357 | static inline int get_compat_msqid64(struct msqid64_ds *m64, | 401 | static inline int get_compat_msqid64(struct msqid64_ds *m64, |
| 358 | struct compat_msqid64_ds __user *up64) | 402 | struct compat_msqid64_ds __user *up64) |
| @@ -470,6 +514,7 @@ long compat_sys_msgctl(int first, int second, void __user *uptr) | |||
| 470 | return err; | 514 | return err; |
| 471 | } | 515 | } |
| 472 | 516 | ||
| 517 | #ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC | ||
| 473 | long compat_sys_shmat(int first, int second, compat_uptr_t third, int version, | 518 | long compat_sys_shmat(int first, int second, compat_uptr_t third, int version, |
| 474 | void __user *uptr) | 519 | void __user *uptr) |
| 475 | { | 520 | { |
| @@ -485,6 +530,19 @@ long compat_sys_shmat(int first, int second, compat_uptr_t third, int version, | |||
| 485 | uaddr = compat_ptr(third); | 530 | uaddr = compat_ptr(third); |
| 486 | return put_user(raddr, uaddr); | 531 | return put_user(raddr, uaddr); |
| 487 | } | 532 | } |
| 533 | #else | ||
| 534 | long compat_sys_shmat(int shmid, compat_uptr_t shmaddr, int shmflg) | ||
| 535 | { | ||
| 536 | unsigned long ret; | ||
| 537 | long err; | ||
| 538 | |||
| 539 | err = do_shmat(shmid, compat_ptr(shmaddr), shmflg, &ret); | ||
| 540 | if (err) | ||
| 541 | return err; | ||
| 542 | force_successful_syscall_return(); | ||
| 543 | return (long)ret; | ||
| 544 | } | ||
| 545 | #endif | ||
| 488 | 546 | ||
| 489 | static inline int get_compat_shmid64_ds(struct shmid64_ds *s64, | 547 | static inline int get_compat_shmid64_ds(struct shmid64_ds *s64, |
| 490 | struct compat_shmid64_ds __user *up64) | 548 | struct compat_shmid64_ds __user *up64) |
