Skip to content

Commit

Permalink
ipc: rename old-style shmctl/semctl/msgctl syscalls
Browse files Browse the repository at this point in the history
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: Arnd Bergmann <arnd@arndb.de>
  • Loading branch information
arndb committed Jan 25, 2019
1 parent 73a6602 commit 275f221
Show file tree
Hide file tree
Showing 14 changed files with 137 additions and 62 deletions.
6 changes: 3 additions & 3 deletions arch/alpha/kernel/syscalls/syscall.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -174,17 +174,17 @@
187 common osf_alt_sigpending sys_ni_syscall
188 common osf_alt_setsid sys_ni_syscall
199 common osf_swapon sys_swapon
200 common msgctl sys_msgctl
200 common msgctl sys_old_msgctl
201 common msgget sys_msgget
202 common msgrcv sys_msgrcv
203 common msgsnd sys_msgsnd
204 common semctl sys_semctl
204 common semctl sys_old_semctl
205 common semget sys_semget
206 common semop sys_semop
207 common osf_utsname sys_osf_utsname
208 common lchown sys_lchown
209 common shmat sys_shmat
210 common shmctl sys_shmctl
210 common shmctl sys_old_shmctl
211 common shmdt sys_shmdt
212 common shmget sys_shmget
213 common osf_mvalid sys_ni_syscall
Expand Down
6 changes: 3 additions & 3 deletions arch/arm/tools/syscall.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -314,15 +314,15 @@
297 common recvmsg sys_recvmsg
298 common semop sys_semop sys_oabi_semop
299 common semget sys_semget
300 common semctl sys_semctl
300 common semctl sys_old_semctl
301 common msgsnd sys_msgsnd
302 common msgrcv sys_msgrcv
303 common msgget sys_msgget
304 common msgctl sys_msgctl
304 common msgctl sys_old_msgctl
305 common shmat sys_shmat
306 common shmdt sys_shmdt
307 common shmget sys_shmget
308 common shmctl sys_shmctl
308 common shmctl sys_old_shmctl
309 common add_key sys_add_key
310 common request_key sys_request_key
311 common keyctl sys_keyctl
Expand Down
6 changes: 3 additions & 3 deletions arch/arm64/include/asm/unistd32.h
Original file line number Diff line number Diff line change
Expand Up @@ -622,23 +622,23 @@ __SYSCALL(__NR_semop, sys_semop)
#define __NR_semget 299
__SYSCALL(__NR_semget, sys_semget)
#define __NR_semctl 300
__SYSCALL(__NR_semctl, compat_sys_semctl)
__SYSCALL(__NR_semctl, compat_sys_old_semctl)
#define __NR_msgsnd 301
__SYSCALL(__NR_msgsnd, compat_sys_msgsnd)
#define __NR_msgrcv 302
__SYSCALL(__NR_msgrcv, compat_sys_msgrcv)
#define __NR_msgget 303
__SYSCALL(__NR_msgget, sys_msgget)
#define __NR_msgctl 304
__SYSCALL(__NR_msgctl, compat_sys_msgctl)
__SYSCALL(__NR_msgctl, compat_sys_old_msgctl)
#define __NR_shmat 305
__SYSCALL(__NR_shmat, compat_sys_shmat)
#define __NR_shmdt 306
__SYSCALL(__NR_shmdt, sys_shmdt)
#define __NR_shmget 307
__SYSCALL(__NR_shmget, sys_shmget)
#define __NR_shmctl 308
__SYSCALL(__NR_shmctl, compat_sys_shmctl)
__SYSCALL(__NR_shmctl, compat_sys_old_shmctl)
#define __NR_add_key 309
__SYSCALL(__NR_add_key, sys_add_key)
#define __NR_request_key 310
Expand Down
6 changes: 3 additions & 3 deletions arch/microblaze/kernel/syscalls/syscall.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -335,15 +335,15 @@
325 common semtimedop sys_semtimedop
326 common timerfd_settime sys_timerfd_settime
327 common timerfd_gettime sys_timerfd_gettime
328 common semctl sys_semctl
328 common semctl sys_old_semctl
329 common semget sys_semget
330 common semop sys_semop
331 common msgctl sys_msgctl
331 common msgctl sys_old_msgctl
332 common msgget sys_msgget
333 common msgrcv sys_msgrcv
334 common msgsnd sys_msgsnd
335 common shmat sys_shmat
336 common shmctl sys_shmctl
336 common shmctl sys_old_shmctl
337 common shmdt sys_shmdt
338 common shmget sys_shmget
339 common signalfd4 sys_signalfd4
Expand Down
6 changes: 3 additions & 3 deletions arch/mips/kernel/syscalls/syscall_n32.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
27 n32 madvise sys_madvise
28 n32 shmget sys_shmget
29 n32 shmat sys_shmat
30 n32 shmctl compat_sys_shmctl
30 n32 shmctl compat_sys_old_shmctl
31 n32 dup sys_dup
32 n32 dup2 sys_dup2
33 n32 pause sys_pause
Expand Down Expand Up @@ -71,12 +71,12 @@
61 n32 uname sys_newuname
62 n32 semget sys_semget
63 n32 semop sys_semop
64 n32 semctl compat_sys_semctl
64 n32 semctl compat_sys_old_semctl
65 n32 shmdt sys_shmdt
66 n32 msgget sys_msgget
67 n32 msgsnd compat_sys_msgsnd
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
71 n32 flock sys_flock
72 n32 fsync sys_fsync
Expand Down
6 changes: 3 additions & 3 deletions arch/mips/kernel/syscalls/syscall_n64.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
27 n64 madvise sys_madvise
28 n64 shmget sys_shmget
29 n64 shmat sys_shmat
30 n64 shmctl sys_shmctl
30 n64 shmctl sys_old_shmctl
31 n64 dup sys_dup
32 n64 dup2 sys_dup2
33 n64 pause sys_pause
Expand Down Expand Up @@ -71,12 +71,12 @@
61 n64 uname sys_newuname
62 n64 semget sys_semget
63 n64 semop sys_semop
64 n64 semctl sys_semctl
64 n64 semctl sys_old_semctl
65 n64 shmdt sys_shmdt
66 n64 msgget sys_msgget
67 n64 msgsnd sys_msgsnd
68 n64 msgrcv sys_msgrcv
69 n64 msgctl sys_msgctl
69 n64 msgctl sys_old_msgctl
70 n64 fcntl sys_fcntl
71 n64 flock sys_flock
72 n64 fsync sys_fsync
Expand Down
6 changes: 3 additions & 3 deletions arch/xtensa/kernel/syscalls/syscall.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@
91 common madvise sys_madvise
92 common shmget sys_shmget
93 common shmat xtensa_shmat
94 common shmctl sys_shmctl
94 common shmctl sys_old_shmctl
95 common shmdt sys_shmdt
# Socket Operations
96 common socket sys_socket
Expand Down Expand Up @@ -177,12 +177,12 @@
161 common semtimedop sys_semtimedop
162 common semget sys_semget
163 common semop sys_semop
164 common semctl sys_semctl
164 common semctl sys_old_semctl
165 common available165 sys_ni_syscall
166 common msgget sys_msgget
167 common msgsnd sys_msgsnd
168 common msgrcv sys_msgrcv
169 common msgctl sys_msgctl
169 common msgctl sys_old_msgctl
170 common available170 sys_ni_syscall
# File System
171 common umount2 sys_umount
Expand Down
3 changes: 3 additions & 0 deletions include/linux/syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,7 @@ asmlinkage long sys_mq_getsetattr(mqd_t mqdes, const struct mq_attr __user *mqst

/* ipc/msg.c */
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_msgrcv(int msqid, struct msgbuf __user *msgp,
size_t msgsz, long msgtyp, int msgflg);
Expand All @@ -726,6 +727,7 @@ asmlinkage long sys_msgsnd(int msqid, struct msgbuf __user *msgp,
/* ipc/sem.c */
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_old_semctl(int semid, int semnum, int cmd, unsigned long arg);
asmlinkage long sys_semtimedop(int semid, struct sembuf __user *sops,
unsigned nsops,
const struct __kernel_timespec __user *timeout);
Expand All @@ -734,6 +736,7 @@ asmlinkage long sys_semop(int semid, struct sembuf __user *sops,

/* ipc/shm.c */
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_shmat(int shmid, char __user *shmaddr, int shmflg);
asmlinkage long sys_shmdt(char __user *shmaddr);
Expand Down
39 changes: 32 additions & 7 deletions ipc/msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -567,17 +567,15 @@ static int msgctl_stat(struct ipc_namespace *ns, int msqid,
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 msqid64_ds msqid64;
int err;

if (msqid < 0 || cmd < 0)
return -EINVAL;

version = ipc_parse_version(&cmd);
ns = current->nsproxy->ipc_ns;

switch (cmd) {
Expand Down Expand Up @@ -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)
{
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

struct compat_msqid_ds {
Expand Down Expand Up @@ -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;
int err;
struct msqid64_ds msqid64;
int version = compat_ipc_parse_version(&cmd);

ns = current->nsproxy->ipc_ns;

Expand Down Expand Up @@ -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)
{
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

static int testmsg(struct msg_msg *msg, long type, int mode)
Expand Down
39 changes: 32 additions & 7 deletions ipc/sem.c
Original file line number Diff line number Diff line change
Expand Up @@ -1634,9 +1634,8 @@ static int semctl_down(struct ipc_namespace *ns, int semid,
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;
void __user *p = (void __user *)arg;
struct semid64_ds semid64;
Expand All @@ -1645,7 +1644,6 @@ long ksys_semctl(int semid, int semnum, int cmd, unsigned long arg)
if (semid < 0)
return -EINVAL;

version = ipc_parse_version(&cmd);
ns = current->nsproxy->ipc_ns;

switch (cmd) {
Expand Down Expand Up @@ -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)
{
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

struct compat_semid_ds {
Expand Down Expand Up @@ -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);
struct ipc_namespace *ns;
struct semid64_ds semid64;
int version = compat_ipc_parse_version(&cmd);
int err;

ns = current->nsproxy->ipc_ns;
Expand Down Expand Up @@ -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)
{
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

/* If the task doesn't already have a undo_list, then allocate one
Expand Down
Loading

0 comments on commit 275f221

Please sign in to comment.