diff options
Diffstat (limited to 'security/selinux/ss/services.c')
| -rw-r--r-- | security/selinux/ss/services.c | 66 |
1 files changed, 50 insertions, 16 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index b4feecc3fe01..ee470a0b5c27 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
| @@ -72,6 +72,7 @@ | |||
| 72 | 72 | ||
| 73 | int selinux_policycap_netpeer; | 73 | int selinux_policycap_netpeer; |
| 74 | int selinux_policycap_openperm; | 74 | int selinux_policycap_openperm; |
| 75 | int selinux_policycap_alwaysnetwork; | ||
| 75 | 76 | ||
| 76 | static DEFINE_RWLOCK(policy_rwlock); | 77 | static DEFINE_RWLOCK(policy_rwlock); |
| 77 | 78 | ||
| @@ -1812,6 +1813,8 @@ static void security_load_policycaps(void) | |||
| 1812 | POLICYDB_CAPABILITY_NETPEER); | 1813 | POLICYDB_CAPABILITY_NETPEER); |
| 1813 | selinux_policycap_openperm = ebitmap_get_bit(&policydb.policycaps, | 1814 | selinux_policycap_openperm = ebitmap_get_bit(&policydb.policycaps, |
| 1814 | POLICYDB_CAPABILITY_OPENPERM); | 1815 | POLICYDB_CAPABILITY_OPENPERM); |
| 1816 | selinux_policycap_alwaysnetwork = ebitmap_get_bit(&policydb.policycaps, | ||
| 1817 | POLICYDB_CAPABILITY_ALWAYSNETWORK); | ||
| 1815 | } | 1818 | } |
| 1816 | 1819 | ||
| 1817 | static int security_preserve_bools(struct policydb *p); | 1820 | static int security_preserve_bools(struct policydb *p); |
| @@ -2323,43 +2326,74 @@ out: | |||
| 2323 | 2326 | ||
| 2324 | /** | 2327 | /** |
| 2325 | * security_fs_use - Determine how to handle labeling for a filesystem. | 2328 | * security_fs_use - Determine how to handle labeling for a filesystem. |
| 2326 | * @fstype: filesystem type | 2329 | * @sb: superblock in question |
| 2327 | * @behavior: labeling behavior | ||
| 2328 | * @sid: SID for filesystem (superblock) | ||
| 2329 | */ | 2330 | */ |
| 2330 | int security_fs_use( | 2331 | int security_fs_use(struct super_block *sb) |
| 2331 | const char *fstype, | ||
| 2332 | unsigned int *behavior, | ||
| 2333 | u32 *sid) | ||
| 2334 | { | 2332 | { |
| 2335 | int rc = 0; | 2333 | int rc = 0; |
| 2336 | struct ocontext *c; | 2334 | struct ocontext *c; |
| 2335 | struct superblock_security_struct *sbsec = sb->s_security; | ||
| 2336 | const char *fstype = sb->s_type->name; | ||
| 2337 | const char *subtype = (sb->s_subtype && sb->s_subtype[0]) ? sb->s_subtype : NULL; | ||
| 2338 | struct ocontext *base = NULL; | ||
| 2337 | 2339 | ||
| 2338 | read_lock(&policy_rwlock); | 2340 | read_lock(&policy_rwlock); |
| 2339 | 2341 | ||
| 2340 | c = policydb.ocontexts[OCON_FSUSE]; | 2342 | for (c = policydb.ocontexts[OCON_FSUSE]; c; c = c->next) { |
| 2341 | while (c) { | 2343 | char *sub; |
| 2342 | if (strcmp(fstype, c->u.name) == 0) | 2344 | int baselen; |
| 2345 | |||
| 2346 | baselen = strlen(fstype); | ||
| 2347 | |||
| 2348 | /* if base does not match, this is not the one */ | ||
| 2349 | if (strncmp(fstype, c->u.name, baselen)) | ||
| 2350 | continue; | ||
| 2351 | |||
| 2352 | /* if there is no subtype, this is the one! */ | ||
| 2353 | if (!subtype) | ||
| 2354 | break; | ||
| 2355 | |||
| 2356 | /* skip past the base in this entry */ | ||
| 2357 | sub = c->u.name + baselen; | ||
| 2358 | |||
| 2359 | /* entry is only a base. save it. keep looking for subtype */ | ||
| 2360 | if (sub[0] == '\0') { | ||
| 2361 | base = c; | ||
| 2362 | continue; | ||
| 2363 | } | ||
| 2364 | |||
| 2365 | /* entry is not followed by a subtype, so it is not a match */ | ||
| 2366 | if (sub[0] != '.') | ||
| 2367 | continue; | ||
| 2368 | |||
| 2369 | /* whew, we found a subtype of this fstype */ | ||
| 2370 | sub++; /* move past '.' */ | ||
| 2371 | |||
| 2372 | /* exact match of fstype AND subtype */ | ||
| 2373 | if (!strcmp(subtype, sub)) | ||
| 2343 | break; | 2374 | break; |
| 2344 | c = c->next; | ||
| 2345 | } | 2375 | } |
| 2346 | 2376 | ||
| 2377 | /* in case we had found an fstype match but no subtype match */ | ||
| 2378 | if (!c) | ||
| 2379 | c = base; | ||
| 2380 | |||
| 2347 | if (c) { | 2381 | if (c) { |
| 2348 | *behavior = c->v.behavior; | 2382 | sbsec->behavior = c->v.behavior; |
| 2349 | if (!c->sid[0]) { | 2383 | if (!c->sid[0]) { |
| 2350 | rc = sidtab_context_to_sid(&sidtab, &c->context[0], | 2384 | rc = sidtab_context_to_sid(&sidtab, &c->context[0], |
| 2351 | &c->sid[0]); | 2385 | &c->sid[0]); |
| 2352 | if (rc) | 2386 | if (rc) |
| 2353 | goto out; | 2387 | goto out; |
| 2354 | } | 2388 | } |
| 2355 | *sid = c->sid[0]; | 2389 | sbsec->sid = c->sid[0]; |
| 2356 | } else { | 2390 | } else { |
| 2357 | rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, sid); | 2391 | rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, &sbsec->sid); |
| 2358 | if (rc) { | 2392 | if (rc) { |
| 2359 | *behavior = SECURITY_FS_USE_NONE; | 2393 | sbsec->behavior = SECURITY_FS_USE_NONE; |
| 2360 | rc = 0; | 2394 | rc = 0; |
| 2361 | } else { | 2395 | } else { |
| 2362 | *behavior = SECURITY_FS_USE_GENFS; | 2396 | sbsec->behavior = SECURITY_FS_USE_GENFS; |
| 2363 | } | 2397 | } |
| 2364 | } | 2398 | } |
| 2365 | 2399 | ||
