Currently, we check shm security only under RCU. Since selinuxActually: either kern_ipc_perm or down_xx(&shm_ids(ns).rwsem) is sufficient.
can free the security structure, through selinux_sem_free_security(),
we can run into a use-after-free condition. This bug affects both
shmctl and shmat syscalls.
The fix is obvious, make sure we hold the kern_ipc_perm.lock while
performing these security checks.
This change is not necessary: down_write(shm_ids(ns).rwsem) already synchronizes against another IPC_RMID.
Reported-by: Manfred Spraul <manfred@xxxxxxxxxxxxxxxx>
Signed-off-by: Davidlohr Bueso <davidlohr@xxxxxx>
---
ipc/shm.c | 23 ++++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/ipc/shm.c b/ipc/shm.c
index 2821cdf..bc3e897 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -781,18 +781,17 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd,
shp = container_of(ipcp, struct shmid_kernel, shm_perm);
+ ipc_lock_object(&shp->shm_perm);
err = security_shm_shmctl(shp, cmd);
if (err)
- goto out_unlock1;
+ goto out_unlock0;
@@ -960,11 +962,12 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)What about audit_ipc_obj()?
}
audit_ipc_obj(&(shp->shm_perm));
+
+ ipc_lock_object(&shp->shm_perm);
err = security_shm_shmctl(shp, cmd);