aboutsummaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-01 10:21:43 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-01 10:21:43 -0400
commit08d76760832993050ad8c25e63b56773ef2ca303 (patch)
treeabdcf148dfe43cd49f30f204f1dac6978107a508 /ipc
parent5f56886521d6ddd3648777fae44d82382dd8c87f (diff)
parent99e621f796d7f0341a51e8cdf32b81663b10b448 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
Pull compat cleanup from Al Viro: "Mostly about syscall wrappers this time; there will be another pile with patches in the same general area from various people, but I'd rather push those after both that and vfs.git pile are in." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: syscalls.h: slightly reduce the jungles of macros get rid of union semop in sys_semctl(2) arguments make do_mremap() static sparc: no need to sign-extend in sync_file_range() wrapper ppc compat wrappers for add_key(2) and request_key(2) are pointless x86: trim sys_ia32.h x86: sys32_kill and sys32_mprotect are pointless get rid of compat_sys_semctl() and friends in case of ARCH_WANT_OLD_COMPAT_IPC merge compat sys_ipc instances consolidate compat lookup_dcookie() convert vmsplice to COMPAT_SYSCALL_DEFINE switch getrusage() to COMPAT_SYSCALL_DEFINE switch epoll_pwait to COMPAT_SYSCALL_DEFINE convert sendfile{,64} to COMPAT_SYSCALL_DEFINE switch signalfd{,4}() to COMPAT_SYSCALL_DEFINE make SYSCALL_DEFINE<n>-generated wrappers do asmlinkage_protect make HAVE_SYSCALL_WRAPPERS unconditional consolidate cond_syscall and SYSCALL_ALIAS declarations teach SYSCALL_DEFINE<n> how to deal with long long/unsigned long long get rid of duplicate logics in __SC_....[1-6] definitions
Diffstat (limited to 'ipc')
-rw-r--r--ipc/compat.c174
-rw-r--r--ipc/sem.c123
-rw-r--r--ipc/syscall.c6
3 files changed, 177 insertions, 126 deletions
diff --git a/ipc/compat.c b/ipc/compat.c
index 2547f29dcd1b..892f6585dd60 100644
--- a/ipc/compat.c
+++ b/ipc/compat.c
@@ -240,7 +240,7 @@ static inline int put_compat_semid_ds(struct semid64_ds *s,
240 240
241static long do_compat_semctl(int first, int second, int third, u32 pad) 241static long do_compat_semctl(int first, int second, int third, u32 pad)
242{ 242{
243 union semun fourth; 243 unsigned long fourth;
244 int err, err2; 244 int err, err2;
245 struct semid64_ds s64; 245 struct semid64_ds s64;
246 struct semid64_ds __user *up64; 246 struct semid64_ds __user *up64;
@@ -249,9 +249,13 @@ static long do_compat_semctl(int first, int second, int third, u32 pad)
249 memset(&s64, 0, sizeof(s64)); 249 memset(&s64, 0, sizeof(s64));
250 250
251 if ((third & (~IPC_64)) == SETVAL) 251 if ((third & (~IPC_64)) == SETVAL)
252 fourth.val = (int) pad; 252#ifdef __BIG_ENDIAN
253 fourth = (unsigned long)pad << 32;
254#else
255 fourth = pad;
256#endif
253 else 257 else
254 fourth.__pad = compat_ptr(pad); 258 fourth = (unsigned long)compat_ptr(pad);
255 switch (third & (~IPC_64)) { 259 switch (third & (~IPC_64)) {
256 case IPC_INFO: 260 case IPC_INFO:
257 case IPC_RMID: 261 case IPC_RMID:
@@ -269,7 +273,7 @@ static long do_compat_semctl(int first, int second, int third, u32 pad)
269 case IPC_STAT: 273 case IPC_STAT:
270 case SEM_STAT: 274 case SEM_STAT:
271 up64 = compat_alloc_user_space(sizeof(s64)); 275 up64 = compat_alloc_user_space(sizeof(s64));
272 fourth.__pad = up64; 276 fourth = (unsigned long)up64;
273 err = sys_semctl(first, second, third, fourth); 277 err = sys_semctl(first, second, third, fourth);
274 if (err < 0) 278 if (err < 0)
275 break; 279 break;
@@ -295,7 +299,7 @@ static long do_compat_semctl(int first, int second, int third, u32 pad)
295 if (err) 299 if (err)
296 break; 300 break;
297 301
298 fourth.__pad = up64; 302 fourth = (unsigned long)up64;
299 err = sys_semctl(first, second, third, fourth); 303 err = sys_semctl(first, second, third, fourth);
300 break; 304 break;
301 305
@@ -306,7 +310,7 @@ static long do_compat_semctl(int first, int second, int third, u32 pad)
306 return err; 310 return err;
307} 311}
308 312
309long compat_do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz) 313static long compat_do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz)
310{ 314{
311 struct compat_msgbuf __user *msgp = dest; 315 struct compat_msgbuf __user *msgp = dest;
312 size_t msgsz; 316 size_t msgsz;
@@ -320,77 +324,117 @@ long compat_do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz)
320 return msgsz; 324 return msgsz;
321} 325}
322 326
327#ifndef COMPAT_SHMLBA
328#define COMPAT_SHMLBA SHMLBA
329#endif
330
323#ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC 331#ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC
324long compat_sys_semctl(int first, int second, int third, void __user *uptr) 332COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second,
333 u32, third, compat_uptr_t, ptr, u32, fifth)
325{ 334{
335 int version;
326 u32 pad; 336 u32 pad;
327 337
328 if (!uptr) 338 version = call >> 16; /* hack for backward compatibility */
329 return -EINVAL; 339 call &= 0xffff;
330 if (get_user(pad, (u32 __user *) uptr)) 340
331 return -EFAULT; 341 switch (call) {
332 return do_compat_semctl(first, second, third, pad); 342 case SEMOP:
333} 343 /* struct sembuf is the same on 32 and 64bit :)) */
344 return sys_semtimedop(first, compat_ptr(ptr), second, NULL);
345 case SEMTIMEDOP:
346 return compat_sys_semtimedop(first, compat_ptr(ptr), second,
347 compat_ptr(fifth));
348 case SEMGET:
349 return sys_semget(first, second, third);
350 case SEMCTL:
351 if (!ptr)
352 return -EINVAL;
353 if (get_user(pad, (u32 __user *) compat_ptr(ptr)))
354 return -EFAULT;
355 return do_compat_semctl(first, second, third, pad);
334 356
335long compat_sys_msgsnd(int first, int second, int third, void __user *uptr) 357 case MSGSND: {
336{ 358 struct compat_msgbuf __user *up = compat_ptr(ptr);
337 struct compat_msgbuf __user *up = uptr; 359 compat_long_t type;
338 long type;
339 360
340 if (first < 0) 361 if (first < 0 || second < 0)
341 return -EINVAL; 362 return -EINVAL;
342 if (second < 0)
343 return -EINVAL;
344 363
345 if (get_user(type, &up->mtype)) 364 if (get_user(type, &up->mtype))
346 return -EFAULT; 365 return -EFAULT;
347 366
348 return do_msgsnd(first, type, up->mtext, second, third); 367 return do_msgsnd(first, type, up->mtext, second, third);
349} 368 }
369 case MSGRCV: {
370 void __user *uptr = compat_ptr(ptr);
350 371
351long compat_sys_msgrcv(int first, int second, int msgtyp, int third, 372 if (first < 0 || second < 0)
352 int version, void __user *uptr)
353{
354 if (first < 0)
355 return -EINVAL;
356 if (second < 0)
357 return -EINVAL;
358
359 if (!version) {
360 struct compat_ipc_kludge ipck;
361 if (!uptr)
362 return -EINVAL; 373 return -EINVAL;
363 if (copy_from_user (&ipck, uptr, sizeof(ipck))) 374
364 return -EFAULT; 375 if (!version) {
365 uptr = compat_ptr(ipck.msgp); 376 struct compat_ipc_kludge ipck;
366 msgtyp = ipck.msgtyp; 377 if (!uptr)
378 return -EINVAL;
379 if (copy_from_user (&ipck, uptr, sizeof(ipck)))
380 return -EFAULT;
381 uptr = compat_ptr(ipck.msgp);
382 fifth = ipck.msgtyp;
383 }
384 return do_msgrcv(first, uptr, second, fifth, third,
385 compat_do_msg_fill);
367 } 386 }
368 return do_msgrcv(first, uptr, second, msgtyp, third, 387 case MSGGET:
369 compat_do_msg_fill); 388 return sys_msgget(first, second);
389 case MSGCTL:
390 return compat_sys_msgctl(first, second, compat_ptr(ptr));
391
392 case SHMAT: {
393 int err;
394 unsigned long raddr;
395
396 if (version == 1)
397 return -EINVAL;
398 err = do_shmat(first, compat_ptr(ptr), second, &raddr,
399 COMPAT_SHMLBA);
400 if (err < 0)
401 return err;
402 return put_user(raddr, (compat_ulong_t *)compat_ptr(third));
403 }
404 case SHMDT:
405 return sys_shmdt(compat_ptr(ptr));
406 case SHMGET:
407 return sys_shmget(first, (unsigned)second, third);
408 case SHMCTL:
409 return compat_sys_shmctl(first, second, compat_ptr(ptr));
410 }
411
412 return -ENOSYS;
370} 413}
371#else 414#endif
372long compat_sys_semctl(int semid, int semnum, int cmd, int arg) 415
416COMPAT_SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, int, arg)
373{ 417{
374 return do_compat_semctl(semid, semnum, cmd, arg); 418 return do_compat_semctl(semid, semnum, cmd, arg);
375} 419}
376 420
377long compat_sys_msgsnd(int msqid, struct compat_msgbuf __user *msgp, 421COMPAT_SYSCALL_DEFINE4(msgsnd, int, msqid, compat_uptr_t, msgp,
378 compat_ssize_t msgsz, int msgflg) 422 compat_ssize_t, msgsz, int, msgflg)
379{ 423{
424 struct compat_msgbuf __user *up = compat_ptr(msgp);
380 compat_long_t mtype; 425 compat_long_t mtype;
381 426
382 if (get_user(mtype, &msgp->mtype)) 427 if (get_user(mtype, &up->mtype))
383 return -EFAULT; 428 return -EFAULT;
384 return do_msgsnd(msqid, mtype, msgp->mtext, (ssize_t)msgsz, msgflg); 429 return do_msgsnd(msqid, mtype, up->mtext, (ssize_t)msgsz, msgflg);
385} 430}
386 431
387long compat_sys_msgrcv(int msqid, struct compat_msgbuf __user *msgp, 432COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp,
388 compat_ssize_t msgsz, long msgtyp, int msgflg) 433 compat_ssize_t, msgsz, long, msgtyp, int, msgflg)
389{ 434{
390 return do_msgrcv(msqid, msgp, (ssize_t)msgsz, msgtyp, msgflg, 435 return do_msgrcv(msqid, compat_ptr(msgp), (ssize_t)msgsz, msgtyp,
391 compat_do_msg_fill); 436 msgflg, compat_do_msg_fill);
392} 437}
393#endif
394 438
395static inline int get_compat_msqid64(struct msqid64_ds *m64, 439static inline int get_compat_msqid64(struct msqid64_ds *m64,
396 struct compat_msqid64_ds __user *up64) 440 struct compat_msqid64_ds __user *up64)
@@ -508,28 +552,7 @@ long compat_sys_msgctl(int first, int second, void __user *uptr)
508 return err; 552 return err;
509} 553}
510 554
511#ifndef COMPAT_SHMLBA 555COMPAT_SYSCALL_DEFINE3(shmat, int, shmid, compat_uptr_t, shmaddr, int, shmflg)
512#define COMPAT_SHMLBA SHMLBA
513#endif
514
515#ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC
516long compat_sys_shmat(int first, int second, compat_uptr_t third, int version,
517 void __user *uptr)
518{
519 int err;
520 unsigned long raddr;
521 compat_ulong_t __user *uaddr;
522
523 if (version == 1)
524 return -EINVAL;
525 err = do_shmat(first, uptr, second, &raddr, COMPAT_SHMLBA);
526 if (err < 0)
527 return err;
528 uaddr = compat_ptr(third);
529 return put_user(raddr, uaddr);
530}
531#else
532long compat_sys_shmat(int shmid, compat_uptr_t shmaddr, int shmflg)
533{ 556{
534 unsigned long ret; 557 unsigned long ret;
535 long err; 558 long err;
@@ -540,7 +563,6 @@ long compat_sys_shmat(int shmid, compat_uptr_t shmaddr, int shmflg)
540 force_successful_syscall_return(); 563 force_successful_syscall_return();
541 return (long)ret; 564 return (long)ret;
542} 565}
543#endif
544 566
545static inline int get_compat_shmid64_ds(struct shmid64_ds *s64, 567static inline int get_compat_shmid64_ds(struct shmid64_ds *s64,
546 struct compat_shmid64_ds __user *up64) 568 struct compat_shmid64_ds __user *up64)
diff --git a/ipc/sem.c b/ipc/sem.c
index 58d31f1c1eb5..5b167d00efa6 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -799,7 +799,7 @@ static unsigned long copy_semid_to_user(void __user *buf, struct semid64_ds *in,
799} 799}
800 800
801static int semctl_nolock(struct ipc_namespace *ns, int semid, 801static int semctl_nolock(struct ipc_namespace *ns, int semid,
802 int cmd, int version, union semun arg) 802 int cmd, int version, void __user *p)
803{ 803{
804 int err; 804 int err;
805 struct sem_array *sma; 805 struct sem_array *sma;
@@ -834,7 +834,7 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid,
834 } 834 }
835 max_id = ipc_get_maxid(&sem_ids(ns)); 835 max_id = ipc_get_maxid(&sem_ids(ns));
836 up_read(&sem_ids(ns).rw_mutex); 836 up_read(&sem_ids(ns).rw_mutex);
837 if (copy_to_user (arg.__buf, &seminfo, sizeof(struct seminfo))) 837 if (copy_to_user(p, &seminfo, sizeof(struct seminfo)))
838 return -EFAULT; 838 return -EFAULT;
839 return (max_id < 0) ? 0: max_id; 839 return (max_id < 0) ? 0: max_id;
840 } 840 }
@@ -871,7 +871,7 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid,
871 tbuf.sem_ctime = sma->sem_ctime; 871 tbuf.sem_ctime = sma->sem_ctime;
872 tbuf.sem_nsems = sma->sem_nsems; 872 tbuf.sem_nsems = sma->sem_nsems;
873 sem_unlock(sma); 873 sem_unlock(sma);
874 if (copy_semid_to_user (arg.buf, &tbuf, version)) 874 if (copy_semid_to_user(p, &tbuf, version))
875 return -EFAULT; 875 return -EFAULT;
876 return id; 876 return id;
877 } 877 }
@@ -883,8 +883,67 @@ out_unlock:
883 return err; 883 return err;
884} 884}
885 885
886static int semctl_setval(struct ipc_namespace *ns, int semid, int semnum,
887 unsigned long arg)
888{
889 struct sem_undo *un;
890 struct sem_array *sma;
891 struct sem* curr;
892 int err;
893 int nsems;
894 struct list_head tasks;
895 int val;
896#if defined(CONFIG_64BIT) && defined(__BIG_ENDIAN)
897 /* big-endian 64bit */
898 val = arg >> 32;
899#else
900 /* 32bit or little-endian 64bit */
901 val = arg;
902#endif
903
904 sma = sem_lock_check(ns, semid);
905 if (IS_ERR(sma))
906 return PTR_ERR(sma);
907
908 INIT_LIST_HEAD(&tasks);
909 nsems = sma->sem_nsems;
910
911 err = -EACCES;
912 if (ipcperms(ns, &sma->sem_perm, S_IWUGO))
913 goto out_unlock;
914
915 err = security_sem_semctl(sma, SETVAL);
916 if (err)
917 goto out_unlock;
918
919 err = -EINVAL;
920 if(semnum < 0 || semnum >= nsems)
921 goto out_unlock;
922
923 curr = &sma->sem_base[semnum];
924
925 err = -ERANGE;
926 if (val > SEMVMX || val < 0)
927 goto out_unlock;
928
929 assert_spin_locked(&sma->sem_perm.lock);
930 list_for_each_entry(un, &sma->list_id, list_id)
931 un->semadj[semnum] = 0;
932
933 curr->semval = val;
934 curr->sempid = task_tgid_vnr(current);
935 sma->sem_ctime = get_seconds();
936 /* maybe some queued-up processes were waiting for this */
937 do_smart_update(sma, NULL, 0, 0, &tasks);
938 err = 0;
939out_unlock:
940 sem_unlock(sma);
941 wake_up_sem_queue_do(&tasks);
942 return err;
943}
944
886static int semctl_main(struct ipc_namespace *ns, int semid, int semnum, 945static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
887 int cmd, int version, union semun arg) 946 int cmd, void __user *p)
888{ 947{
889 struct sem_array *sma; 948 struct sem_array *sma;
890 struct sem* curr; 949 struct sem* curr;
@@ -903,7 +962,7 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
903 962
904 err = -EACCES; 963 err = -EACCES;
905 if (ipcperms(ns, &sma->sem_perm, 964 if (ipcperms(ns, &sma->sem_perm,
906 (cmd == SETVAL || cmd == SETALL) ? S_IWUGO : S_IRUGO)) 965 cmd == SETALL ? S_IWUGO : S_IRUGO))
907 goto out_unlock; 966 goto out_unlock;
908 967
909 err = security_sem_semctl(sma, cmd); 968 err = security_sem_semctl(sma, cmd);
@@ -914,7 +973,7 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
914 switch (cmd) { 973 switch (cmd) {
915 case GETALL: 974 case GETALL:
916 { 975 {
917 ushort __user *array = arg.array; 976 ushort __user *array = p;
918 int i; 977 int i;
919 978
920 if(nsems > SEMMSL_FAST) { 979 if(nsems > SEMMSL_FAST) {
@@ -957,7 +1016,7 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
957 } 1016 }
958 } 1017 }
959 1018
960 if (copy_from_user (sem_io, arg.array, nsems*sizeof(ushort))) { 1019 if (copy_from_user (sem_io, p, nsems*sizeof(ushort))) {
961 sem_putref(sma); 1020 sem_putref(sma);
962 err = -EFAULT; 1021 err = -EFAULT;
963 goto out_free; 1022 goto out_free;
@@ -991,7 +1050,7 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
991 err = 0; 1050 err = 0;
992 goto out_unlock; 1051 goto out_unlock;
993 } 1052 }
994 /* GETVAL, GETPID, GETNCTN, GETZCNT, SETVAL: fall-through */ 1053 /* GETVAL, GETPID, GETNCTN, GETZCNT: fall-through */
995 } 1054 }
996 err = -EINVAL; 1055 err = -EINVAL;
997 if(semnum < 0 || semnum >= nsems) 1056 if(semnum < 0 || semnum >= nsems)
@@ -1012,27 +1071,6 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
1012 case GETZCNT: 1071 case GETZCNT:
1013 err = count_semzcnt(sma,semnum); 1072 err = count_semzcnt(sma,semnum);
1014 goto out_unlock; 1073 goto out_unlock;
1015 case SETVAL:
1016 {
1017 int val = arg.val;
1018 struct sem_undo *un;
1019
1020 err = -ERANGE;
1021 if (val > SEMVMX || val < 0)
1022 goto out_unlock;
1023
1024 assert_spin_locked(&sma->sem_perm.lock);
1025 list_for_each_entry(un, &sma->list_id, list_id)
1026 un->semadj[semnum] = 0;
1027
1028 curr->semval = val;
1029 curr->sempid = task_tgid_vnr(current);
1030 sma->sem_ctime = get_seconds();
1031 /* maybe some queued-up processes were waiting for this */
1032 do_smart_update(sma, NULL, 0, 0, &tasks);
1033 err = 0;
1034 goto out_unlock;
1035 }
1036 } 1074 }
1037out_unlock: 1075out_unlock:
1038 sem_unlock(sma); 1076 sem_unlock(sma);
@@ -1076,7 +1114,7 @@ copy_semid_from_user(struct semid64_ds *out, void __user *buf, int version)
1076 * NOTE: no locks must be held, the rw_mutex is taken inside this function. 1114 * NOTE: no locks must be held, the rw_mutex is taken inside this function.
1077 */ 1115 */
1078static int semctl_down(struct ipc_namespace *ns, int semid, 1116static int semctl_down(struct ipc_namespace *ns, int semid,
1079 int cmd, int version, union semun arg) 1117 int cmd, int version, void __user *p)
1080{ 1118{
1081 struct sem_array *sma; 1119 struct sem_array *sma;
1082 int err; 1120 int err;
@@ -1084,7 +1122,7 @@ static int semctl_down(struct ipc_namespace *ns, int semid,
1084 struct kern_ipc_perm *ipcp; 1122 struct kern_ipc_perm *ipcp;
1085 1123
1086 if(cmd == IPC_SET) { 1124 if(cmd == IPC_SET) {
1087 if (copy_semid_from_user(&semid64, arg.buf, version)) 1125 if (copy_semid_from_user(&semid64, p, version))
1088 return -EFAULT; 1126 return -EFAULT;
1089 } 1127 }
1090 1128
@@ -1120,11 +1158,11 @@ out_up:
1120 return err; 1158 return err;
1121} 1159}
1122 1160
1123SYSCALL_DEFINE(semctl)(int semid, int semnum, int cmd, union semun arg) 1161SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, unsigned long, arg)
1124{ 1162{
1125 int err = -EINVAL;
1126 int version; 1163 int version;
1127 struct ipc_namespace *ns; 1164 struct ipc_namespace *ns;
1165 void __user *p = (void __user *)arg;
1128 1166
1129 if (semid < 0) 1167 if (semid < 0)
1130 return -EINVAL; 1168 return -EINVAL;
@@ -1137,32 +1175,23 @@ SYSCALL_DEFINE(semctl)(int semid, int semnum, int cmd, union semun arg)
1137 case SEM_INFO: 1175 case SEM_INFO:
1138 case IPC_STAT: 1176 case IPC_STAT:
1139 case SEM_STAT: 1177 case SEM_STAT:
1140 err = semctl_nolock(ns, semid, cmd, version, arg); 1178 return semctl_nolock(ns, semid, cmd, version, p);
1141 return err;
1142 case GETALL: 1179 case GETALL:
1143 case GETVAL: 1180 case GETVAL:
1144 case GETPID: 1181 case GETPID:
1145 case GETNCNT: 1182 case GETNCNT:
1146 case GETZCNT: 1183 case GETZCNT:
1147 case SETVAL:
1148 case SETALL: 1184 case SETALL:
1149 err = semctl_main(ns,semid,semnum,cmd,version,arg); 1185 return semctl_main(ns, semid, semnum, cmd, p);
1150 return err; 1186 case SETVAL:
1187 return semctl_setval(ns, semid, semnum, arg);
1151 case IPC_RMID: 1188 case IPC_RMID:
1152 case IPC_SET: 1189 case IPC_SET:
1153 err = semctl_down(ns, semid, cmd, version, arg); 1190 return semctl_down(ns, semid, cmd, version, p);
1154 return err;
1155 default: 1191 default:
1156 return -EINVAL; 1192 return -EINVAL;
1157 } 1193 }
1158} 1194}
1159#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
1160asmlinkage long SyS_semctl(int semid, int semnum, int cmd, union semun arg)
1161{
1162 return SYSC_semctl((int) semid, (int) semnum, (int) cmd, arg);
1163}
1164SYSCALL_ALIAS(sys_semctl, SyS_semctl);
1165#endif
1166 1195
1167/* If the task doesn't already have a undo_list, then allocate one 1196/* If the task doesn't already have a undo_list, then allocate one
1168 * here. We guarantee there is only one thread using this undo list, 1197 * here. We guarantee there is only one thread using this undo list,
diff --git a/ipc/syscall.c b/ipc/syscall.c
index 0d1e32ce048e..52429489cde0 100644
--- a/ipc/syscall.c
+++ b/ipc/syscall.c
@@ -33,12 +33,12 @@ SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second,
33 case SEMGET: 33 case SEMGET:
34 return sys_semget(first, second, third); 34 return sys_semget(first, second, third);
35 case SEMCTL: { 35 case SEMCTL: {
36 union semun fourth; 36 unsigned long arg;
37 if (!ptr) 37 if (!ptr)
38 return -EINVAL; 38 return -EINVAL;
39 if (get_user(fourth.__pad, (void __user * __user *) ptr)) 39 if (get_user(arg, (unsigned long __user *) ptr))
40 return -EFAULT; 40 return -EFAULT;
41 return sys_semctl(first, second, third, fourth); 41 return sys_semctl(first, second, third, arg);
42 } 42 }
43 43
44 case MSGSND: 44 case MSGSND: