aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorWaiman Long <Waiman.Long@hp.com>2014-06-23 11:28:51 -0400
committerPaul Moore <pmoore@redhat.com>2014-06-23 16:52:55 -0400
commitf31e799459659ae88c341aeac16a8a5efb1271d4 (patch)
tree912cc7f6dd3350c32501a344cf438f7ec2269c72 /security
parent6e51f9cbfa04a92b40e7f9c1e76c8ecbff534a22 (diff)
selinux: no recursive read_lock of policy_rwlock in security_genfs_sid()
With the introduction of fair queued rwlock, recursive read_lock() may hang the offending process if there is a write_lock() somewhere in between. With recursive read_lock checking enabled, the following error was reported: ============================================= [ INFO: possible recursive locking detected ] 3.16.0-rc1 #2 Tainted: G E --------------------------------------------- load_policy/708 is trying to acquire lock: (policy_rwlock){.+.+..}, at: [<ffffffff8125b32a>] security_genfs_sid+0x3a/0x170 but task is already holding lock: (policy_rwlock){.+.+..}, at: [<ffffffff8125b48c>] security_fs_use+0x2c/0x110 other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(policy_rwlock); lock(policy_rwlock); This patch fixes the occurrence of recursive read_lock() of policy_rwlock by adding a helper function __security_genfs_sid() which requires caller to take the lock before calling it. The security_fs_use() was then modified to call the new helper function. Signed-off-by: Waiman Long <Waiman.Long@hp.com> Acked-by: Stephen Smalley <sds@tycho.nsa.gov> Signed-off-by: Paul Moore <pmoore@redhat.com>
Diffstat (limited to 'security')
-rw-r--r--security/selinux/ss/services.c41
1 files changed, 32 insertions, 9 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 4bca49414a40..2aa9d172dc7e 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -2277,7 +2277,7 @@ out:
2277} 2277}
2278 2278
2279/** 2279/**
2280 * security_genfs_sid - Obtain a SID for a file in a filesystem 2280 * __security_genfs_sid - Helper to obtain a SID for a file in a filesystem
2281 * @fstype: filesystem type 2281 * @fstype: filesystem type
2282 * @path: path from root of mount 2282 * @path: path from root of mount
2283 * @sclass: file security class 2283 * @sclass: file security class
@@ -2286,11 +2286,13 @@ out:
2286 * Obtain a SID to use for a file in a filesystem that 2286 * Obtain a SID to use for a file in a filesystem that
2287 * cannot support xattr or use a fixed labeling behavior like 2287 * cannot support xattr or use a fixed labeling behavior like
2288 * transition SIDs or task SIDs. 2288 * transition SIDs or task SIDs.
2289 *
2290 * The caller must acquire the policy_rwlock before calling this function.
2289 */ 2291 */
2290int security_genfs_sid(const char *fstype, 2292static inline int __security_genfs_sid(const char *fstype,
2291 char *path, 2293 char *path,
2292 u16 orig_sclass, 2294 u16 orig_sclass,
2293 u32 *sid) 2295 u32 *sid)
2294{ 2296{
2295 int len; 2297 int len;
2296 u16 sclass; 2298 u16 sclass;
@@ -2301,8 +2303,6 @@ int security_genfs_sid(const char *fstype,
2301 while (path[0] == '/' && path[1] == '/') 2303 while (path[0] == '/' && path[1] == '/')
2302 path++; 2304 path++;
2303 2305
2304 read_lock(&policy_rwlock);
2305
2306 sclass = unmap_class(orig_sclass); 2306 sclass = unmap_class(orig_sclass);
2307 *sid = SECINITSID_UNLABELED; 2307 *sid = SECINITSID_UNLABELED;
2308 2308
@@ -2336,11 +2336,33 @@ int security_genfs_sid(const char *fstype,
2336 *sid = c->sid[0]; 2336 *sid = c->sid[0];
2337 rc = 0; 2337 rc = 0;
2338out: 2338out:
2339 read_unlock(&policy_rwlock);
2340 return rc; 2339 return rc;
2341} 2340}
2342 2341
2343/** 2342/**
2343 * security_genfs_sid - Obtain a SID for a file in a filesystem
2344 * @fstype: filesystem type
2345 * @path: path from root of mount
2346 * @sclass: file security class
2347 * @sid: SID for path
2348 *
2349 * Acquire policy_rwlock before calling __security_genfs_sid() and release
2350 * it afterward.
2351 */
2352int security_genfs_sid(const char *fstype,
2353 char *path,
2354 u16 orig_sclass,
2355 u32 *sid)
2356{
2357 int retval;
2358
2359 read_lock(&policy_rwlock);
2360 retval = __security_genfs_sid(fstype, path, orig_sclass, sid);
2361 read_unlock(&policy_rwlock);
2362 return retval;
2363}
2364
2365/**
2344 * security_fs_use - Determine how to handle labeling for a filesystem. 2366 * security_fs_use - Determine how to handle labeling for a filesystem.
2345 * @sb: superblock in question 2367 * @sb: superblock in question
2346 */ 2368 */
@@ -2370,7 +2392,8 @@ int security_fs_use(struct super_block *sb)
2370 } 2392 }
2371 sbsec->sid = c->sid[0]; 2393 sbsec->sid = c->sid[0];
2372 } else { 2394 } else {
2373 rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, &sbsec->sid); 2395 rc = __security_genfs_sid(fstype, "/", SECCLASS_DIR,
2396 &sbsec->sid);
2374 if (rc) { 2397 if (rc) {
2375 sbsec->behavior = SECURITY_FS_USE_NONE; 2398 sbsec->behavior = SECURITY_FS_USE_NONE;
2376 rc = 0; 2399 rc = 0;