Commit a214c047 authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Linus Torvalds

[PATCH] s390: semtimedop.

Fix SEMTIMEDOP operation in sys_ipc. Patch by Ernie Petrides.
parent c5838f46
...@@ -373,12 +373,45 @@ struct shmid64_ds32 { ...@@ -373,12 +373,45 @@ struct shmid64_ds32 {
unsigned int __unused5; unsigned int __unused5;
}; };
extern int sem_ctls[];
#define sc_semopm (sem_ctls[2])
#define SEMOPM_FAST 64 /* ~ 372 bytes on stack */
static long
do_sys32_semtimedop (int semid, struct sembuf *tsops, int nsops,
struct compat_timespec *timeout32)
{
struct sembuf *sops, fast_sops[SEMOPM_FAST];
struct timespec t;
mm_segment_t oldfs;
long ret;
/* parameter checking precedence should mirror sys_semtimedop() */
if (nsops < 1 || semid < 0)
return -EINVAL;
if (nsops > sc_semopm)
return -E2BIG;
if (nsops <= SEMOPM_FAST)
sops = fast_sops;
else {
sops = kmalloc(nsops * sizeof(*sops), GFP_KERNEL);
if (sops == NULL)
return -ENOMEM;
}
if (copy_from_user(sops, tsops, nsops * sizeof(*tsops)) ||
get_compat_timespec(&t, timeout32))
ret = -EFAULT;
else {
oldfs = get_fs();
set_fs(KERNEL_DS);
ret = sys_semtimedop(semid, sops, nsops, &t);
set_fs(oldfs);
}
if (sops != fast_sops)
kfree(sops);
return ret;
}
/*
* sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
*
* This is really horribly ugly.
*/
#define IPCOP_MASK(__x) (1UL << (__x)) #define IPCOP_MASK(__x) (1UL << (__x))
static int do_sys32_semctl(int first, int second, int third, void *uptr) static int do_sys32_semctl(int first, int second, int third, void *uptr)
{ {
...@@ -763,7 +796,12 @@ static int do_sys32_shmctl (int first, int second, void *uptr) ...@@ -763,7 +796,12 @@ static int do_sys32_shmctl (int first, int second, void *uptr)
return err; return err;
} }
asmlinkage int sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth) /*
* sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation.
*
* This is really horribly ugly.
*/
asmlinkage int sys32_ipc (u32 call, int first, int second, int third, u32 ptr)
{ {
int version, err; int version, err;
...@@ -773,11 +811,22 @@ asmlinkage int sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u ...@@ -773,11 +811,22 @@ asmlinkage int sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u
if(version) if(version)
return -EINVAL; return -EINVAL;
if (call <= SEMCTL) if (call <= SEMTIMEDOP)
switch (call) { switch (call) {
case SEMTIMEDOP:
if (third) {
err = do_sys32_semtimedop(first,
(struct sembuf *)AA(ptr),
second,
(struct compat_timespec *)
AA((u32)third));
goto out;
}
/* else fall through for normal semop() */
case SEMOP: case SEMOP:
/* struct sembuf is the same on 32 and 64bit :)) */ /* struct sembuf is the same on 32 and 64bit :)) */
err = sys_semop (first, (struct sembuf *)AA(ptr), second); err = sys_semtimedop (first, (struct sembuf *)AA(ptr),
second, NULL);
goto out; goto out;
case SEMGET: case SEMGET:
err = sys_semget (first, second, third); err = sys_semget (first, second, third);
......
...@@ -184,8 +184,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, ...@@ -184,8 +184,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
* This is really horribly ugly. * This is really horribly ugly.
*/ */
asmlinkage __SYS_RETTYPE sys_ipc (uint call, int first, int second, asmlinkage __SYS_RETTYPE sys_ipc (uint call, int first, int second,
unsigned long third, void *ptr, unsigned long third, void *ptr)
unsigned long fifth)
{ {
struct ipc_kludge tmp; struct ipc_kludge tmp;
int ret; int ret;
...@@ -195,8 +194,8 @@ asmlinkage __SYS_RETTYPE sys_ipc (uint call, int first, int second, ...@@ -195,8 +194,8 @@ asmlinkage __SYS_RETTYPE sys_ipc (uint call, int first, int second,
return sys_semtimedop (first, (struct sembuf *) ptr, second, return sys_semtimedop (first, (struct sembuf *) ptr, second,
NULL); NULL);
case SEMTIMEDOP: case SEMTIMEDOP:
return sys_semtimedop(first, (struct sembuf *) ptr, second, return sys_semtimedop (first, (struct sembuf *) ptr, second,
(const struct timespec *) fifth); (const struct timespec *) third);
case SEMGET: case SEMGET:
return sys_semget (first, second, third); return sys_semget (first, second, third);
case SEMCTL: { case SEMCTL: {
......
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