diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2007-10-09 23:56:31 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-14 00:53:12 -0400 |
commit | 7379b42b607782695f49d05c80d3eb99e5072908 (patch) | |
tree | 7187727755fbcb36b66c583c7ed89cb169a52f12 /arch/sparc64 | |
parent | fa7744dbb69c06b69c7449063c440d8a53df9e6c (diff) |
[SPARC64]: Fix bugs in SYSV IPC handling in 64-bit processes.
Thanks to Tom Callaway for the excellent bug report and
test case.
sys_ipc() has several problems, most to due with semaphore
call handling:
1) 'err' return should be a 'long'
2) "union semun" is passed in a register on 64-bit compared
to 32-bit which provides it on the stack and therefore
by reference
3) Second and third arguments to SEMCTL are swapped compared
to 32-bit.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64')
-rw-r--r-- | arch/sparc64/kernel/sys_sparc.c | 15 |
1 files changed, 4 insertions, 11 deletions
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c index d108eeb0734f..0d5c50264945 100644 --- a/arch/sparc64/kernel/sys_sparc.c +++ b/arch/sparc64/kernel/sys_sparc.c | |||
@@ -436,7 +436,7 @@ out: | |||
436 | asmlinkage long sys_ipc(unsigned int call, int first, unsigned long second, | 436 | asmlinkage long sys_ipc(unsigned int call, int first, unsigned long second, |
437 | unsigned long third, void __user *ptr, long fifth) | 437 | unsigned long third, void __user *ptr, long fifth) |
438 | { | 438 | { |
439 | int err; | 439 | long err; |
440 | 440 | ||
441 | /* No need for backward compatibility. We can start fresh... */ | 441 | /* No need for backward compatibility. We can start fresh... */ |
442 | if (call <= SEMCTL) { | 442 | if (call <= SEMCTL) { |
@@ -453,16 +453,9 @@ asmlinkage long sys_ipc(unsigned int call, int first, unsigned long second, | |||
453 | err = sys_semget(first, (int)second, (int)third); | 453 | err = sys_semget(first, (int)second, (int)third); |
454 | goto out; | 454 | goto out; |
455 | case SEMCTL: { | 455 | case SEMCTL: { |
456 | union semun fourth; | 456 | err = sys_semctl(first, third, |
457 | err = -EINVAL; | 457 | (int)second | IPC_64, |
458 | if (!ptr) | 458 | (union semun) ptr); |
459 | goto out; | ||
460 | err = -EFAULT; | ||
461 | if (get_user(fourth.__pad, | ||
462 | (void __user * __user *) ptr)) | ||
463 | goto out; | ||
464 | err = sys_semctl(first, (int)second | IPC_64, | ||
465 | (int)third, fourth); | ||
466 | goto out; | 459 | goto out; |
467 | } | 460 | } |
468 | default: | 461 | default: |