Commit 275f2214 authored by Arnd Bergmann's avatar Arnd Bergmann

ipc: rename old-style shmctl/semctl/msgctl syscalls

The behavior of these system calls is slightly different between
architectures, as determined by the CONFIG_ARCH_WANT_IPC_PARSE_VERSION
symbol. Most architectures that implement the split IPC syscalls don't set
that symbol and only get the modern version, but alpha, arm, microblaze,
mips-n32, mips-n64 and xtensa expect the caller to pass the IPC_64 flag.

For the architectures that so far only implement sys_ipc(), i.e. m68k,
mips-o32, powerpc, s390, sh, sparc, and x86-32, we want the new behavior
when adding the split syscalls, so we need to distinguish between the
two groups of architectures.

The method I picked for this distinction is to have a separate system call
entry point: sys_old_*ctl() now uses ipc_parse_version, while sys_*ctl()
does not. The system call tables of the five architectures are changed
accordingly.

As an additional benefit, we no longer need the configuration specific
definition for ipc_parse_version(), it always does the same thing now,
but simply won't get called on architectures with the modern interface.

A small downside is that on architectures that do set
ARCH_WANT_IPC_PARSE_VERSION, we now have an extra set of entry points
that are never called. They only add a few bytes of bloat, so it seems
better to keep them compared to adding yet another Kconfig symbol.
I considered adding new syscall numbers for the IPC_64 variants for
consistency, but decided against that for now.
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parent 73a66023
...@@ -174,17 +174,17 @@ ...@@ -174,17 +174,17 @@
187 common osf_alt_sigpending sys_ni_syscall 187 common osf_alt_sigpending sys_ni_syscall
188 common osf_alt_setsid sys_ni_syscall 188 common osf_alt_setsid sys_ni_syscall
199 common osf_swapon sys_swapon 199 common osf_swapon sys_swapon
200 common msgctl sys_msgctl 200 common msgctl sys_old_msgctl
201 common msgget sys_msgget 201 common msgget sys_msgget
202 common msgrcv sys_msgrcv 202 common msgrcv sys_msgrcv
203 common msgsnd sys_msgsnd 203 common msgsnd sys_msgsnd
204 common semctl sys_semctl 204 common semctl sys_old_semctl
205 common semget sys_semget 205 common semget sys_semget
206 common semop sys_semop 206 common semop sys_semop
207 common osf_utsname sys_osf_utsname 207 common osf_utsname sys_osf_utsname
208 common lchown sys_lchown 208 common lchown sys_lchown
209 common shmat sys_shmat 209 common shmat sys_shmat
210 common shmctl sys_shmctl 210 common shmctl sys_old_shmctl
211 common shmdt sys_shmdt 211 common shmdt sys_shmdt
212 common shmget sys_shmget 212 common shmget sys_shmget
213 common osf_mvalid sys_ni_syscall 213 common osf_mvalid sys_ni_syscall
......
...@@ -314,15 +314,15 @@ ...@@ -314,15 +314,15 @@
297 common recvmsg sys_recvmsg 297 common recvmsg sys_recvmsg
298 common semop sys_semop sys_oabi_semop 298 common semop sys_semop sys_oabi_semop
299 common semget sys_semget 299 common semget sys_semget
300 common semctl sys_semctl 300 common semctl sys_old_semctl
301 common msgsnd sys_msgsnd 301 common msgsnd sys_msgsnd
302 common msgrcv sys_msgrcv 302 common msgrcv sys_msgrcv
303 common msgget sys_msgget 303 common msgget sys_msgget
304 common msgctl sys_msgctl 304 common msgctl sys_old_msgctl
305 common shmat sys_shmat 305 common shmat sys_shmat
306 common shmdt sys_shmdt 306 common shmdt sys_shmdt
307 common shmget sys_shmget 307 common shmget sys_shmget
308 common shmctl sys_shmctl 308 common shmctl sys_old_shmctl
309 common add_key sys_add_key 309 common add_key sys_add_key
310 common request_key sys_request_key 310 common request_key sys_request_key
311 common keyctl sys_keyctl 311 common keyctl sys_keyctl
......
...@@ -622,7 +622,7 @@ __SYSCALL(__NR_semop, sys_semop) ...@@ -622,7 +622,7 @@ __SYSCALL(__NR_semop, sys_semop)
#define __NR_semget 299 #define __NR_semget 299
__SYSCALL(__NR_semget, sys_semget) __SYSCALL(__NR_semget, sys_semget)
#define __NR_semctl 300 #define __NR_semctl 300
__SYSCALL(__NR_semctl, compat_sys_semctl) __SYSCALL(__NR_semctl, compat_sys_old_semctl)
#define __NR_msgsnd 301 #define __NR_msgsnd 301
__SYSCALL(__NR_msgsnd, compat_sys_msgsnd) __SYSCALL(__NR_msgsnd, compat_sys_msgsnd)
#define __NR_msgrcv 302 #define __NR_msgrcv 302
...@@ -630,7 +630,7 @@ __SYSCALL(__NR_msgrcv, compat_sys_msgrcv) ...@@ -630,7 +630,7 @@ __SYSCALL(__NR_msgrcv, compat_sys_msgrcv)
#define __NR_msgget 303 #define __NR_msgget 303
__SYSCALL(__NR_msgget, sys_msgget) __SYSCALL(__NR_msgget, sys_msgget)
#define __NR_msgctl 304 #define __NR_msgctl 304
__SYSCALL(__NR_msgctl, compat_sys_msgctl) __SYSCALL(__NR_msgctl, compat_sys_old_msgctl)
#define __NR_shmat 305 #define __NR_shmat 305
__SYSCALL(__NR_shmat, compat_sys_shmat) __SYSCALL(__NR_shmat, compat_sys_shmat)
#define __NR_shmdt 306 #define __NR_shmdt 306
...@@ -638,7 +638,7 @@ __SYSCALL(__NR_shmdt, sys_shmdt) ...@@ -638,7 +638,7 @@ __SYSCALL(__NR_shmdt, sys_shmdt)
#define __NR_shmget 307 #define __NR_shmget 307
__SYSCALL(__NR_shmget, sys_shmget) __SYSCALL(__NR_shmget, sys_shmget)
#define __NR_shmctl 308 #define __NR_shmctl 308
__SYSCALL(__NR_shmctl, compat_sys_shmctl) __SYSCALL(__NR_shmctl, compat_sys_old_shmctl)
#define __NR_add_key 309 #define __NR_add_key 309
__SYSCALL(__NR_add_key, sys_add_key) __SYSCALL(__NR_add_key, sys_add_key)
#define __NR_request_key 310 #define __NR_request_key 310
......
...@@ -335,15 +335,15 @@ ...@@ -335,15 +335,15 @@
325 common semtimedop sys_semtimedop 325 common semtimedop sys_semtimedop
326 common timerfd_settime sys_timerfd_settime 326 common timerfd_settime sys_timerfd_settime
327 common timerfd_gettime sys_timerfd_gettime 327 common timerfd_gettime sys_timerfd_gettime
328 common semctl sys_semctl 328 common semctl sys_old_semctl
329 common semget sys_semget 329 common semget sys_semget
330 common semop sys_semop 330 common semop sys_semop
331 common msgctl sys_msgctl 331 common msgctl sys_old_msgctl
332 common msgget sys_msgget 332 common msgget sys_msgget
333 common msgrcv sys_msgrcv 333 common msgrcv sys_msgrcv
334 common msgsnd sys_msgsnd 334 common msgsnd sys_msgsnd
335 common shmat sys_shmat 335 common shmat sys_shmat
336 common shmctl sys_shmctl 336 common shmctl sys_old_shmctl
337 common shmdt sys_shmdt 337 common shmdt sys_shmdt
338 common shmget sys_shmget 338 common shmget sys_shmget
339 common signalfd4 sys_signalfd4 339 common signalfd4 sys_signalfd4
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
27 n32 madvise sys_madvise 27 n32 madvise sys_madvise
28 n32 shmget sys_shmget 28 n32 shmget sys_shmget
29 n32 shmat sys_shmat 29 n32 shmat sys_shmat
30 n32 shmctl compat_sys_shmctl 30 n32 shmctl compat_sys_old_shmctl
31 n32 dup sys_dup 31 n32 dup sys_dup
32 n32 dup2 sys_dup2 32 n32 dup2 sys_dup2
33 n32 pause sys_pause 33 n32 pause sys_pause
...@@ -71,12 +71,12 @@ ...@@ -71,12 +71,12 @@
61 n32 uname sys_newuname 61 n32 uname sys_newuname
62 n32 semget sys_semget 62 n32 semget sys_semget
63 n32 semop sys_semop 63 n32 semop sys_semop
64 n32 semctl compat_sys_semctl 64 n32 semctl compat_sys_old_semctl
65 n32 shmdt sys_shmdt 65 n32 shmdt sys_shmdt
66 n32 msgget sys_msgget 66 n32 msgget sys_msgget
67 n32 msgsnd compat_sys_msgsnd 67 n32 msgsnd compat_sys_msgsnd
68 n32 msgrcv compat_sys_msgrcv 68 n32 msgrcv compat_sys_msgrcv
69 n32 msgctl compat_sys_msgctl 69 n32 msgctl compat_sys_old_msgctl
70 n32 fcntl compat_sys_fcntl 70 n32 fcntl compat_sys_fcntl
71 n32 flock sys_flock 71 n32 flock sys_flock
72 n32 fsync sys_fsync 72 n32 fsync sys_fsync
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
27 n64 madvise sys_madvise 27 n64 madvise sys_madvise
28 n64 shmget sys_shmget 28 n64 shmget sys_shmget
29 n64 shmat sys_shmat 29 n64 shmat sys_shmat
30 n64 shmctl sys_shmctl 30 n64 shmctl sys_old_shmctl
31 n64 dup sys_dup 31 n64 dup sys_dup
32 n64 dup2 sys_dup2 32 n64 dup2 sys_dup2
33 n64 pause sys_pause 33 n64 pause sys_pause
...@@ -71,12 +71,12 @@ ...@@ -71,12 +71,12 @@
61 n64 uname sys_newuname 61 n64 uname sys_newuname
62 n64 semget sys_semget 62 n64 semget sys_semget
63 n64 semop sys_semop 63 n64 semop sys_semop
64 n64 semctl sys_semctl 64 n64 semctl sys_old_semctl
65 n64 shmdt sys_shmdt 65 n64 shmdt sys_shmdt
66 n64 msgget sys_msgget 66 n64 msgget sys_msgget
67 n64 msgsnd sys_msgsnd 67 n64 msgsnd sys_msgsnd
68 n64 msgrcv sys_msgrcv 68 n64 msgrcv sys_msgrcv
69 n64 msgctl sys_msgctl 69 n64 msgctl sys_old_msgctl
70 n64 fcntl sys_fcntl 70 n64 fcntl sys_fcntl
71 n64 flock sys_flock 71 n64 flock sys_flock
72 n64 fsync sys_fsync 72 n64 fsync sys_fsync
......
...@@ -103,7 +103,7 @@ ...@@ -103,7 +103,7 @@
91 common madvise sys_madvise 91 common madvise sys_madvise
92 common shmget sys_shmget 92 common shmget sys_shmget
93 common shmat xtensa_shmat 93 common shmat xtensa_shmat
94 common shmctl sys_shmctl 94 common shmctl sys_old_shmctl
95 common shmdt sys_shmdt 95 common shmdt sys_shmdt
# Socket Operations # Socket Operations
96 common socket sys_socket 96 common socket sys_socket
...@@ -177,12 +177,12 @@ ...@@ -177,12 +177,12 @@
161 common semtimedop sys_semtimedop 161 common semtimedop sys_semtimedop
162 common semget sys_semget 162 common semget sys_semget
163 common semop sys_semop 163 common semop sys_semop
164 common semctl sys_semctl 164 common semctl sys_old_semctl
165 common available165 sys_ni_syscall 165 common available165 sys_ni_syscall
166 common msgget sys_msgget 166 common msgget sys_msgget
167 common msgsnd sys_msgsnd 167 common msgsnd sys_msgsnd
168 common msgrcv sys_msgrcv 168 common msgrcv sys_msgrcv
169 common msgctl sys_msgctl 169 common msgctl sys_old_msgctl
170 common available170 sys_ni_syscall 170 common available170 sys_ni_syscall
# File System # File System
171 common umount2 sys_umount 171 common umount2 sys_umount
......
...@@ -717,6 +717,7 @@ asmlinkage long sys_mq_getsetattr(mqd_t mqdes, const struct mq_attr __user *mqst ...@@ -717,6 +717,7 @@ asmlinkage long sys_mq_getsetattr(mqd_t mqdes, const struct mq_attr __user *mqst
/* ipc/msg.c */ /* ipc/msg.c */
asmlinkage long sys_msgget(key_t key, int msgflg); asmlinkage long sys_msgget(key_t key, int msgflg);
asmlinkage long sys_old_msgctl(int msqid, int cmd, struct msqid_ds __user *buf);
asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf); asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf);
asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp, asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp,
size_t msgsz, long msgtyp, int msgflg); size_t msgsz, long msgtyp, int msgflg);
...@@ -726,6 +727,7 @@ asmlinkage long sys_msgsnd(int msqid, struct msgbuf __user *msgp, ...@@ -726,6 +727,7 @@ asmlinkage long sys_msgsnd(int msqid, struct msgbuf __user *msgp,
/* ipc/sem.c */ /* ipc/sem.c */
asmlinkage long sys_semget(key_t key, int nsems, int semflg); asmlinkage long sys_semget(key_t key, int nsems, int semflg);
asmlinkage long sys_semctl(int semid, int semnum, int cmd, unsigned long arg); asmlinkage long sys_semctl(int semid, int semnum, int cmd, unsigned long arg);
asmlinkage long sys_old_semctl(int semid, int semnum, int cmd, unsigned long arg);
asmlinkage long sys_semtimedop(int semid, struct sembuf __user *sops, asmlinkage long sys_semtimedop(int semid, struct sembuf __user *sops,
unsigned nsops, unsigned nsops,
const struct __kernel_timespec __user *timeout); const struct __kernel_timespec __user *timeout);
...@@ -734,6 +736,7 @@ asmlinkage long sys_semop(int semid, struct sembuf __user *sops, ...@@ -734,6 +736,7 @@ asmlinkage long sys_semop(int semid, struct sembuf __user *sops,
/* ipc/shm.c */ /* ipc/shm.c */
asmlinkage long sys_shmget(key_t key, size_t size, int flag); asmlinkage long sys_shmget(key_t key, size_t size, int flag);
asmlinkage long sys_old_shmctl(int shmid, int cmd, struct shmid_ds __user *buf);
asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf); asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf);
asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg); asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg);
asmlinkage long sys_shmdt(char __user *shmaddr); asmlinkage long sys_shmdt(char __user *shmaddr);
......
...@@ -567,9 +567,8 @@ static int msgctl_stat(struct ipc_namespace *ns, int msqid, ...@@ -567,9 +567,8 @@ static int msgctl_stat(struct ipc_namespace *ns, int msqid,
return err; return err;
} }
long ksys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf) static long ksys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf, int version)
{ {
int version;
struct ipc_namespace *ns; struct ipc_namespace *ns;
struct msqid64_ds msqid64; struct msqid64_ds msqid64;
int err; int err;
...@@ -577,7 +576,6 @@ long ksys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf) ...@@ -577,7 +576,6 @@ long ksys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
if (msqid < 0 || cmd < 0) if (msqid < 0 || cmd < 0)
return -EINVAL; return -EINVAL;
version = ipc_parse_version(&cmd);
ns = current->nsproxy->ipc_ns; ns = current->nsproxy->ipc_ns;
switch (cmd) { switch (cmd) {
...@@ -613,9 +611,23 @@ long ksys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf) ...@@ -613,9 +611,23 @@ long ksys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf) SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
{ {
return ksys_msgctl(msqid, cmd, buf); return ksys_msgctl(msqid, cmd, buf, IPC_64);
} }
#ifdef CONFIG_ARCH_WANT_IPC_PARSE_VERSION
long ksys_old_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
{
int version = ipc_parse_version(&cmd);
return ksys_msgctl(msqid, cmd, buf, version);
}
SYSCALL_DEFINE3(old_msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
{
return ksys_old_msgctl(msqid, cmd, buf);
}
#endif
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
struct compat_msqid_ds { struct compat_msqid_ds {
...@@ -689,12 +701,11 @@ static int copy_compat_msqid_to_user(void __user *buf, struct msqid64_ds *in, ...@@ -689,12 +701,11 @@ static int copy_compat_msqid_to_user(void __user *buf, struct msqid64_ds *in,
} }
} }
long compat_ksys_msgctl(int msqid, int cmd, void __user *uptr) static long compat_ksys_msgctl(int msqid, int cmd, void __user *uptr, int version)
{ {
struct ipc_namespace *ns; struct ipc_namespace *ns;
int err; int err;
struct msqid64_ds msqid64; struct msqid64_ds msqid64;
int version = compat_ipc_parse_version(&cmd);
ns = current->nsproxy->ipc_ns; ns = current->nsproxy->ipc_ns;
...@@ -734,8 +745,22 @@ long compat_ksys_msgctl(int msqid, int cmd, void __user *uptr) ...@@ -734,8 +745,22 @@ long compat_ksys_msgctl(int msqid, int cmd, void __user *uptr)
COMPAT_SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, void __user *, uptr) COMPAT_SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, void __user *, uptr)
{ {
return compat_ksys_msgctl(msqid, cmd, uptr); return compat_ksys_msgctl(msqid, cmd, uptr, IPC_64);
} }
#ifdef CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION
long compat_ksys_old_msgctl(int msqid, int cmd, void __user *uptr)
{
int version = compat_ipc_parse_version(&cmd);
return compat_ksys_msgctl(msqid, cmd, uptr, version);
}
COMPAT_SYSCALL_DEFINE3(old_msgctl, int, msqid, int, cmd, void __user *, uptr)
{
return compat_ksys_old_msgctl(msqid, cmd, uptr);
}
#endif
#endif #endif
static int testmsg(struct msg_msg *msg, long type, int mode) static int testmsg(struct msg_msg *msg, long type, int mode)
......
...@@ -1634,9 +1634,8 @@ static int semctl_down(struct ipc_namespace *ns, int semid, ...@@ -1634,9 +1634,8 @@ static int semctl_down(struct ipc_namespace *ns, int semid,
return err; return err;
} }
long ksys_semctl(int semid, int semnum, int cmd, unsigned long arg) static long ksys_semctl(int semid, int semnum, int cmd, unsigned long arg, int version)
{ {
int version;
struct ipc_namespace *ns; struct ipc_namespace *ns;
void __user *p = (void __user *)arg; void __user *p = (void __user *)arg;
struct semid64_ds semid64; struct semid64_ds semid64;
...@@ -1645,7 +1644,6 @@ long ksys_semctl(int semid, int semnum, int cmd, unsigned long arg) ...@@ -1645,7 +1644,6 @@ long ksys_semctl(int semid, int semnum, int cmd, unsigned long arg)
if (semid < 0) if (semid < 0)
return -EINVAL; return -EINVAL;
version = ipc_parse_version(&cmd);
ns = current->nsproxy->ipc_ns; ns = current->nsproxy->ipc_ns;
switch (cmd) { switch (cmd) {
...@@ -1691,9 +1689,23 @@ long ksys_semctl(int semid, int semnum, int cmd, unsigned long arg) ...@@ -1691,9 +1689,23 @@ long ksys_semctl(int semid, int semnum, int cmd, unsigned long arg)
SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, unsigned long, arg) SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, unsigned long, arg)
{ {
return ksys_semctl(semid, semnum, cmd, arg); return ksys_semctl(semid, semnum, cmd, arg, IPC_64);
} }
#ifdef CONFIG_ARCH_WANT_IPC_PARSE_VERSION
long ksys_old_semctl(int semid, int semnum, int cmd, unsigned long arg)
{
int version = ipc_parse_version(&cmd);
return ksys_semctl(semid, semnum, cmd, arg, version);
}
SYSCALL_DEFINE4(old_semctl, int, semid, int, semnum, int, cmd, unsigned long, arg)
{
return ksys_old_semctl(semid, semnum, cmd, arg);
}
#endif
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
struct compat_semid_ds { struct compat_semid_ds {
...@@ -1744,12 +1756,11 @@ static int copy_compat_semid_to_user(void __user *buf, struct semid64_ds *in, ...@@ -1744,12 +1756,11 @@ static int copy_compat_semid_to_user(void __user *buf, struct semid64_ds *in,
} }
} }
long compat_ksys_semctl(int semid, int semnum, int cmd, int arg) static long compat_ksys_semctl(int semid, int semnum, int cmd, int arg, int version)
{ {
void __user *p = compat_ptr(arg); void __user *p = compat_ptr(arg);
struct ipc_namespace *ns; struct ipc_namespace *ns;
struct semid64_ds semid64; struct semid64_ds semid64;
int version = compat_ipc_parse_version(&cmd);
int err; int err;
ns = current->nsproxy->ipc_ns; ns = current->nsproxy->ipc_ns;
...@@ -1792,8 +1803,22 @@ long compat_ksys_semctl(int semid, int semnum, int cmd, int arg) ...@@ -1792,8 +1803,22 @@ long compat_ksys_semctl(int semid, int semnum, int cmd, int arg)
COMPAT_SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, int, arg) COMPAT_SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, int, arg)
{ {
return compat_ksys_semctl(semid, semnum, cmd, arg); return compat_ksys_semctl(semid, semnum, cmd, arg, IPC_64);
} }
#ifdef CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION
long compat_ksys_old_semctl(int semid, int semnum, int cmd, int arg)
{
int version = compat_ipc_parse_version(&cmd);
return compat_ksys_semctl(semid, semnum, cmd, arg, version);
}
COMPAT_SYSCALL_DEFINE4(old_semctl, int, semid, int, semnum, int, cmd, int, arg)
{
return compat_ksys_old_semctl(semid, semnum, cmd, arg);
}
#endif
#endif #endif
/* If the task doesn't already have a undo_list, then allocate one /* If the task doesn't already have a undo_list, then allocate one
......
...@@ -1137,16 +1137,15 @@ static int shmctl_do_lock(struct ipc_namespace *ns, int shmid, int cmd) ...@@ -1137,16 +1137,15 @@ static int shmctl_do_lock(struct ipc_namespace *ns, int shmid, int cmd)
return err; return err;
} }
long ksys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf) static long ksys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf, int version)
{ {
int err, version; int err;
struct ipc_namespace *ns; struct ipc_namespace *ns;
struct shmid64_ds sem64; struct shmid64_ds sem64;
if (cmd < 0 || shmid < 0) if (cmd < 0 || shmid < 0)
return -EINVAL; return -EINVAL;
version = ipc_parse_version(&cmd);
ns = current->nsproxy->ipc_ns; ns = current->nsproxy->ipc_ns;
switch (cmd) { switch (cmd) {
...@@ -1194,8 +1193,22 @@ long ksys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf) ...@@ -1194,8 +1193,22 @@ long ksys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf)
SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
{ {
return ksys_shmctl(shmid, cmd, buf); return ksys_shmctl(shmid, cmd, buf, IPC_64);
}
#ifdef CONFIG_ARCH_WANT_IPC_PARSE_VERSION
long ksys_old_shmctl(int shmid, int cmd, struct shmid_ds __user *buf)
{
int version = ipc_parse_version(&cmd);
return ksys_shmctl(shmid, cmd, buf, version);
}
SYSCALL_DEFINE3(old_shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
{
return ksys_old_shmctl(shmid, cmd, buf);
} }
#endif
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
...@@ -1319,11 +1332,10 @@ static int copy_compat_shmid_from_user(struct shmid64_ds *out, void __user *buf, ...@@ -1319,11 +1332,10 @@ static int copy_compat_shmid_from_user(struct shmid64_ds *out, void __user *buf,
} }
} }
long compat_ksys_shmctl(int shmid, int cmd, void __user *uptr) long compat_ksys_shmctl(int shmid, int cmd, void __user *uptr, int version)
{ {
struct ipc_namespace *ns; struct ipc_namespace *ns;
struct shmid64_ds sem64; struct shmid64_ds sem64;
int version = compat_ipc_parse_version(&cmd);
int err; int err;
ns = current->nsproxy->ipc_ns; ns = current->nsproxy->ipc_ns;
...@@ -1378,8 +1390,22 @@ long compat_ksys_shmctl(int shmid, int cmd, void __user *uptr) ...@@ -1378,8 +1390,22 @@ long compat_ksys_shmctl(int shmid, int cmd, void __user *uptr)
COMPAT_SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, void __user *, uptr) COMPAT_SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, void __user *, uptr)
{ {
return compat_ksys_shmctl(shmid, cmd, uptr); return compat_ksys_shmctl(shmid, cmd, uptr, IPC_64);
} }
#ifdef CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION
long compat_ksys_old_shmctl(int shmid, int cmd, void __user *uptr)
{
int version = compat_ipc_parse_version(&cmd);
return compat_ksys_shmctl(shmid, cmd, uptr, version);
}
COMPAT_SYSCALL_DEFINE3(old_shmctl, int, shmid, int, cmd, void __user *, uptr)
{
return compat_ksys_old_shmctl(shmid, cmd, uptr);
}
#endif
#endif #endif
/* /*
......
...@@ -47,7 +47,7 @@ int ksys_ipc(unsigned int call, int first, unsigned long second, ...@@ -47,7 +47,7 @@ int ksys_ipc(unsigned int call, int first, unsigned long second,
return -EINVAL; return -EINVAL;
if (get_user(arg, (unsigned long __user *) ptr)) if (get_user(arg, (unsigned long __user *) ptr))
return -EFAULT; return -EFAULT;
return ksys_semctl(first, second, third, arg); return ksys_old_semctl(first, second, third, arg);
} }
case MSGSND: case MSGSND:
...@@ -75,7 +75,7 @@ int ksys_ipc(unsigned int call, int first, unsigned long second, ...@@ -75,7 +75,7 @@ int ksys_ipc(unsigned int call, int first, unsigned long second,
case MSGGET: case MSGGET:
return ksys_msgget((key_t) first, second); return ksys_msgget((key_t) first, second);
case MSGCTL: case MSGCTL:
return ksys_msgctl(first, second, return ksys_old_msgctl(first, second,
(struct msqid_ds __user *)ptr); (struct msqid_ds __user *)ptr);
case SHMAT: case SHMAT:
...@@ -100,7 +100,7 @@ int ksys_ipc(unsigned int call, int first, unsigned long second, ...@@ -100,7 +100,7 @@ int ksys_ipc(unsigned int call, int first, unsigned long second,
case SHMGET: case SHMGET:
return ksys_shmget(first, second, third); return ksys_shmget(first, second, third);
case SHMCTL: case SHMCTL:
return ksys_shmctl(first, second, return ksys_old_shmctl(first, second,
(struct shmid_ds __user *) ptr); (struct shmid_ds __user *) ptr);
default: default:
return -ENOSYS; return -ENOSYS;
...@@ -152,7 +152,7 @@ int compat_ksys_ipc(u32 call, int first, int second, ...@@ -152,7 +152,7 @@ int compat_ksys_ipc(u32 call, int first, int second,
return -EINVAL; return -EINVAL;
if (get_user(pad, (u32 __user *) compat_ptr(ptr))) if (get_user(pad, (u32 __user *) compat_ptr(ptr)))
return -EFAULT; return -EFAULT;
return compat_ksys_semctl(first, second, third, pad); return compat_ksys_old_semctl(first, second, third, pad);
case MSGSND: case MSGSND:
return compat_ksys_msgsnd(first, ptr, second, third); return compat_ksys_msgsnd(first, ptr, second, third);
...@@ -177,7 +177,7 @@ int compat_ksys_ipc(u32 call, int first, int second, ...@@ -177,7 +177,7 @@ int compat_ksys_ipc(u32 call, int first, int second,
case MSGGET: case MSGGET:
return ksys_msgget(first, second); return ksys_msgget(first, second);
case MSGCTL: case MSGCTL:
return compat_ksys_msgctl(first, second, compat_ptr(ptr)); return compat_ksys_old_msgctl(first, second, compat_ptr(ptr));
case SHMAT: { case SHMAT: {
int err; int err;
...@@ -196,7 +196,7 @@ int compat_ksys_ipc(u32 call, int first, int second, ...@@ -196,7 +196,7 @@ int compat_ksys_ipc(u32 call, int first, int second,
case SHMGET: case SHMGET:
return ksys_shmget(first, (unsigned int)second, third); return ksys_shmget(first, (unsigned int)second, third);
case SHMCTL: case SHMCTL:
return compat_ksys_shmctl(first, second, compat_ptr(ptr)); return compat_ksys_old_shmctl(first, second, compat_ptr(ptr));
} }
return -ENOSYS; return -ENOSYS;
......
...@@ -160,10 +160,7 @@ static inline void ipc_update_pid(struct pid **pos, struct pid *pid) ...@@ -160,10 +160,7 @@ static inline void ipc_update_pid(struct pid **pos, struct pid *pid)
} }
} }
#ifndef CONFIG_ARCH_WANT_IPC_PARSE_VERSION #ifdef CONFIG_ARCH_WANT_IPC_PARSE_VERSION
/* On IA-64, we always use the "64-bit version" of the IPC structures. */
# define ipc_parse_version(cmd) IPC_64
#else
int ipc_parse_version(int *cmd); int ipc_parse_version(int *cmd);
#endif #endif
...@@ -246,13 +243,9 @@ int get_compat_ipc64_perm(struct ipc64_perm *, ...@@ -246,13 +243,9 @@ int get_compat_ipc64_perm(struct ipc64_perm *,
static inline int compat_ipc_parse_version(int *cmd) static inline int compat_ipc_parse_version(int *cmd)
{ {
#ifdef CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION
int version = *cmd & IPC_64; int version = *cmd & IPC_64;
*cmd &= ~IPC_64; *cmd &= ~IPC_64;
return version; return version;
#else
return IPC_64;
#endif
} }
#endif #endif
...@@ -261,29 +254,29 @@ long ksys_semtimedop(int semid, struct sembuf __user *tsops, ...@@ -261,29 +254,29 @@ long ksys_semtimedop(int semid, struct sembuf __user *tsops,
unsigned int nsops, unsigned int nsops,
const struct __kernel_timespec __user *timeout); const struct __kernel_timespec __user *timeout);
long ksys_semget(key_t key, int nsems, int semflg); long ksys_semget(key_t key, int nsems, int semflg);
long ksys_semctl(int semid, int semnum, int cmd, unsigned long arg); long ksys_old_semctl(int semid, int semnum, int cmd, unsigned long arg);
long ksys_msgget(key_t key, int msgflg); long ksys_msgget(key_t key, int msgflg);
long ksys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf); long ksys_old_msgctl(int msqid, int cmd, struct msqid_ds __user *buf);
long ksys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz, long ksys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz,
long msgtyp, int msgflg); long msgtyp, int msgflg);
long ksys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz, long ksys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz,
int msgflg); int msgflg);
long ksys_shmget(key_t key, size_t size, int shmflg); long ksys_shmget(key_t key, size_t size, int shmflg);
long ksys_shmdt(char __user *shmaddr); long ksys_shmdt(char __user *shmaddr);
long ksys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf); long ksys_old_shmctl(int shmid, int cmd, struct shmid_ds __user *buf);
/* for CONFIG_ARCH_WANT_OLD_COMPAT_IPC */ /* for CONFIG_ARCH_WANT_OLD_COMPAT_IPC */
long compat_ksys_semtimedop(int semid, struct sembuf __user *tsems, long compat_ksys_semtimedop(int semid, struct sembuf __user *tsems,
unsigned int nsops, unsigned int nsops,
const struct old_timespec32 __user *timeout); const struct old_timespec32 __user *timeout);
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
long compat_ksys_semctl(int semid, int semnum, int cmd, int arg); long compat_ksys_old_semctl(int semid, int semnum, int cmd, int arg);
long compat_ksys_msgctl(int msqid, int cmd, void __user *uptr); long compat_ksys_old_msgctl(int msqid, int cmd, void __user *uptr);
long compat_ksys_msgrcv(int msqid, compat_uptr_t msgp, compat_ssize_t msgsz, long compat_ksys_msgrcv(int msqid, compat_uptr_t msgp, compat_ssize_t msgsz,
compat_long_t msgtyp, int msgflg); compat_long_t msgtyp, int msgflg);
long compat_ksys_msgsnd(int msqid, compat_uptr_t msgp, long compat_ksys_msgsnd(int msqid, compat_uptr_t msgp,
compat_ssize_t msgsz, int msgflg); compat_ssize_t msgsz, int msgflg);
long compat_ksys_shmctl(int shmid, int cmd, void __user *uptr); long compat_ksys_old_shmctl(int shmid, int cmd, void __user *uptr);
#endif /* CONFIG_COMPAT */ #endif /* CONFIG_COMPAT */
#endif #endif
...@@ -197,6 +197,7 @@ COND_SYSCALL_COMPAT(mq_getsetattr); ...@@ -197,6 +197,7 @@ COND_SYSCALL_COMPAT(mq_getsetattr);
/* ipc/msg.c */ /* ipc/msg.c */
COND_SYSCALL(msgget); COND_SYSCALL(msgget);
COND_SYSCALL(old_msgctl);
COND_SYSCALL(msgctl); COND_SYSCALL(msgctl);
COND_SYSCALL_COMPAT(msgctl); COND_SYSCALL_COMPAT(msgctl);
COND_SYSCALL(msgrcv); COND_SYSCALL(msgrcv);
...@@ -206,6 +207,7 @@ COND_SYSCALL_COMPAT(msgsnd); ...@@ -206,6 +207,7 @@ COND_SYSCALL_COMPAT(msgsnd);
/* ipc/sem.c */ /* ipc/sem.c */
COND_SYSCALL(semget); COND_SYSCALL(semget);
COND_SYSCALL(old_semctl);
COND_SYSCALL(semctl); COND_SYSCALL(semctl);
COND_SYSCALL_COMPAT(semctl); COND_SYSCALL_COMPAT(semctl);
COND_SYSCALL(semtimedop); COND_SYSCALL(semtimedop);
...@@ -214,6 +216,7 @@ COND_SYSCALL(semop); ...@@ -214,6 +216,7 @@ COND_SYSCALL(semop);
/* ipc/shm.c */ /* ipc/shm.c */
COND_SYSCALL(shmget); COND_SYSCALL(shmget);
COND_SYSCALL(old_shmctl);
COND_SYSCALL(shmctl); COND_SYSCALL(shmctl);
COND_SYSCALL_COMPAT(shmctl); COND_SYSCALL_COMPAT(shmctl);
COND_SYSCALL(shmat); COND_SYSCALL(shmat);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment