diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 35eb8de892fc..118ddfb614ee 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -1423,6 +1423,41 @@ static int selinux_capable(struct task_struct *tsk, int cap) | |||
1423 | return task_has_capability(tsk,cap); | 1423 | return task_has_capability(tsk,cap); |
1424 | } | 1424 | } |
1425 | 1425 | ||
1426 | static int selinux_sysctl_get_sid(ctl_table *table, u16 tclass, u32 *sid) | ||
1427 | { | ||
1428 | int buflen, rc; | ||
1429 | char *buffer, *path, *end; | ||
1430 | |||
1431 | rc = -ENOMEM; | ||
1432 | buffer = (char*)__get_free_page(GFP_KERNEL); | ||
1433 | if (!buffer) | ||
1434 | goto out; | ||
1435 | |||
1436 | buflen = PAGE_SIZE; | ||
1437 | end = buffer+buflen; | ||
1438 | *--end = '\0'; | ||
1439 | buflen--; | ||
1440 | path = end-1; | ||
1441 | *path = '/'; | ||
1442 | while (table) { | ||
1443 | const char *name = table->procname; | ||
1444 | size_t namelen = strlen(name); | ||
1445 | buflen -= namelen + 1; | ||
1446 | if (buflen < 0) | ||
1447 | goto out_free; | ||
1448 | end -= namelen; | ||
1449 | memcpy(end, name, namelen); | ||
1450 | *--end = '/'; | ||
1451 | path = end; | ||
1452 | table = table->parent; | ||
1453 | } | ||
1454 | rc = security_genfs_sid("proc", path, tclass, sid); | ||
1455 | out_free: | ||
1456 | free_page((unsigned long)buffer); | ||
1457 | out: | ||
1458 | return rc; | ||
1459 | } | ||
1460 | |||
1426 | static int selinux_sysctl(ctl_table *table, int op) | 1461 | static int selinux_sysctl(ctl_table *table, int op) |
1427 | { | 1462 | { |
1428 | int error = 0; | 1463 | int error = 0; |
@@ -1437,8 +1472,8 @@ static int selinux_sysctl(ctl_table *table, int op) | |||
1437 | 1472 | ||
1438 | tsec = current->security; | 1473 | tsec = current->security; |
1439 | 1474 | ||
1440 | rc = selinux_proc_get_sid(table->de, (op == 001) ? | 1475 | rc = selinux_sysctl_get_sid(table, (op == 0001) ? |
1441 | SECCLASS_DIR : SECCLASS_FILE, &tsid); | 1476 | SECCLASS_DIR : SECCLASS_FILE, &tsid); |
1442 | if (rc) { | 1477 | if (rc) { |
1443 | /* Default to the well-defined sysctl SID. */ | 1478 | /* Default to the well-defined sysctl SID. */ |
1444 | tsid = SECINITSID_SYSCTL; | 1479 | tsid = SECINITSID_SYSCTL; |