close race condition in shared memory mapping/unmapping
PATCH 1/1 close race condition in shared memory mapping/unmapping
Hey all-
Found this the other day poking through the ipc code. There appears to
be a race condition in the counter that records how many processes are accessing a given shared memory segment. In most places the shm_nattch variable is protected by the shm_ids.sem semaphore, but there are a few openings which appear to be able to allow a corruption of this variable when run on SMP systems. I've attached a patch to 2.6.9-rc2 for review.
The locking may be a little over-aggressive (I was following examples
from other points in this file), but I figure better safe than sorry :).
Anywho, here it is.
Thanks
Neil
Signature · 8 lines
/*************************************************** *Neil Horman *Software Engineer *Red Hat, Inc. *[email protected] *gpg keyid: 1024D / 0x92A74FA1 *http://pgp.mit.edu ***************************************************/
ipc/shm.c renamed from ipc/shm.c.orig +9 -0
@@ -86,12 +86,14 @@static inline void shm_inc (int id) {struct shmid_kernel *shp; +down (&shm_ids.sem);if (!(shp =shm_lock (id)))BUG (); shp->shm_atim =get_seconds (); shp->shm_lprid = current->tgid; shp->shm_nattch++;shm_unlock (shp); +up (&shm_ids.sem); }/* This is called by fork, once for every shm attach. */
@@ -697,18 +699,23 @@* We cannot rely on the fs check since SYSV IPC does have an * additional creator id... */ +down (&shm_ids.sem); shp =shm_lock (shmid);if (shp ==NULL ) { +shm_unlock (shp); +up (&shm_ids.sem); err = -EINVAL ; goto out; } err =shm_checkid (shp,shmid);if (err) {shm_unlock (shp); +up (&shm_ids.sem); goto out; }if (ipcperms (&shp->shm_perm, acc_mode)) {shm_unlock (shp); +up (&shm_ids.sem); err = -EACCES ; goto out; }
@@ -716,6 +723,7 @@ err =security_shm_shmat (shp, shmaddr, shmflg);if (err) {shm_unlock (shp); +up (&shm_ids.sem);return err; }
@@ -723,6 +731,7 @@ size =i_size_read (file->f_dentry->d_inode); shp->shm_nattch++;shm_unlock (shp); +up (&shm_ids.sem);down_write (¤t->mm->mmap_sem);if (addr && !(shmflg &SHM_REMAP )) {
Hi Neil,
ipc/shm.c line 709
Quoted 8 lines · Neil Horman
ipc/shm.c renamed from ipc/shm.c.orig +3
-0+down (&shm_ids.sem); shp =shm_lock (shmid);if (shp ==NULL ) { +shm_unlock (shp); +up (&shm_ids.sem); err = -EINVAL ; goto out; }
Trying to unlock a NULL pointer?
Cheers,
Felipe
Quoted 14 lines · Felipe W Damasio
Hi Neil,
ipc/shm.c line 709
Quoted 8 lines · Neil Horman
ipc/shm.c renamed from ipc/shm.c.orig +3
-0+down (&shm_ids.sem); shp =shm_lock (shmid);if (shp ==NULL ) { +shm_unlock (shp); +up (&shm_ids.sem); err = -EINVAL ; goto out; }
Quoted 5 lines
Trying to unlock a NULL pointer?
Cheers,
Felipe
Crap, good catch. I'll repost with that fixed. Anything else you see a problem with? Regards
Neil
Signature · 8 lines
/*************************************************** *Neil Horman *Software Engineer *Red Hat, Inc. *[email protected] *gpg keyid: 1024D / 0x92A74FA1 *http://pgp.mit.edu ***************************************************/
Quoted 9 lines · * Neil Horman ([email protected]) wrote:
Hey all-
Found this the other day poking through the ipc code. There appears to
be a race condition in the counter that records how many processes are accessing a given shared memory segment. In most places theshm_nattchvariable is protected by the shm_ids.sem semaphore, but there are a few openings which appear to be able to allow a corruption of this variable when run on SMP systems. I've attached a patch to 2.6.9-rc2 for review.
The locking may be a little over-aggressive (I was following examples
from other points in this file), but I figure better safe than sorry :).
Are you sure you've got this right? I thought that the shmid_kernel struct protects shm_nattch with a local (per structure) lock which is embedded in kern_ipc_perm. Did you find shm_nattch changes w/out shm_lock/shm_unlock around it? I believe shm_ids.sem is protecting the id allocation, not per object data such as shm_nattch.
thanks,
-chris
Signature · 1 line
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net
Quoted 9 lines · Chris Wright
Quoted 5 lines · * Neil Horman ([email protected]) wrote:
Hey all-
Found this the other day poking through the ipc code. There appears to
be a race condition in the counter that records how many processes are accessing a given shared memory segment. In most places theshm_nattchvariable is protected by the shm_ids.sem semaphore, but there are a few openings which appear to be able to allow a corruption of this variable when run on SMP systems. I've attached a patch to 2.6.9-rc2 for review.
The locking may be a little over-aggressive (I was following examples
from other points in this file), but I figure better safe than sorry :).
Quoted 8 lines
Are you sure you've got this right? I thought that the
shmid_kernelstruct protectsshm_nattchwith a local (per structure) lock which is embedded inkern_ipc_perm. Did you findshm_nattchchanges w/out shm_lock/shm_unlock around it? I believe shm_ids.sem is protecting the id allocation, not per object data such asshm_nattch.thanks,
-chris
You're right, its not correct. I'm sorry. I'm looking into a locking bug in 2.4, which does its ipc locking for shared memory very differently. Since the shared memory code looks simmilar in 2.6, I was making the assumption that the change applied upstram as well, but I don't think thats the case after looking more carefully. My bad. Neil
Signature · 8 lines
/*************************************************** *Neil Horman *Software Engineer *Red Hat, Inc. *[email protected] *gpg keyid: 1024D / 0x92A74FA1 *http://pgp.mit.edu ***************************************************/