semctl syscall in compat64 mode need to use the arg argument as 64-bit as it may contain user buffer pointer so use type compat_ulong_t instead of type int.
Also 64 bit architectures use a 64-bit long time field similar to the native struct semid64_ds so do not copy the 32-bit lower and upper half time.
Signed-off-by: Amit Daniel Kachhap amit.kachhap@arm.com --- ipc/sem.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/ipc/sem.c b/ipc/sem.c index 9f10259ce08b..3bf64f2a26f5 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -1756,10 +1756,15 @@ static int copy_compat_semid_to_user(void __user *buf, struct semid64_ds *in, struct compat_semid64_ds v; memset(&v, 0, sizeof(v)); to_compat_ipc64_perm(&v.sem_perm, &in->sem_perm); +#ifdef CONFIG_COMPAT64 + v.sem_otime = in->sem_otime; + v.sem_ctime = in->sem_ctime; +#else v.sem_otime = lower_32_bits(in->sem_otime); v.sem_otime_high = upper_32_bits(in->sem_otime); v.sem_ctime = lower_32_bits(in->sem_ctime); v.sem_ctime_high = upper_32_bits(in->sem_ctime); +#endif v.sem_nsems = in->sem_nsems; return copy_to_user(buf, &v, sizeof(v)); } else { @@ -1773,7 +1778,7 @@ static int copy_compat_semid_to_user(void __user *buf, struct semid64_ds *in, } }
-static long compat_ksys_semctl(int semid, int semnum, int cmd, int arg, int version) +static long compat_ksys_semctl(int semid, int semnum, int cmd, compat_ulong_t arg, int version) { void __user *p = compat_ptr(arg); struct ipc_namespace *ns; @@ -1818,7 +1823,7 @@ static long compat_ksys_semctl(int semid, int semnum, int cmd, int arg, int vers } }
-COMPAT_SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, int, arg) +COMPAT_SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, compat_ulong_t, arg) { return compat_ksys_semctl(semid, semnum, cmd, arg, IPC_64); }