diff options
Diffstat (limited to 'ipc/shm.c')
-rw-r--r-- | ipc/shm.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/ipc/shm.c b/ipc/shm.c index 00faa05cf72a..dff40c9f73c9 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -758,7 +758,9 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd, do_shm_rmid(ns, ipcp); goto out_up; case IPC_SET: - ipc_update_perm(&shmid64.shm_perm, ipcp); + err = ipc_update_perm(&shmid64.shm_perm, ipcp); + if (err) + goto out_unlock; shp->shm_ctim = get_seconds(); break; default: @@ -893,10 +895,10 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) audit_ipc_obj(&(shp->shm_perm)); if (!ns_capable(ns->user_ns, CAP_IPC_LOCK)) { - uid_t euid = current_euid(); + kuid_t euid = current_euid(); err = -EPERM; - if (euid != shp->shm_perm.uid && - euid != shp->shm_perm.cuid) + if (!uid_eq(euid, shp->shm_perm.uid) && + !uid_eq(euid, shp->shm_perm.cuid)) goto out_unlock; if (cmd == SHM_LOCK && !rlimit(RLIMIT_MEMLOCK)) goto out_unlock; @@ -1220,6 +1222,7 @@ SYSCALL_DEFINE1(shmdt, char __user *, shmaddr) #ifdef CONFIG_PROC_FS static int sysvipc_shm_proc_show(struct seq_file *s, void *it) { + struct user_namespace *user_ns = seq_user_ns(s); struct shmid_kernel *shp = it; unsigned long rss = 0, swp = 0; @@ -1242,10 +1245,10 @@ static int sysvipc_shm_proc_show(struct seq_file *s, void *it) shp->shm_cprid, shp->shm_lprid, shp->shm_nattch, - shp->shm_perm.uid, - shp->shm_perm.gid, - shp->shm_perm.cuid, - shp->shm_perm.cgid, + from_kuid_munged(user_ns, shp->shm_perm.uid), + from_kgid_munged(user_ns, shp->shm_perm.gid), + from_kuid_munged(user_ns, shp->shm_perm.cuid), + from_kgid_munged(user_ns, shp->shm_perm.cgid), shp->shm_atim, shp->shm_dtim, shp->shm_ctim, |