[SSI] openssi/kernel/ipc shm.c,1.30,1.31

Roger Tsang <[email protected]> Mon, 15 Mar 2010 00:55:20 +0000
Newsgroups gmane.linux.cluster.ssic.cvs
Message-ID <[email protected]>
Update of /cvsroot/ssic-linux/openssi/kernel/ipc
In directory sfp-cvsdas-3.v30.ch3.sourceforge.com:/tmp/cvs-serv25859/kernel/ipc

Modified Files:
      Tag: OPENSSI-FC
	shm.c 
Log Message:
IPC (#ifdef IPC_SHM_RACE_FIX):
- Fix do_shmat() assigning pointer to invalid vfsmount structure if raced with ipc_shm_nodedown().
- Fix duplicate ipc free or ipc leak if shm_destroy() raced with do_shmat() while calling ipc_rcu_putref().


Index: shm.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/ipc/shm.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- shm.c	7 Mar 2010 06:00:28 -0000	1.30
+++ shm.c	15 Mar 2010 00:55:17 -0000	1.31
@@ -238,7 +238,17 @@
 						shp->mlock_user);
 	fput (shp->shm_file);
 	security_shm_free(shp);
+#ifdef CONFIG_SSI
+#ifdef IPC_SHM_RACE_FIX
+	ipc_lock_by_ptr(&shp->shm_perm);
+	ipc_rcu_putref(shp);
+	shm_unlock(shp);
+#else
 	ipc_rcu_putref(shp);
+#endif
+#else
+	ipc_rcu_putref(shp);
+#endif /* !CONFIG_SSI */
 }
 
 /*
@@ -1091,7 +1101,7 @@
 			struct vfsmount *new_mnt=NULL;
 #else
 			struct dentry *old_dentry = NULL;
-			struct vfsmount *old_mnt = NULL;
+			struct vfsmount *new_mnt, *old_mnt = NULL;
 
 			ipc_rcu_getref(shp);
 #endif /* IPC_SHM_RACE_FIX */
@@ -1126,23 +1136,40 @@
 				goto cont;
 			}
 
+#ifdef IPC_SHM_RACE_FIX
 			if (de) {
+				read_lock(&cfs_shm_node_mnts_lock);
+				new_mnt = mntget(
+					cfs_shm_node_mnts[shp->shm_node]);
+				read_unlock(&cfs_shm_node_mnts_lock);
+			} else
+				new_mnt = NULL;
+
+			if (new_mnt) {
 				/* switch file to cfs and cleanup */
-#ifdef IPC_SHM_RACE_FIX
 				old_dentry = shp->shm_file->f_dentry;
 				shp->shm_file->f_dentry = de;
-
 				old_mnt = shp->shm_file->f_vfsmnt;
-				shp->shm_file->f_vfsmnt = mntget(
-					cfs_shm_node_mnts[shp->shm_node]);
+				shp->shm_file->f_vfsmnt = new_mnt;
+				shp->shm_file->f_op = &cfs_shm_file_operations;
+				shp->shm_file->f_mapping =
+						de->d_inode->i_mapping;
+			} else {
+				ssi_local_destroy(shp);
+				up(&shm_ids.sem);
+				if (de)
+					dput(de);
+				return -EINVAL;
+			}
 #else
+			if (de) {
+				/* switch file to cfs and cleanup */
 				dput(shp->shm_file->f_dentry);
 				mntput(shp->shm_file->f_vfsmnt);
 				new_mnt = (struct vfsmount *)
 					cfs_shm_node_mnts[shp->shm_node];
 				shp->shm_file->f_dentry = de;
 				shp->shm_file->f_vfsmnt = mntget(new_mnt);
-#endif
 				shp->shm_file->f_op = &cfs_shm_file_operations;
 				shp->shm_file->f_mapping =
 						de->d_inode->i_mapping;
@@ -1152,6 +1179,7 @@
 				up(&shm_ids.sem);
 				return -EINVAL;
 			}
+#endif /* !IPC_SHM_RACE_FIX */
 cont:
 			up(&shm_ids.sem);
 #ifdef IPC_SHM_RACE_FIX


------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev