Commit 224789f6 authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Linus Torvalds

[PATCH] Fix shmget for ppc64, s390-64 & sparc64.

The second parameter of the sys_ipc system wrapper on ppc64, s390-64 and
sparc64 is an "int".  sys_shmget gets called with this 32 bit value as the
size parameter.  This limits the maximum shared memory segment on these
three architectures to 2GB.  To fix this the second parameter is declared
as an "unsigned long" and is then casted to the type required by the The
same int vs.  unsigned long bug is fixed for sys_msgsnd and sys_msgrcv as
well.
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 1e8a9345
...@@ -57,7 +57,8 @@ check_bugs(void) ...@@ -57,7 +57,8 @@ check_bugs(void)
* This is really horribly ugly. * This is really horribly ugly.
*/ */
asmlinkage int asmlinkage int
sys_ipc (uint call, int first, int second, long third, void __user *ptr, long fifth) sys_ipc (uint call, int first, unsigned long second, long third,
void __user *ptr, long fifth)
{ {
int version, ret; int version, ret;
...@@ -67,15 +68,16 @@ sys_ipc (uint call, int first, int second, long third, void __user *ptr, long fi ...@@ -67,15 +68,16 @@ sys_ipc (uint call, int first, int second, long third, void __user *ptr, long fi
ret = -ENOSYS; ret = -ENOSYS;
switch (call) { switch (call) {
case SEMOP: case SEMOP:
ret = sys_semtimedop (first, (struct sembuf __user *)ptr, second, ret = sys_semtimedop(first, (struct sembuf __user *)ptr,
NULL); (unsigned)second, NULL);
break; break;
case SEMTIMEDOP: case SEMTIMEDOP:
ret = sys_semtimedop (first, (struct sembuf __user *)ptr, second, ret = sys_semtimedop(first, (struct sembuf __user *)ptr,
(unsigned)second,
(const struct timespec __user *) fifth); (const struct timespec __user *) fifth);
break; break;
case SEMGET: case SEMGET:
ret = sys_semget (first, second, third); ret = sys_semget (first, (int)second, third);
break; break;
case SEMCTL: { case SEMCTL: {
union semun fourth; union semun fourth;
...@@ -85,11 +87,12 @@ sys_ipc (uint call, int first, int second, long third, void __user *ptr, long fi ...@@ -85,11 +87,12 @@ sys_ipc (uint call, int first, int second, long third, void __user *ptr, long fi
break; break;
if ((ret = get_user(fourth.__pad, (void __user * __user *)ptr))) if ((ret = get_user(fourth.__pad, (void __user * __user *)ptr)))
break; break;
ret = sys_semctl (first, second, third, fourth); ret = sys_semctl(first, (int)second, third, fourth);
break; break;
} }
case MSGSND: case MSGSND:
ret = sys_msgsnd (first, (struct msgbuf __user *) ptr, second, third); ret = sys_msgsnd(first, (struct msgbuf __user *)ptr,
(size_t)second, third);
break; break;
case MSGRCV: case MSGRCV:
switch (version) { switch (version) {
...@@ -103,27 +106,29 @@ sys_ipc (uint call, int first, int second, long third, void __user *ptr, long fi ...@@ -103,27 +106,29 @@ sys_ipc (uint call, int first, int second, long third, void __user *ptr, long fi
(struct ipc_kludge __user *) ptr, (struct ipc_kludge __user *) ptr,
sizeof (tmp)) ? -EFAULT : 0)) sizeof (tmp)) ? -EFAULT : 0))
break; break;
ret = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, ret = sys_msgrcv(first, tmp.msgp, (size_t) second,
third); tmp.msgtyp, third);
break; break;
} }
default: default:
ret = sys_msgrcv (first, (struct msgbuf __user *) ptr, ret = sys_msgrcv (first, (struct msgbuf __user *) ptr,
second, fifth, third); (size_t)second, fifth, third);
break; break;
} }
break; break;
case MSGGET: case MSGGET:
ret = sys_msgget ((key_t) first, second); ret = sys_msgget ((key_t)first, (int)second);
break; break;
case MSGCTL: case MSGCTL:
ret = sys_msgctl (first, second, (struct msqid_ds __user *) ptr); ret = sys_msgctl(first, (int)second,
(struct msqid_ds __user *)ptr);
break; break;
case SHMAT: case SHMAT:
switch (version) { switch (version) {
default: { default: {
ulong raddr; ulong raddr;
ret = do_shmat (first, (char __user *) ptr, second, &raddr); ret = do_shmat(first, (char __user *) ptr,
(int)second, &raddr);
if (ret) if (ret)
break; break;
ret = put_user (raddr, (ulong __user *) third); ret = put_user (raddr, (ulong __user *) third);
...@@ -133,8 +138,8 @@ sys_ipc (uint call, int first, int second, long third, void __user *ptr, long fi ...@@ -133,8 +138,8 @@ sys_ipc (uint call, int first, int second, long third, void __user *ptr, long fi
ret = -EINVAL; ret = -EINVAL;
if (!segment_eq(get_fs(), get_ds())) if (!segment_eq(get_fs(), get_ds()))
break; break;
ret = do_shmat (first, (char __user *) ptr, second, ret = do_shmat(first, (char __user *)ptr,
(ulong *) third); (int)second, (ulong *)third);
break; break;
} }
break; break;
...@@ -142,10 +147,11 @@ sys_ipc (uint call, int first, int second, long third, void __user *ptr, long fi ...@@ -142,10 +147,11 @@ sys_ipc (uint call, int first, int second, long third, void __user *ptr, long fi
ret = sys_shmdt ((char __user *)ptr); ret = sys_shmdt ((char __user *)ptr);
break; break;
case SHMGET: case SHMGET:
ret = sys_shmget (first, second, third); ret = sys_shmget (first, (size_t)second, third);
break; break;
case SHMCTL: case SHMCTL:
ret = sys_shmctl (first, second, (struct shmid_ds __user *) ptr); ret = sys_shmctl(first, (int)second,
(struct shmid_ds __user *)ptr);
break; break;
} }
......
...@@ -145,7 +145,7 @@ asmlinkage long old_select(struct sel_arg_struct __user *arg) ...@@ -145,7 +145,7 @@ asmlinkage long old_select(struct sel_arg_struct __user *arg)
* *
* This is really horribly ugly. * This is really horribly ugly.
*/ */
asmlinkage long sys_ipc(uint call, int first, int second, asmlinkage long sys_ipc(uint call, int first, unsigned long second,
unsigned long third, void __user *ptr) unsigned long third, void __user *ptr)
{ {
struct ipc_kludge tmp; struct ipc_kludge tmp;
...@@ -153,24 +153,25 @@ asmlinkage long sys_ipc(uint call, int first, int second, ...@@ -153,24 +153,25 @@ asmlinkage long sys_ipc(uint call, int first, int second,
switch (call) { switch (call) {
case SEMOP: case SEMOP:
return sys_semtimedop (first, (struct sembuf __user *) ptr, second, return sys_semtimedop(first, (struct sembuf __user *)ptr,
NULL); (unsigned)second, NULL);
case SEMTIMEDOP: case SEMTIMEDOP:
return sys_semtimedop (first, (struct sembuf __user *) ptr, second, return sys_semtimedop(first, (struct sembuf __user *)ptr,
(unsigned)second,
(const struct timespec __user *) third); (const struct timespec __user *) third);
case SEMGET: case SEMGET:
return sys_semget (first, second, third); return sys_semget(first, (int)second, third);
case SEMCTL: { case SEMCTL: {
union semun fourth; union semun fourth;
if (!ptr) if (!ptr)
return -EINVAL; return -EINVAL;
if (get_user(fourth.__pad, (void __user * __user *) ptr)) if (get_user(fourth.__pad, (void __user * __user *) ptr))
return -EFAULT; return -EFAULT;
return sys_semctl (first, second, third, fourth); return sys_semctl(first, (int)second, third, fourth);
} }
case MSGSND: case MSGSND:
return sys_msgsnd (first, (struct msgbuf __user *) ptr, return sys_msgsnd (first, (struct msgbuf __user *) ptr,
second, third); (size_t)second, third);
break; break;
case MSGRCV: case MSGRCV:
if (!ptr) if (!ptr)
...@@ -179,15 +180,17 @@ asmlinkage long sys_ipc(uint call, int first, int second, ...@@ -179,15 +180,17 @@ asmlinkage long sys_ipc(uint call, int first, int second,
sizeof (struct ipc_kludge))) sizeof (struct ipc_kludge)))
return -EFAULT; return -EFAULT;
return sys_msgrcv (first, tmp.msgp, return sys_msgrcv (first, tmp.msgp,
second, tmp.msgtyp, third); (size_t)second, tmp.msgtyp, third);
case MSGGET: case MSGGET:
return sys_msgget ((key_t) first, second); return sys_msgget((key_t)first, (int)second);
case MSGCTL: case MSGCTL:
return sys_msgctl (first, second, (struct msqid_ds __user *) ptr); return sys_msgctl(first, (int)second,
(struct msqid_ds __user *)ptr);
case SHMAT: { case SHMAT: {
ulong raddr; ulong raddr;
ret = do_shmat (first, (char __user *) ptr, second, &raddr); ret = do_shmat(first, (char __user *)ptr,
(int)second, &raddr);
if (ret) if (ret)
return ret; return ret;
return put_user (raddr, (ulong __user *) third); return put_user (raddr, (ulong __user *) third);
...@@ -196,9 +199,9 @@ asmlinkage long sys_ipc(uint call, int first, int second, ...@@ -196,9 +199,9 @@ asmlinkage long sys_ipc(uint call, int first, int second,
case SHMDT: case SHMDT:
return sys_shmdt ((char __user *)ptr); return sys_shmdt ((char __user *)ptr);
case SHMGET: case SHMGET:
return sys_shmget (first, second, third); return sys_shmget(first, (size_t)second, third);
case SHMCTL: case SHMCTL:
return sys_shmctl (first, second, return sys_shmctl(first, (int)second,
(struct shmid_ds __user *) ptr); (struct shmid_ds __user *) ptr);
default: default:
return -ENOSYS; return -ENOSYS;
......
...@@ -199,7 +199,8 @@ asmlinkage long sparc_pipe(struct pt_regs *regs) ...@@ -199,7 +199,8 @@ asmlinkage long sparc_pipe(struct pt_regs *regs)
* This is really horribly ugly. * This is really horribly ugly.
*/ */
asmlinkage long sys_ipc(unsigned int call, int first, int second, unsigned long third, void __user *ptr, long fifth) asmlinkage long sys_ipc(unsigned int call, int first, unsigned long second,
unsigned long third, void __user *ptr, long fifth)
{ {
int err; int err;
...@@ -207,14 +208,15 @@ asmlinkage long sys_ipc(unsigned int call, int first, int second, unsigned long ...@@ -207,14 +208,15 @@ asmlinkage long sys_ipc(unsigned int call, int first, int second, unsigned long
if (call <= SEMCTL) { if (call <= SEMCTL) {
switch (call) { switch (call) {
case SEMOP: case SEMOP:
err = sys_semtimedop(first, ptr, second, NULL); err = sys_semtimedop(first, ptr,
(unsigned)second, NULL);
goto out; goto out;
case SEMTIMEDOP: case SEMTIMEDOP:
err = sys_semtimedop(first, ptr, second, err = sys_semtimedop(first, ptr, (unsigned)second,
(const struct timespec __user *) fifth); (const struct timespec __user *) fifth);
goto out; goto out;
case SEMGET: case SEMGET:
err = sys_semget(first, second, (int)third); err = sys_semget(first, (int)second, (int)third);
goto out; goto out;
case SEMCTL: { case SEMCTL: {
union semun fourth; union semun fourth;
...@@ -225,7 +227,7 @@ asmlinkage long sys_ipc(unsigned int call, int first, int second, unsigned long ...@@ -225,7 +227,7 @@ asmlinkage long sys_ipc(unsigned int call, int first, int second, unsigned long
if (get_user(fourth.__pad, if (get_user(fourth.__pad,
(void __user * __user *) ptr)) (void __user * __user *) ptr))
goto out; goto out;
err = sys_semctl(first, second | IPC_64, err = sys_semctl(first, (int)second | IPC_64,
(int)third, fourth); (int)third, fourth);
goto out; goto out;
} }
...@@ -237,17 +239,18 @@ asmlinkage long sys_ipc(unsigned int call, int first, int second, unsigned long ...@@ -237,17 +239,18 @@ asmlinkage long sys_ipc(unsigned int call, int first, int second, unsigned long
if (call <= MSGCTL) { if (call <= MSGCTL) {
switch (call) { switch (call) {
case MSGSND: case MSGSND:
err = sys_msgsnd(first, ptr, second, (int)third); err = sys_msgsnd(first, ptr, (size_t)second,
(int)third);
goto out; goto out;
case MSGRCV: case MSGRCV:
err = sys_msgrcv(first, ptr, second, fifth, err = sys_msgrcv(first, ptr, (size_t)second, fifth,
(int)third); (int)third);
goto out; goto out;
case MSGGET: case MSGGET:
err = sys_msgget((key_t) first, second); err = sys_msgget((key_t)first, (int)second);
goto out; goto out;
case MSGCTL: case MSGCTL:
err = sys_msgctl(first, second | IPC_64, ptr); err = sys_msgctl(first, (int)second | IPC_64, ptr);
goto out; goto out;
default: default:
err = -ENOSYS; err = -ENOSYS;
...@@ -258,7 +261,7 @@ asmlinkage long sys_ipc(unsigned int call, int first, int second, unsigned long ...@@ -258,7 +261,7 @@ asmlinkage long sys_ipc(unsigned int call, int first, int second, unsigned long
switch (call) { switch (call) {
case SHMAT: { case SHMAT: {
ulong raddr; ulong raddr;
err = do_shmat(first, ptr, second, &raddr); err = do_shmat(first, ptr, (int)second, &raddr);
if (!err) { if (!err) {
if (put_user(raddr, if (put_user(raddr,
(ulong __user *) third)) (ulong __user *) third))
...@@ -270,10 +273,10 @@ asmlinkage long sys_ipc(unsigned int call, int first, int second, unsigned long ...@@ -270,10 +273,10 @@ asmlinkage long sys_ipc(unsigned int call, int first, int second, unsigned long
err = sys_shmdt(ptr); err = sys_shmdt(ptr);
goto out; goto out;
case SHMGET: case SHMGET:
err = sys_shmget(first, second, (int)third); err = sys_shmget(first, (size_t)second, (int)third);
goto out; goto out;
case SHMCTL: case SHMCTL:
err = sys_shmctl(first, second | IPC_64, ptr); err = sys_shmctl(first, (int)second | IPC_64, ptr);
goto out; goto out;
default: default:
err = -ENOSYS; err = -ENOSYS;
......
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