diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2017-07-09 10:27:22 -0400 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2017-07-15 20:46:45 -0400 |
| commit | 20bc2a3aff5a88a666e81182fd277ea2a521fd3d (patch) | |
| tree | 5834be6c2b551d9429c250b6c620f32dedb9ed0c /ipc | |
| parent | 28327fae62b011216026b66299882c53b95b4500 (diff) | |
ipc(2): move compat to native
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'ipc')
| -rw-r--r-- | ipc/compat.c | 98 | ||||
| -rw-r--r-- | ipc/syscall.c | 90 |
2 files changed, 93 insertions, 95 deletions
diff --git a/ipc/compat.c b/ipc/compat.c index 3c25ca1e46c7..00c2e3beccc8 100644 --- a/ipc/compat.c +++ b/ipc/compat.c | |||
| @@ -39,11 +39,6 @@ struct compat_msgbuf { | |||
| 39 | char mtext[1]; | 39 | char mtext[1]; |
| 40 | }; | 40 | }; |
| 41 | 41 | ||
| 42 | struct compat_ipc_kludge { | ||
| 43 | compat_uptr_t msgp; | ||
| 44 | compat_long_t msgtyp; | ||
| 45 | }; | ||
| 46 | |||
| 47 | int get_compat_ipc64_perm(struct ipc64_perm *to, | 42 | int get_compat_ipc64_perm(struct ipc64_perm *to, |
| 48 | struct compat_ipc64_perm __user *from) | 43 | struct compat_ipc64_perm __user *from) |
| 49 | { | 44 | { |
| @@ -104,95 +99,6 @@ static long compat_do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bu | |||
| 104 | return msgsz; | 99 | return msgsz; |
| 105 | } | 100 | } |
| 106 | 101 | ||
| 107 | #ifndef COMPAT_SHMLBA | ||
| 108 | #define COMPAT_SHMLBA SHMLBA | ||
| 109 | #endif | ||
| 110 | |||
| 111 | #ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC | ||
| 112 | COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second, | ||
| 113 | u32, third, compat_uptr_t, ptr, u32, fifth) | ||
| 114 | { | ||
| 115 | int version; | ||
| 116 | u32 pad; | ||
| 117 | |||
| 118 | version = call >> 16; /* hack for backward compatibility */ | ||
| 119 | call &= 0xffff; | ||
| 120 | |||
| 121 | switch (call) { | ||
| 122 | case SEMOP: | ||
| 123 | /* struct sembuf is the same on 32 and 64bit :)) */ | ||
| 124 | return sys_semtimedop(first, compat_ptr(ptr), second, NULL); | ||
| 125 | case SEMTIMEDOP: | ||
| 126 | return compat_sys_semtimedop(first, compat_ptr(ptr), second, | ||
| 127 | compat_ptr(fifth)); | ||
| 128 | case SEMGET: | ||
| 129 | return sys_semget(first, second, third); | ||
| 130 | case SEMCTL: | ||
| 131 | if (!ptr) | ||
| 132 | return -EINVAL; | ||
| 133 | if (get_user(pad, (u32 __user *) compat_ptr(ptr))) | ||
| 134 | return -EFAULT; | ||
| 135 | return compat_sys_semctl(first, second, third, pad); | ||
| 136 | |||
| 137 | case MSGSND: { | ||
| 138 | struct compat_msgbuf __user *up = compat_ptr(ptr); | ||
| 139 | compat_long_t type; | ||
| 140 | |||
| 141 | if (first < 0 || second < 0) | ||
| 142 | return -EINVAL; | ||
| 143 | |||
| 144 | if (get_user(type, &up->mtype)) | ||
| 145 | return -EFAULT; | ||
| 146 | |||
| 147 | return do_msgsnd(first, type, up->mtext, second, third); | ||
| 148 | } | ||
| 149 | case MSGRCV: { | ||
| 150 | void __user *uptr = compat_ptr(ptr); | ||
| 151 | |||
| 152 | if (first < 0 || second < 0) | ||
| 153 | return -EINVAL; | ||
| 154 | |||
| 155 | if (!version) { | ||
| 156 | struct compat_ipc_kludge ipck; | ||
| 157 | if (!uptr) | ||
| 158 | return -EINVAL; | ||
| 159 | if (copy_from_user(&ipck, uptr, sizeof(ipck))) | ||
| 160 | return -EFAULT; | ||
| 161 | uptr = compat_ptr(ipck.msgp); | ||
| 162 | fifth = ipck.msgtyp; | ||
| 163 | } | ||
| 164 | return do_msgrcv(first, uptr, second, (s32)fifth, third, | ||
| 165 | compat_do_msg_fill); | ||
| 166 | } | ||
| 167 | case MSGGET: | ||
| 168 | return sys_msgget(first, second); | ||
| 169 | case MSGCTL: | ||
| 170 | return compat_sys_msgctl(first, second, compat_ptr(ptr)); | ||
| 171 | |||
| 172 | case SHMAT: { | ||
| 173 | int err; | ||
| 174 | unsigned long raddr; | ||
| 175 | |||
| 176 | if (version == 1) | ||
| 177 | return -EINVAL; | ||
| 178 | err = do_shmat(first, compat_ptr(ptr), second, &raddr, | ||
| 179 | COMPAT_SHMLBA); | ||
| 180 | if (err < 0) | ||
| 181 | return err; | ||
| 182 | return put_user(raddr, (compat_ulong_t *)compat_ptr(third)); | ||
| 183 | } | ||
| 184 | case SHMDT: | ||
| 185 | return sys_shmdt(compat_ptr(ptr)); | ||
| 186 | case SHMGET: | ||
| 187 | return sys_shmget(first, (unsigned)second, third); | ||
| 188 | case SHMCTL: | ||
| 189 | return compat_sys_shmctl(first, second, compat_ptr(ptr)); | ||
| 190 | } | ||
| 191 | |||
| 192 | return -ENOSYS; | ||
| 193 | } | ||
| 194 | #endif | ||
| 195 | |||
| 196 | COMPAT_SYSCALL_DEFINE4(msgsnd, int, msqid, compat_uptr_t, msgp, | 102 | COMPAT_SYSCALL_DEFINE4(msgsnd, int, msqid, compat_uptr_t, msgp, |
| 197 | compat_ssize_t, msgsz, int, msgflg) | 103 | compat_ssize_t, msgsz, int, msgflg) |
| 198 | { | 104 | { |
| @@ -211,6 +117,10 @@ COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp, | |||
| 211 | msgflg, compat_do_msg_fill); | 117 | msgflg, compat_do_msg_fill); |
| 212 | } | 118 | } |
| 213 | 119 | ||
| 120 | #ifndef COMPAT_SHMLBA | ||
| 121 | #define COMPAT_SHMLBA SHMLBA | ||
| 122 | #endif | ||
| 123 | |||
| 214 | COMPAT_SYSCALL_DEFINE3(shmat, int, shmid, compat_uptr_t, shmaddr, int, shmflg) | 124 | COMPAT_SYSCALL_DEFINE3(shmat, int, shmid, compat_uptr_t, shmaddr, int, shmflg) |
| 215 | { | 125 | { |
| 216 | unsigned long ret; | 126 | unsigned long ret; |
diff --git a/ipc/syscall.c b/ipc/syscall.c index 52429489cde0..667022746ca5 100644 --- a/ipc/syscall.c +++ b/ipc/syscall.c | |||
| @@ -5,12 +5,12 @@ | |||
| 5 | * the individual syscalls instead. | 5 | * the individual syscalls instead. |
| 6 | */ | 6 | */ |
| 7 | #include <linux/unistd.h> | 7 | #include <linux/unistd.h> |
| 8 | #include <linux/syscalls.h> | ||
| 8 | 9 | ||
| 9 | #ifdef __ARCH_WANT_SYS_IPC | 10 | #ifdef __ARCH_WANT_SYS_IPC |
| 10 | #include <linux/errno.h> | 11 | #include <linux/errno.h> |
| 11 | #include <linux/ipc.h> | 12 | #include <linux/ipc.h> |
| 12 | #include <linux/shm.h> | 13 | #include <linux/shm.h> |
| 13 | #include <linux/syscalls.h> | ||
| 14 | #include <linux/uaccess.h> | 14 | #include <linux/uaccess.h> |
| 15 | 15 | ||
| 16 | SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, | 16 | SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, |
| @@ -97,3 +97,91 @@ SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, | |||
| 97 | } | 97 | } |
| 98 | } | 98 | } |
| 99 | #endif | 99 | #endif |
| 100 | |||
| 101 | #ifdef CONFIG_COMPAT | ||
| 102 | #include <linux/compat.h> | ||
| 103 | |||
| 104 | #ifndef COMPAT_SHMLBA | ||
| 105 | #define COMPAT_SHMLBA SHMLBA | ||
| 106 | #endif | ||
| 107 | |||
| 108 | struct compat_ipc_kludge { | ||
| 109 | compat_uptr_t msgp; | ||
| 110 | compat_long_t msgtyp; | ||
| 111 | }; | ||
| 112 | |||
| 113 | #ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC | ||
| 114 | COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second, | ||
| 115 | u32, third, compat_uptr_t, ptr, u32, fifth) | ||
| 116 | { | ||
| 117 | int version; | ||
| 118 | u32 pad; | ||
| 119 | |||
| 120 | version = call >> 16; /* hack for backward compatibility */ | ||
| 121 | call &= 0xffff; | ||
| 122 | |||
| 123 | switch (call) { | ||
| 124 | case SEMOP: | ||
| 125 | /* struct sembuf is the same on 32 and 64bit :)) */ | ||
| 126 | return sys_semtimedop(first, compat_ptr(ptr), second, NULL); | ||
| 127 | case SEMTIMEDOP: | ||
| 128 | return compat_sys_semtimedop(first, compat_ptr(ptr), second, | ||
| 129 | compat_ptr(fifth)); | ||
| 130 | case SEMGET: | ||
| 131 | return sys_semget(first, second, third); | ||
| 132 | case SEMCTL: | ||
| 133 | if (!ptr) | ||
| 134 | return -EINVAL; | ||
| 135 | if (get_user(pad, (u32 __user *) compat_ptr(ptr))) | ||
| 136 | return -EFAULT; | ||
| 137 | return compat_sys_semctl(first, second, third, pad); | ||
| 138 | |||
| 139 | case MSGSND: | ||
| 140 | return compat_sys_msgsnd(first, ptr, second, third); | ||
| 141 | |||
| 142 | case MSGRCV: { | ||
| 143 | void __user *uptr = compat_ptr(ptr); | ||
| 144 | |||
| 145 | if (first < 0 || second < 0) | ||
| 146 | return -EINVAL; | ||
| 147 | |||
| 148 | if (!version) { | ||
| 149 | struct compat_ipc_kludge ipck; | ||
| 150 | if (!uptr) | ||
| 151 | return -EINVAL; | ||
| 152 | if (copy_from_user(&ipck, uptr, sizeof(ipck))) | ||
| 153 | return -EFAULT; | ||
| 154 | return compat_sys_msgrcv(first, ipck.msgp, second, | ||
| 155 | ipck.msgtyp, third); | ||
| 156 | } | ||
| 157 | return compat_sys_msgrcv(first, ptr, second, fifth, third); | ||
| 158 | } | ||
| 159 | case MSGGET: | ||
| 160 | return sys_msgget(first, second); | ||
| 161 | case MSGCTL: | ||
| 162 | return compat_sys_msgctl(first, second, compat_ptr(ptr)); | ||
| 163 | |||
| 164 | case SHMAT: { | ||
| 165 | int err; | ||
| 166 | unsigned long raddr; | ||
| 167 | |||
| 168 | if (version == 1) | ||
| 169 | return -EINVAL; | ||
| 170 | err = do_shmat(first, compat_ptr(ptr), second, &raddr, | ||
| 171 | COMPAT_SHMLBA); | ||
| 172 | if (err < 0) | ||
| 173 | return err; | ||
| 174 | return put_user(raddr, (compat_ulong_t *)compat_ptr(third)); | ||
| 175 | } | ||
| 176 | case SHMDT: | ||
| 177 | return sys_shmdt(compat_ptr(ptr)); | ||
| 178 | case SHMGET: | ||
| 179 | return sys_shmget(first, (unsigned)second, third); | ||
| 180 | case SHMCTL: | ||
| 181 | return compat_sys_shmctl(first, second, compat_ptr(ptr)); | ||
| 182 | } | ||
| 183 | |||
| 184 | return -ENOSYS; | ||
| 185 | } | ||
| 186 | #endif | ||
| 187 | #endif | ||
