diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 394 |
1 files changed, 197 insertions, 197 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index c7c6619431d5..0a4b4b040e0a 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -210,16 +210,6 @@ static inline u32 task_sid(const struct task_struct *task) | |||
210 | return sid; | 210 | return sid; |
211 | } | 211 | } |
212 | 212 | ||
213 | /* | ||
214 | * get the subjective security ID of the current task | ||
215 | */ | ||
216 | static inline u32 current_sid(void) | ||
217 | { | ||
218 | const struct task_security_struct *tsec = current_security(); | ||
219 | |||
220 | return tsec->sid; | ||
221 | } | ||
222 | |||
223 | /* Allocate and free functions for each kind of security blob. */ | 213 | /* Allocate and free functions for each kind of security blob. */ |
224 | 214 | ||
225 | static int inode_alloc_security(struct inode *inode) | 215 | static int inode_alloc_security(struct inode *inode) |
@@ -492,7 +482,11 @@ static int selinux_is_sblabel_mnt(struct super_block *sb) | |||
492 | !strcmp(sb->s_type->name, "sysfs") || | 482 | !strcmp(sb->s_type->name, "sysfs") || |
493 | !strcmp(sb->s_type->name, "pstore") || | 483 | !strcmp(sb->s_type->name, "pstore") || |
494 | !strcmp(sb->s_type->name, "debugfs") || | 484 | !strcmp(sb->s_type->name, "debugfs") || |
495 | !strcmp(sb->s_type->name, "rootfs"); | 485 | !strcmp(sb->s_type->name, "tracefs") || |
486 | !strcmp(sb->s_type->name, "rootfs") || | ||
487 | (selinux_policycap_cgroupseclabel && | ||
488 | (!strcmp(sb->s_type->name, "cgroup") || | ||
489 | !strcmp(sb->s_type->name, "cgroup2"))); | ||
496 | } | 490 | } |
497 | 491 | ||
498 | static int sb_finish_set_opts(struct super_block *sb) | 492 | static int sb_finish_set_opts(struct super_block *sb) |
@@ -833,10 +827,14 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
833 | } | 827 | } |
834 | 828 | ||
835 | /* | 829 | /* |
836 | * If this is a user namespace mount, no contexts are allowed | 830 | * If this is a user namespace mount and the filesystem type is not |
837 | * on the command line and security labels must be ignored. | 831 | * explicitly whitelisted, then no contexts are allowed on the command |
832 | * line and security labels must be ignored. | ||
838 | */ | 833 | */ |
839 | if (sb->s_user_ns != &init_user_ns) { | 834 | if (sb->s_user_ns != &init_user_ns && |
835 | strcmp(sb->s_type->name, "tmpfs") && | ||
836 | strcmp(sb->s_type->name, "ramfs") && | ||
837 | strcmp(sb->s_type->name, "devpts")) { | ||
840 | if (context_sid || fscontext_sid || rootcontext_sid || | 838 | if (context_sid || fscontext_sid || rootcontext_sid || |
841 | defcontext_sid) { | 839 | defcontext_sid) { |
842 | rc = -EACCES; | 840 | rc = -EACCES; |
@@ -1268,6 +1266,8 @@ static inline int default_protocol_dgram(int protocol) | |||
1268 | 1266 | ||
1269 | static inline u16 socket_type_to_security_class(int family, int type, int protocol) | 1267 | static inline u16 socket_type_to_security_class(int family, int type, int protocol) |
1270 | { | 1268 | { |
1269 | int extsockclass = selinux_policycap_extsockclass; | ||
1270 | |||
1271 | switch (family) { | 1271 | switch (family) { |
1272 | case PF_UNIX: | 1272 | case PF_UNIX: |
1273 | switch (type) { | 1273 | switch (type) { |
@@ -1282,13 +1282,19 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc | |||
1282 | case PF_INET6: | 1282 | case PF_INET6: |
1283 | switch (type) { | 1283 | switch (type) { |
1284 | case SOCK_STREAM: | 1284 | case SOCK_STREAM: |
1285 | case SOCK_SEQPACKET: | ||
1285 | if (default_protocol_stream(protocol)) | 1286 | if (default_protocol_stream(protocol)) |
1286 | return SECCLASS_TCP_SOCKET; | 1287 | return SECCLASS_TCP_SOCKET; |
1288 | else if (extsockclass && protocol == IPPROTO_SCTP) | ||
1289 | return SECCLASS_SCTP_SOCKET; | ||
1287 | else | 1290 | else |
1288 | return SECCLASS_RAWIP_SOCKET; | 1291 | return SECCLASS_RAWIP_SOCKET; |
1289 | case SOCK_DGRAM: | 1292 | case SOCK_DGRAM: |
1290 | if (default_protocol_dgram(protocol)) | 1293 | if (default_protocol_dgram(protocol)) |
1291 | return SECCLASS_UDP_SOCKET; | 1294 | return SECCLASS_UDP_SOCKET; |
1295 | else if (extsockclass && (protocol == IPPROTO_ICMP || | ||
1296 | protocol == IPPROTO_ICMPV6)) | ||
1297 | return SECCLASS_ICMP_SOCKET; | ||
1292 | else | 1298 | else |
1293 | return SECCLASS_RAWIP_SOCKET; | 1299 | return SECCLASS_RAWIP_SOCKET; |
1294 | case SOCK_DCCP: | 1300 | case SOCK_DCCP: |
@@ -1342,6 +1348,68 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc | |||
1342 | return SECCLASS_APPLETALK_SOCKET; | 1348 | return SECCLASS_APPLETALK_SOCKET; |
1343 | } | 1349 | } |
1344 | 1350 | ||
1351 | if (extsockclass) { | ||
1352 | switch (family) { | ||
1353 | case PF_AX25: | ||
1354 | return SECCLASS_AX25_SOCKET; | ||
1355 | case PF_IPX: | ||
1356 | return SECCLASS_IPX_SOCKET; | ||
1357 | case PF_NETROM: | ||
1358 | return SECCLASS_NETROM_SOCKET; | ||
1359 | case PF_ATMPVC: | ||
1360 | return SECCLASS_ATMPVC_SOCKET; | ||
1361 | case PF_X25: | ||
1362 | return SECCLASS_X25_SOCKET; | ||
1363 | case PF_ROSE: | ||
1364 | return SECCLASS_ROSE_SOCKET; | ||
1365 | case PF_DECnet: | ||
1366 | return SECCLASS_DECNET_SOCKET; | ||
1367 | case PF_ATMSVC: | ||
1368 | return SECCLASS_ATMSVC_SOCKET; | ||
1369 | case PF_RDS: | ||
1370 | return SECCLASS_RDS_SOCKET; | ||
1371 | case PF_IRDA: | ||
1372 | return SECCLASS_IRDA_SOCKET; | ||
1373 | case PF_PPPOX: | ||
1374 | return SECCLASS_PPPOX_SOCKET; | ||
1375 | case PF_LLC: | ||
1376 | return SECCLASS_LLC_SOCKET; | ||
1377 | case PF_CAN: | ||
1378 | return SECCLASS_CAN_SOCKET; | ||
1379 | case PF_TIPC: | ||
1380 | return SECCLASS_TIPC_SOCKET; | ||
1381 | case PF_BLUETOOTH: | ||
1382 | return SECCLASS_BLUETOOTH_SOCKET; | ||
1383 | case PF_IUCV: | ||
1384 | return SECCLASS_IUCV_SOCKET; | ||
1385 | case PF_RXRPC: | ||
1386 | return SECCLASS_RXRPC_SOCKET; | ||
1387 | case PF_ISDN: | ||
1388 | return SECCLASS_ISDN_SOCKET; | ||
1389 | case PF_PHONET: | ||
1390 | return SECCLASS_PHONET_SOCKET; | ||
1391 | case PF_IEEE802154: | ||
1392 | return SECCLASS_IEEE802154_SOCKET; | ||
1393 | case PF_CAIF: | ||
1394 | return SECCLASS_CAIF_SOCKET; | ||
1395 | case PF_ALG: | ||
1396 | return SECCLASS_ALG_SOCKET; | ||
1397 | case PF_NFC: | ||
1398 | return SECCLASS_NFC_SOCKET; | ||
1399 | case PF_VSOCK: | ||
1400 | return SECCLASS_VSOCK_SOCKET; | ||
1401 | case PF_KCM: | ||
1402 | return SECCLASS_KCM_SOCKET; | ||
1403 | case PF_QIPCRTR: | ||
1404 | return SECCLASS_QIPCRTR_SOCKET; | ||
1405 | case PF_SMC: | ||
1406 | return SECCLASS_SMC_SOCKET; | ||
1407 | #if PF_MAX > 44 | ||
1408 | #error New address family defined, please update this function. | ||
1409 | #endif | ||
1410 | } | ||
1411 | } | ||
1412 | |||
1345 | return SECCLASS_SOCKET; | 1413 | return SECCLASS_SOCKET; |
1346 | } | 1414 | } |
1347 | 1415 | ||
@@ -1608,55 +1676,6 @@ static inline u32 signal_to_av(int sig) | |||
1608 | return perm; | 1676 | return perm; |
1609 | } | 1677 | } |
1610 | 1678 | ||
1611 | /* | ||
1612 | * Check permission between a pair of credentials | ||
1613 | * fork check, ptrace check, etc. | ||
1614 | */ | ||
1615 | static int cred_has_perm(const struct cred *actor, | ||
1616 | const struct cred *target, | ||
1617 | u32 perms) | ||
1618 | { | ||
1619 | u32 asid = cred_sid(actor), tsid = cred_sid(target); | ||
1620 | |||
1621 | return avc_has_perm(asid, tsid, SECCLASS_PROCESS, perms, NULL); | ||
1622 | } | ||
1623 | |||
1624 | /* | ||
1625 | * Check permission between a pair of tasks, e.g. signal checks, | ||
1626 | * fork check, ptrace check, etc. | ||
1627 | * tsk1 is the actor and tsk2 is the target | ||
1628 | * - this uses the default subjective creds of tsk1 | ||
1629 | */ | ||
1630 | static int task_has_perm(const struct task_struct *tsk1, | ||
1631 | const struct task_struct *tsk2, | ||
1632 | u32 perms) | ||
1633 | { | ||
1634 | const struct task_security_struct *__tsec1, *__tsec2; | ||
1635 | u32 sid1, sid2; | ||
1636 | |||
1637 | rcu_read_lock(); | ||
1638 | __tsec1 = __task_cred(tsk1)->security; sid1 = __tsec1->sid; | ||
1639 | __tsec2 = __task_cred(tsk2)->security; sid2 = __tsec2->sid; | ||
1640 | rcu_read_unlock(); | ||
1641 | return avc_has_perm(sid1, sid2, SECCLASS_PROCESS, perms, NULL); | ||
1642 | } | ||
1643 | |||
1644 | /* | ||
1645 | * Check permission between current and another task, e.g. signal checks, | ||
1646 | * fork check, ptrace check, etc. | ||
1647 | * current is the actor and tsk2 is the target | ||
1648 | * - this uses current's subjective creds | ||
1649 | */ | ||
1650 | static int current_has_perm(const struct task_struct *tsk, | ||
1651 | u32 perms) | ||
1652 | { | ||
1653 | u32 sid, tsid; | ||
1654 | |||
1655 | sid = current_sid(); | ||
1656 | tsid = task_sid(tsk); | ||
1657 | return avc_has_perm(sid, tsid, SECCLASS_PROCESS, perms, NULL); | ||
1658 | } | ||
1659 | |||
1660 | #if CAP_LAST_CAP > 63 | 1679 | #if CAP_LAST_CAP > 63 |
1661 | #error Fix SELinux to handle capabilities > 63. | 1680 | #error Fix SELinux to handle capabilities > 63. |
1662 | #endif | 1681 | #endif |
@@ -1698,16 +1717,6 @@ static int cred_has_capability(const struct cred *cred, | |||
1698 | return rc; | 1717 | return rc; |
1699 | } | 1718 | } |
1700 | 1719 | ||
1701 | /* Check whether a task is allowed to use a system operation. */ | ||
1702 | static int task_has_system(struct task_struct *tsk, | ||
1703 | u32 perms) | ||
1704 | { | ||
1705 | u32 sid = task_sid(tsk); | ||
1706 | |||
1707 | return avc_has_perm(sid, SECINITSID_KERNEL, | ||
1708 | SECCLASS_SYSTEM, perms, NULL); | ||
1709 | } | ||
1710 | |||
1711 | /* Check whether a task has a particular permission to an inode. | 1720 | /* Check whether a task has a particular permission to an inode. |
1712 | The 'adp' parameter is optional and allows other audit | 1721 | The 'adp' parameter is optional and allows other audit |
1713 | data to be passed (e.g. the dentry). */ | 1722 | data to be passed (e.g. the dentry). */ |
@@ -1879,15 +1888,6 @@ static int may_create(struct inode *dir, | |||
1879 | FILESYSTEM__ASSOCIATE, &ad); | 1888 | FILESYSTEM__ASSOCIATE, &ad); |
1880 | } | 1889 | } |
1881 | 1890 | ||
1882 | /* Check whether a task can create a key. */ | ||
1883 | static int may_create_key(u32 ksid, | ||
1884 | struct task_struct *ctx) | ||
1885 | { | ||
1886 | u32 sid = task_sid(ctx); | ||
1887 | |||
1888 | return avc_has_perm(sid, ksid, SECCLASS_KEY, KEY__CREATE, NULL); | ||
1889 | } | ||
1890 | |||
1891 | #define MAY_LINK 0 | 1891 | #define MAY_LINK 0 |
1892 | #define MAY_UNLINK 1 | 1892 | #define MAY_UNLINK 1 |
1893 | #define MAY_RMDIR 2 | 1893 | #define MAY_RMDIR 2 |
@@ -2143,24 +2143,26 @@ static int selinux_binder_transfer_file(struct task_struct *from, | |||
2143 | static int selinux_ptrace_access_check(struct task_struct *child, | 2143 | static int selinux_ptrace_access_check(struct task_struct *child, |
2144 | unsigned int mode) | 2144 | unsigned int mode) |
2145 | { | 2145 | { |
2146 | if (mode & PTRACE_MODE_READ) { | 2146 | u32 sid = current_sid(); |
2147 | u32 sid = current_sid(); | 2147 | u32 csid = task_sid(child); |
2148 | u32 csid = task_sid(child); | 2148 | |
2149 | if (mode & PTRACE_MODE_READ) | ||
2149 | return avc_has_perm(sid, csid, SECCLASS_FILE, FILE__READ, NULL); | 2150 | return avc_has_perm(sid, csid, SECCLASS_FILE, FILE__READ, NULL); |
2150 | } | ||
2151 | 2151 | ||
2152 | return current_has_perm(child, PROCESS__PTRACE); | 2152 | return avc_has_perm(sid, csid, SECCLASS_PROCESS, PROCESS__PTRACE, NULL); |
2153 | } | 2153 | } |
2154 | 2154 | ||
2155 | static int selinux_ptrace_traceme(struct task_struct *parent) | 2155 | static int selinux_ptrace_traceme(struct task_struct *parent) |
2156 | { | 2156 | { |
2157 | return task_has_perm(parent, current, PROCESS__PTRACE); | 2157 | return avc_has_perm(task_sid(parent), current_sid(), SECCLASS_PROCESS, |
2158 | PROCESS__PTRACE, NULL); | ||
2158 | } | 2159 | } |
2159 | 2160 | ||
2160 | static int selinux_capget(struct task_struct *target, kernel_cap_t *effective, | 2161 | static int selinux_capget(struct task_struct *target, kernel_cap_t *effective, |
2161 | kernel_cap_t *inheritable, kernel_cap_t *permitted) | 2162 | kernel_cap_t *inheritable, kernel_cap_t *permitted) |
2162 | { | 2163 | { |
2163 | return current_has_perm(target, PROCESS__GETCAP); | 2164 | return avc_has_perm(current_sid(), task_sid(target), SECCLASS_PROCESS, |
2165 | PROCESS__GETCAP, NULL); | ||
2164 | } | 2166 | } |
2165 | 2167 | ||
2166 | static int selinux_capset(struct cred *new, const struct cred *old, | 2168 | static int selinux_capset(struct cred *new, const struct cred *old, |
@@ -2168,7 +2170,8 @@ static int selinux_capset(struct cred *new, const struct cred *old, | |||
2168 | const kernel_cap_t *inheritable, | 2170 | const kernel_cap_t *inheritable, |
2169 | const kernel_cap_t *permitted) | 2171 | const kernel_cap_t *permitted) |
2170 | { | 2172 | { |
2171 | return cred_has_perm(old, new, PROCESS__SETCAP); | 2173 | return avc_has_perm(cred_sid(old), cred_sid(new), SECCLASS_PROCESS, |
2174 | PROCESS__SETCAP, NULL); | ||
2172 | } | 2175 | } |
2173 | 2176 | ||
2174 | /* | 2177 | /* |
@@ -2224,29 +2227,22 @@ static int selinux_quota_on(struct dentry *dentry) | |||
2224 | 2227 | ||
2225 | static int selinux_syslog(int type) | 2228 | static int selinux_syslog(int type) |
2226 | { | 2229 | { |
2227 | int rc; | ||
2228 | |||
2229 | switch (type) { | 2230 | switch (type) { |
2230 | case SYSLOG_ACTION_READ_ALL: /* Read last kernel messages */ | 2231 | case SYSLOG_ACTION_READ_ALL: /* Read last kernel messages */ |
2231 | case SYSLOG_ACTION_SIZE_BUFFER: /* Return size of the log buffer */ | 2232 | case SYSLOG_ACTION_SIZE_BUFFER: /* Return size of the log buffer */ |
2232 | rc = task_has_system(current, SYSTEM__SYSLOG_READ); | 2233 | return avc_has_perm(current_sid(), SECINITSID_KERNEL, |
2233 | break; | 2234 | SECCLASS_SYSTEM, SYSTEM__SYSLOG_READ, NULL); |
2234 | case SYSLOG_ACTION_CONSOLE_OFF: /* Disable logging to console */ | 2235 | case SYSLOG_ACTION_CONSOLE_OFF: /* Disable logging to console */ |
2235 | case SYSLOG_ACTION_CONSOLE_ON: /* Enable logging to console */ | 2236 | case SYSLOG_ACTION_CONSOLE_ON: /* Enable logging to console */ |
2236 | /* Set level of messages printed to console */ | 2237 | /* Set level of messages printed to console */ |
2237 | case SYSLOG_ACTION_CONSOLE_LEVEL: | 2238 | case SYSLOG_ACTION_CONSOLE_LEVEL: |
2238 | rc = task_has_system(current, SYSTEM__SYSLOG_CONSOLE); | 2239 | return avc_has_perm(current_sid(), SECINITSID_KERNEL, |
2239 | break; | 2240 | SECCLASS_SYSTEM, SYSTEM__SYSLOG_CONSOLE, |
2240 | case SYSLOG_ACTION_CLOSE: /* Close log */ | 2241 | NULL); |
2241 | case SYSLOG_ACTION_OPEN: /* Open log */ | ||
2242 | case SYSLOG_ACTION_READ: /* Read from log */ | ||
2243 | case SYSLOG_ACTION_READ_CLEAR: /* Read/clear last kernel messages */ | ||
2244 | case SYSLOG_ACTION_CLEAR: /* Clear ring buffer */ | ||
2245 | default: | ||
2246 | rc = task_has_system(current, SYSTEM__SYSLOG_MOD); | ||
2247 | break; | ||
2248 | } | 2242 | } |
2249 | return rc; | 2243 | /* All other syslog types */ |
2244 | return avc_has_perm(current_sid(), SECINITSID_KERNEL, | ||
2245 | SECCLASS_SYSTEM, SYSTEM__SYSLOG_MOD, NULL); | ||
2250 | } | 2246 | } |
2251 | 2247 | ||
2252 | /* | 2248 | /* |
@@ -2271,13 +2267,13 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages) | |||
2271 | 2267 | ||
2272 | /* binprm security operations */ | 2268 | /* binprm security operations */ |
2273 | 2269 | ||
2274 | static u32 ptrace_parent_sid(struct task_struct *task) | 2270 | static u32 ptrace_parent_sid(void) |
2275 | { | 2271 | { |
2276 | u32 sid = 0; | 2272 | u32 sid = 0; |
2277 | struct task_struct *tracer; | 2273 | struct task_struct *tracer; |
2278 | 2274 | ||
2279 | rcu_read_lock(); | 2275 | rcu_read_lock(); |
2280 | tracer = ptrace_parent(task); | 2276 | tracer = ptrace_parent(current); |
2281 | if (tracer) | 2277 | if (tracer) |
2282 | sid = task_sid(tracer); | 2278 | sid = task_sid(tracer); |
2283 | rcu_read_unlock(); | 2279 | rcu_read_unlock(); |
@@ -2404,9 +2400,8 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) | |||
2404 | 2400 | ||
2405 | /* Make sure that anyone attempting to ptrace over a task that | 2401 | /* Make sure that anyone attempting to ptrace over a task that |
2406 | * changes its SID has the appropriate permit */ | 2402 | * changes its SID has the appropriate permit */ |
2407 | if (bprm->unsafe & | 2403 | if (bprm->unsafe & LSM_UNSAFE_PTRACE) { |
2408 | (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) { | 2404 | u32 ptsid = ptrace_parent_sid(); |
2409 | u32 ptsid = ptrace_parent_sid(current); | ||
2410 | if (ptsid != 0) { | 2405 | if (ptsid != 0) { |
2411 | rc = avc_has_perm(ptsid, new_tsec->sid, | 2406 | rc = avc_has_perm(ptsid, new_tsec->sid, |
2412 | SECCLASS_PROCESS, | 2407 | SECCLASS_PROCESS, |
@@ -3503,6 +3498,7 @@ static int default_noexec; | |||
3503 | static int file_map_prot_check(struct file *file, unsigned long prot, int shared) | 3498 | static int file_map_prot_check(struct file *file, unsigned long prot, int shared) |
3504 | { | 3499 | { |
3505 | const struct cred *cred = current_cred(); | 3500 | const struct cred *cred = current_cred(); |
3501 | u32 sid = cred_sid(cred); | ||
3506 | int rc = 0; | 3502 | int rc = 0; |
3507 | 3503 | ||
3508 | if (default_noexec && | 3504 | if (default_noexec && |
@@ -3513,7 +3509,8 @@ static int file_map_prot_check(struct file *file, unsigned long prot, int shared | |||
3513 | * private file mapping that will also be writable. | 3509 | * private file mapping that will also be writable. |
3514 | * This has an additional check. | 3510 | * This has an additional check. |
3515 | */ | 3511 | */ |
3516 | rc = cred_has_perm(cred, cred, PROCESS__EXECMEM); | 3512 | rc = avc_has_perm(sid, sid, SECCLASS_PROCESS, |
3513 | PROCESS__EXECMEM, NULL); | ||
3517 | if (rc) | 3514 | if (rc) |
3518 | goto error; | 3515 | goto error; |
3519 | } | 3516 | } |
@@ -3564,6 +3561,7 @@ static int selinux_file_mprotect(struct vm_area_struct *vma, | |||
3564 | unsigned long prot) | 3561 | unsigned long prot) |
3565 | { | 3562 | { |
3566 | const struct cred *cred = current_cred(); | 3563 | const struct cred *cred = current_cred(); |
3564 | u32 sid = cred_sid(cred); | ||
3567 | 3565 | ||
3568 | if (selinux_checkreqprot) | 3566 | if (selinux_checkreqprot) |
3569 | prot = reqprot; | 3567 | prot = reqprot; |
@@ -3573,12 +3571,14 @@ static int selinux_file_mprotect(struct vm_area_struct *vma, | |||
3573 | int rc = 0; | 3571 | int rc = 0; |
3574 | if (vma->vm_start >= vma->vm_mm->start_brk && | 3572 | if (vma->vm_start >= vma->vm_mm->start_brk && |
3575 | vma->vm_end <= vma->vm_mm->brk) { | 3573 | vma->vm_end <= vma->vm_mm->brk) { |
3576 | rc = cred_has_perm(cred, cred, PROCESS__EXECHEAP); | 3574 | rc = avc_has_perm(sid, sid, SECCLASS_PROCESS, |
3575 | PROCESS__EXECHEAP, NULL); | ||
3577 | } else if (!vma->vm_file && | 3576 | } else if (!vma->vm_file && |
3578 | ((vma->vm_start <= vma->vm_mm->start_stack && | 3577 | ((vma->vm_start <= vma->vm_mm->start_stack && |
3579 | vma->vm_end >= vma->vm_mm->start_stack) || | 3578 | vma->vm_end >= vma->vm_mm->start_stack) || |
3580 | vma_is_stack_for_current(vma))) { | 3579 | vma_is_stack_for_current(vma))) { |
3581 | rc = current_has_perm(current, PROCESS__EXECSTACK); | 3580 | rc = avc_has_perm(sid, sid, SECCLASS_PROCESS, |
3581 | PROCESS__EXECSTACK, NULL); | ||
3582 | } else if (vma->vm_file && vma->anon_vma) { | 3582 | } else if (vma->vm_file && vma->anon_vma) { |
3583 | /* | 3583 | /* |
3584 | * We are making executable a file mapping that has | 3584 | * We are making executable a file mapping that has |
@@ -3711,7 +3711,9 @@ static int selinux_file_open(struct file *file, const struct cred *cred) | |||
3711 | 3711 | ||
3712 | static int selinux_task_create(unsigned long clone_flags) | 3712 | static int selinux_task_create(unsigned long clone_flags) |
3713 | { | 3713 | { |
3714 | return current_has_perm(current, PROCESS__FORK); | 3714 | u32 sid = current_sid(); |
3715 | |||
3716 | return avc_has_perm(sid, sid, SECCLASS_PROCESS, PROCESS__FORK, NULL); | ||
3715 | } | 3717 | } |
3716 | 3718 | ||
3717 | /* | 3719 | /* |
@@ -3821,15 +3823,12 @@ static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode) | |||
3821 | 3823 | ||
3822 | static int selinux_kernel_module_request(char *kmod_name) | 3824 | static int selinux_kernel_module_request(char *kmod_name) |
3823 | { | 3825 | { |
3824 | u32 sid; | ||
3825 | struct common_audit_data ad; | 3826 | struct common_audit_data ad; |
3826 | 3827 | ||
3827 | sid = task_sid(current); | ||
3828 | |||
3829 | ad.type = LSM_AUDIT_DATA_KMOD; | 3828 | ad.type = LSM_AUDIT_DATA_KMOD; |
3830 | ad.u.kmod_name = kmod_name; | 3829 | ad.u.kmod_name = kmod_name; |
3831 | 3830 | ||
3832 | return avc_has_perm(sid, SECINITSID_KERNEL, SECCLASS_SYSTEM, | 3831 | return avc_has_perm(current_sid(), SECINITSID_KERNEL, SECCLASS_SYSTEM, |
3833 | SYSTEM__MODULE_REQUEST, &ad); | 3832 | SYSTEM__MODULE_REQUEST, &ad); |
3834 | } | 3833 | } |
3835 | 3834 | ||
@@ -3881,17 +3880,20 @@ static int selinux_kernel_read_file(struct file *file, | |||
3881 | 3880 | ||
3882 | static int selinux_task_setpgid(struct task_struct *p, pid_t pgid) | 3881 | static int selinux_task_setpgid(struct task_struct *p, pid_t pgid) |
3883 | { | 3882 | { |
3884 | return current_has_perm(p, PROCESS__SETPGID); | 3883 | return avc_has_perm(current_sid(), task_sid(p), SECCLASS_PROCESS, |
3884 | PROCESS__SETPGID, NULL); | ||
3885 | } | 3885 | } |
3886 | 3886 | ||
3887 | static int selinux_task_getpgid(struct task_struct *p) | 3887 | static int selinux_task_getpgid(struct task_struct *p) |
3888 | { | 3888 | { |
3889 | return current_has_perm(p, PROCESS__GETPGID); | 3889 | return avc_has_perm(current_sid(), task_sid(p), SECCLASS_PROCESS, |
3890 | PROCESS__GETPGID, NULL); | ||
3890 | } | 3891 | } |
3891 | 3892 | ||
3892 | static int selinux_task_getsid(struct task_struct *p) | 3893 | static int selinux_task_getsid(struct task_struct *p) |
3893 | { | 3894 | { |
3894 | return current_has_perm(p, PROCESS__GETSESSION); | 3895 | return avc_has_perm(current_sid(), task_sid(p), SECCLASS_PROCESS, |
3896 | PROCESS__GETSESSION, NULL); | ||
3895 | } | 3897 | } |
3896 | 3898 | ||
3897 | static void selinux_task_getsecid(struct task_struct *p, u32 *secid) | 3899 | static void selinux_task_getsecid(struct task_struct *p, u32 *secid) |
@@ -3901,17 +3903,20 @@ static void selinux_task_getsecid(struct task_struct *p, u32 *secid) | |||
3901 | 3903 | ||
3902 | static int selinux_task_setnice(struct task_struct *p, int nice) | 3904 | static int selinux_task_setnice(struct task_struct *p, int nice) |
3903 | { | 3905 | { |
3904 | return current_has_perm(p, PROCESS__SETSCHED); | 3906 | return avc_has_perm(current_sid(), task_sid(p), SECCLASS_PROCESS, |
3907 | PROCESS__SETSCHED, NULL); | ||
3905 | } | 3908 | } |
3906 | 3909 | ||
3907 | static int selinux_task_setioprio(struct task_struct *p, int ioprio) | 3910 | static int selinux_task_setioprio(struct task_struct *p, int ioprio) |
3908 | { | 3911 | { |
3909 | return current_has_perm(p, PROCESS__SETSCHED); | 3912 | return avc_has_perm(current_sid(), task_sid(p), SECCLASS_PROCESS, |
3913 | PROCESS__SETSCHED, NULL); | ||
3910 | } | 3914 | } |
3911 | 3915 | ||
3912 | static int selinux_task_getioprio(struct task_struct *p) | 3916 | static int selinux_task_getioprio(struct task_struct *p) |
3913 | { | 3917 | { |
3914 | return current_has_perm(p, PROCESS__GETSCHED); | 3918 | return avc_has_perm(current_sid(), task_sid(p), SECCLASS_PROCESS, |
3919 | PROCESS__GETSCHED, NULL); | ||
3915 | } | 3920 | } |
3916 | 3921 | ||
3917 | static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource, | 3922 | static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource, |
@@ -3924,47 +3929,42 @@ static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource, | |||
3924 | later be used as a safe reset point for the soft limit | 3929 | later be used as a safe reset point for the soft limit |
3925 | upon context transitions. See selinux_bprm_committing_creds. */ | 3930 | upon context transitions. See selinux_bprm_committing_creds. */ |
3926 | if (old_rlim->rlim_max != new_rlim->rlim_max) | 3931 | if (old_rlim->rlim_max != new_rlim->rlim_max) |
3927 | return current_has_perm(p, PROCESS__SETRLIMIT); | 3932 | return avc_has_perm(current_sid(), task_sid(p), |
3933 | SECCLASS_PROCESS, PROCESS__SETRLIMIT, NULL); | ||
3928 | 3934 | ||
3929 | return 0; | 3935 | return 0; |
3930 | } | 3936 | } |
3931 | 3937 | ||
3932 | static int selinux_task_setscheduler(struct task_struct *p) | 3938 | static int selinux_task_setscheduler(struct task_struct *p) |
3933 | { | 3939 | { |
3934 | return current_has_perm(p, PROCESS__SETSCHED); | 3940 | return avc_has_perm(current_sid(), task_sid(p), SECCLASS_PROCESS, |
3941 | PROCESS__SETSCHED, NULL); | ||
3935 | } | 3942 | } |
3936 | 3943 | ||
3937 | static int selinux_task_getscheduler(struct task_struct *p) | 3944 | static int selinux_task_getscheduler(struct task_struct *p) |
3938 | { | 3945 | { |
3939 | return current_has_perm(p, PROCESS__GETSCHED); | 3946 | return avc_has_perm(current_sid(), task_sid(p), SECCLASS_PROCESS, |
3947 | PROCESS__GETSCHED, NULL); | ||
3940 | } | 3948 | } |
3941 | 3949 | ||
3942 | static int selinux_task_movememory(struct task_struct *p) | 3950 | static int selinux_task_movememory(struct task_struct *p) |
3943 | { | 3951 | { |
3944 | return current_has_perm(p, PROCESS__SETSCHED); | 3952 | return avc_has_perm(current_sid(), task_sid(p), SECCLASS_PROCESS, |
3953 | PROCESS__SETSCHED, NULL); | ||
3945 | } | 3954 | } |
3946 | 3955 | ||
3947 | static int selinux_task_kill(struct task_struct *p, struct siginfo *info, | 3956 | static int selinux_task_kill(struct task_struct *p, struct siginfo *info, |
3948 | int sig, u32 secid) | 3957 | int sig, u32 secid) |
3949 | { | 3958 | { |
3950 | u32 perm; | 3959 | u32 perm; |
3951 | int rc; | ||
3952 | 3960 | ||
3953 | if (!sig) | 3961 | if (!sig) |
3954 | perm = PROCESS__SIGNULL; /* null signal; existence test */ | 3962 | perm = PROCESS__SIGNULL; /* null signal; existence test */ |
3955 | else | 3963 | else |
3956 | perm = signal_to_av(sig); | 3964 | perm = signal_to_av(sig); |
3957 | if (secid) | 3965 | if (!secid) |
3958 | rc = avc_has_perm(secid, task_sid(p), | 3966 | secid = current_sid(); |
3959 | SECCLASS_PROCESS, perm, NULL); | 3967 | return avc_has_perm(secid, task_sid(p), SECCLASS_PROCESS, perm, NULL); |
3960 | else | ||
3961 | rc = current_has_perm(p, perm); | ||
3962 | return rc; | ||
3963 | } | ||
3964 | |||
3965 | static int selinux_task_wait(struct task_struct *p) | ||
3966 | { | ||
3967 | return task_has_perm(p, current, PROCESS__SIGCHLD); | ||
3968 | } | 3968 | } |
3969 | 3969 | ||
3970 | static void selinux_task_to_inode(struct task_struct *p, | 3970 | static void selinux_task_to_inode(struct task_struct *p, |
@@ -4254,12 +4254,11 @@ static int socket_sockcreate_sid(const struct task_security_struct *tsec, | |||
4254 | socksid); | 4254 | socksid); |
4255 | } | 4255 | } |
4256 | 4256 | ||
4257 | static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms) | 4257 | static int sock_has_perm(struct sock *sk, u32 perms) |
4258 | { | 4258 | { |
4259 | struct sk_security_struct *sksec = sk->sk_security; | 4259 | struct sk_security_struct *sksec = sk->sk_security; |
4260 | struct common_audit_data ad; | 4260 | struct common_audit_data ad; |
4261 | struct lsm_network_audit net = {0,}; | 4261 | struct lsm_network_audit net = {0,}; |
4262 | u32 tsid = task_sid(task); | ||
4263 | 4262 | ||
4264 | if (sksec->sid == SECINITSID_KERNEL) | 4263 | if (sksec->sid == SECINITSID_KERNEL) |
4265 | return 0; | 4264 | return 0; |
@@ -4268,7 +4267,8 @@ static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms) | |||
4268 | ad.u.net = &net; | 4267 | ad.u.net = &net; |
4269 | ad.u.net->sk = sk; | 4268 | ad.u.net->sk = sk; |
4270 | 4269 | ||
4271 | return avc_has_perm(tsid, sksec->sid, sksec->sclass, perms, &ad); | 4270 | return avc_has_perm(current_sid(), sksec->sid, sksec->sclass, perms, |
4271 | &ad); | ||
4272 | } | 4272 | } |
4273 | 4273 | ||
4274 | static int selinux_socket_create(int family, int type, | 4274 | static int selinux_socket_create(int family, int type, |
@@ -4330,7 +4330,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
4330 | u16 family; | 4330 | u16 family; |
4331 | int err; | 4331 | int err; |
4332 | 4332 | ||
4333 | err = sock_has_perm(current, sk, SOCKET__BIND); | 4333 | err = sock_has_perm(sk, SOCKET__BIND); |
4334 | if (err) | 4334 | if (err) |
4335 | goto out; | 4335 | goto out; |
4336 | 4336 | ||
@@ -4365,7 +4365,8 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
4365 | 4365 | ||
4366 | inet_get_local_port_range(sock_net(sk), &low, &high); | 4366 | inet_get_local_port_range(sock_net(sk), &low, &high); |
4367 | 4367 | ||
4368 | if (snum < max(PROT_SOCK, low) || snum > high) { | 4368 | if (snum < max(inet_prot_sock(sock_net(sk)), low) || |
4369 | snum > high) { | ||
4369 | err = sel_netport_sid(sk->sk_protocol, | 4370 | err = sel_netport_sid(sk->sk_protocol, |
4370 | snum, &sid); | 4371 | snum, &sid); |
4371 | if (err) | 4372 | if (err) |
@@ -4429,7 +4430,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, | |||
4429 | struct sk_security_struct *sksec = sk->sk_security; | 4430 | struct sk_security_struct *sksec = sk->sk_security; |
4430 | int err; | 4431 | int err; |
4431 | 4432 | ||
4432 | err = sock_has_perm(current, sk, SOCKET__CONNECT); | 4433 | err = sock_has_perm(sk, SOCKET__CONNECT); |
4433 | if (err) | 4434 | if (err) |
4434 | return err; | 4435 | return err; |
4435 | 4436 | ||
@@ -4481,7 +4482,7 @@ out: | |||
4481 | 4482 | ||
4482 | static int selinux_socket_listen(struct socket *sock, int backlog) | 4483 | static int selinux_socket_listen(struct socket *sock, int backlog) |
4483 | { | 4484 | { |
4484 | return sock_has_perm(current, sock->sk, SOCKET__LISTEN); | 4485 | return sock_has_perm(sock->sk, SOCKET__LISTEN); |
4485 | } | 4486 | } |
4486 | 4487 | ||
4487 | static int selinux_socket_accept(struct socket *sock, struct socket *newsock) | 4488 | static int selinux_socket_accept(struct socket *sock, struct socket *newsock) |
@@ -4492,7 +4493,7 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock) | |||
4492 | u16 sclass; | 4493 | u16 sclass; |
4493 | u32 sid; | 4494 | u32 sid; |
4494 | 4495 | ||
4495 | err = sock_has_perm(current, sock->sk, SOCKET__ACCEPT); | 4496 | err = sock_has_perm(sock->sk, SOCKET__ACCEPT); |
4496 | if (err) | 4497 | if (err) |
4497 | return err; | 4498 | return err; |
4498 | 4499 | ||
@@ -4513,30 +4514,30 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock) | |||
4513 | static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg, | 4514 | static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg, |
4514 | int size) | 4515 | int size) |
4515 | { | 4516 | { |
4516 | return sock_has_perm(current, sock->sk, SOCKET__WRITE); | 4517 | return sock_has_perm(sock->sk, SOCKET__WRITE); |
4517 | } | 4518 | } |
4518 | 4519 | ||
4519 | static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg, | 4520 | static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg, |
4520 | int size, int flags) | 4521 | int size, int flags) |
4521 | { | 4522 | { |
4522 | return sock_has_perm(current, sock->sk, SOCKET__READ); | 4523 | return sock_has_perm(sock->sk, SOCKET__READ); |
4523 | } | 4524 | } |
4524 | 4525 | ||
4525 | static int selinux_socket_getsockname(struct socket *sock) | 4526 | static int selinux_socket_getsockname(struct socket *sock) |
4526 | { | 4527 | { |
4527 | return sock_has_perm(current, sock->sk, SOCKET__GETATTR); | 4528 | return sock_has_perm(sock->sk, SOCKET__GETATTR); |
4528 | } | 4529 | } |
4529 | 4530 | ||
4530 | static int selinux_socket_getpeername(struct socket *sock) | 4531 | static int selinux_socket_getpeername(struct socket *sock) |
4531 | { | 4532 | { |
4532 | return sock_has_perm(current, sock->sk, SOCKET__GETATTR); | 4533 | return sock_has_perm(sock->sk, SOCKET__GETATTR); |
4533 | } | 4534 | } |
4534 | 4535 | ||
4535 | static int selinux_socket_setsockopt(struct socket *sock, int level, int optname) | 4536 | static int selinux_socket_setsockopt(struct socket *sock, int level, int optname) |
4536 | { | 4537 | { |
4537 | int err; | 4538 | int err; |
4538 | 4539 | ||
4539 | err = sock_has_perm(current, sock->sk, SOCKET__SETOPT); | 4540 | err = sock_has_perm(sock->sk, SOCKET__SETOPT); |
4540 | if (err) | 4541 | if (err) |
4541 | return err; | 4542 | return err; |
4542 | 4543 | ||
@@ -4546,12 +4547,12 @@ static int selinux_socket_setsockopt(struct socket *sock, int level, int optname | |||
4546 | static int selinux_socket_getsockopt(struct socket *sock, int level, | 4547 | static int selinux_socket_getsockopt(struct socket *sock, int level, |
4547 | int optname) | 4548 | int optname) |
4548 | { | 4549 | { |
4549 | return sock_has_perm(current, sock->sk, SOCKET__GETOPT); | 4550 | return sock_has_perm(sock->sk, SOCKET__GETOPT); |
4550 | } | 4551 | } |
4551 | 4552 | ||
4552 | static int selinux_socket_shutdown(struct socket *sock, int how) | 4553 | static int selinux_socket_shutdown(struct socket *sock, int how) |
4553 | { | 4554 | { |
4554 | return sock_has_perm(current, sock->sk, SOCKET__SHUTDOWN); | 4555 | return sock_has_perm(sock->sk, SOCKET__SHUTDOWN); |
4555 | } | 4556 | } |
4556 | 4557 | ||
4557 | static int selinux_socket_unix_stream_connect(struct sock *sock, | 4558 | static int selinux_socket_unix_stream_connect(struct sock *sock, |
@@ -5039,7 +5040,7 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) | |||
5039 | goto out; | 5040 | goto out; |
5040 | } | 5041 | } |
5041 | 5042 | ||
5042 | err = sock_has_perm(current, sk, perm); | 5043 | err = sock_has_perm(sk, perm); |
5043 | out: | 5044 | out: |
5044 | return err; | 5045 | return err; |
5045 | } | 5046 | } |
@@ -5370,20 +5371,17 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) | |||
5370 | return selinux_nlmsg_perm(sk, skb); | 5371 | return selinux_nlmsg_perm(sk, skb); |
5371 | } | 5372 | } |
5372 | 5373 | ||
5373 | static int ipc_alloc_security(struct task_struct *task, | 5374 | static int ipc_alloc_security(struct kern_ipc_perm *perm, |
5374 | struct kern_ipc_perm *perm, | ||
5375 | u16 sclass) | 5375 | u16 sclass) |
5376 | { | 5376 | { |
5377 | struct ipc_security_struct *isec; | 5377 | struct ipc_security_struct *isec; |
5378 | u32 sid; | ||
5379 | 5378 | ||
5380 | isec = kzalloc(sizeof(struct ipc_security_struct), GFP_KERNEL); | 5379 | isec = kzalloc(sizeof(struct ipc_security_struct), GFP_KERNEL); |
5381 | if (!isec) | 5380 | if (!isec) |
5382 | return -ENOMEM; | 5381 | return -ENOMEM; |
5383 | 5382 | ||
5384 | sid = task_sid(task); | ||
5385 | isec->sclass = sclass; | 5383 | isec->sclass = sclass; |
5386 | isec->sid = sid; | 5384 | isec->sid = current_sid(); |
5387 | perm->security = isec; | 5385 | perm->security = isec; |
5388 | 5386 | ||
5389 | return 0; | 5387 | return 0; |
@@ -5451,7 +5449,7 @@ static int selinux_msg_queue_alloc_security(struct msg_queue *msq) | |||
5451 | u32 sid = current_sid(); | 5449 | u32 sid = current_sid(); |
5452 | int rc; | 5450 | int rc; |
5453 | 5451 | ||
5454 | rc = ipc_alloc_security(current, &msq->q_perm, SECCLASS_MSGQ); | 5452 | rc = ipc_alloc_security(&msq->q_perm, SECCLASS_MSGQ); |
5455 | if (rc) | 5453 | if (rc) |
5456 | return rc; | 5454 | return rc; |
5457 | 5455 | ||
@@ -5498,7 +5496,8 @@ static int selinux_msg_queue_msgctl(struct msg_queue *msq, int cmd) | |||
5498 | case IPC_INFO: | 5496 | case IPC_INFO: |
5499 | case MSG_INFO: | 5497 | case MSG_INFO: |
5500 | /* No specific object, just general system-wide information. */ | 5498 | /* No specific object, just general system-wide information. */ |
5501 | return task_has_system(current, SYSTEM__IPC_INFO); | 5499 | return avc_has_perm(current_sid(), SECINITSID_KERNEL, |
5500 | SECCLASS_SYSTEM, SYSTEM__IPC_INFO, NULL); | ||
5502 | case IPC_STAT: | 5501 | case IPC_STAT: |
5503 | case MSG_STAT: | 5502 | case MSG_STAT: |
5504 | perms = MSGQ__GETATTR | MSGQ__ASSOCIATE; | 5503 | perms = MSGQ__GETATTR | MSGQ__ASSOCIATE; |
@@ -5592,7 +5591,7 @@ static int selinux_shm_alloc_security(struct shmid_kernel *shp) | |||
5592 | u32 sid = current_sid(); | 5591 | u32 sid = current_sid(); |
5593 | int rc; | 5592 | int rc; |
5594 | 5593 | ||
5595 | rc = ipc_alloc_security(current, &shp->shm_perm, SECCLASS_SHM); | 5594 | rc = ipc_alloc_security(&shp->shm_perm, SECCLASS_SHM); |
5596 | if (rc) | 5595 | if (rc) |
5597 | return rc; | 5596 | return rc; |
5598 | 5597 | ||
@@ -5640,7 +5639,8 @@ static int selinux_shm_shmctl(struct shmid_kernel *shp, int cmd) | |||
5640 | case IPC_INFO: | 5639 | case IPC_INFO: |
5641 | case SHM_INFO: | 5640 | case SHM_INFO: |
5642 | /* No specific object, just general system-wide information. */ | 5641 | /* No specific object, just general system-wide information. */ |
5643 | return task_has_system(current, SYSTEM__IPC_INFO); | 5642 | return avc_has_perm(current_sid(), SECINITSID_KERNEL, |
5643 | SECCLASS_SYSTEM, SYSTEM__IPC_INFO, NULL); | ||
5644 | case IPC_STAT: | 5644 | case IPC_STAT: |
5645 | case SHM_STAT: | 5645 | case SHM_STAT: |
5646 | perms = SHM__GETATTR | SHM__ASSOCIATE; | 5646 | perms = SHM__GETATTR | SHM__ASSOCIATE; |
@@ -5684,7 +5684,7 @@ static int selinux_sem_alloc_security(struct sem_array *sma) | |||
5684 | u32 sid = current_sid(); | 5684 | u32 sid = current_sid(); |
5685 | int rc; | 5685 | int rc; |
5686 | 5686 | ||
5687 | rc = ipc_alloc_security(current, &sma->sem_perm, SECCLASS_SEM); | 5687 | rc = ipc_alloc_security(&sma->sem_perm, SECCLASS_SEM); |
5688 | if (rc) | 5688 | if (rc) |
5689 | return rc; | 5689 | return rc; |
5690 | 5690 | ||
@@ -5732,7 +5732,8 @@ static int selinux_sem_semctl(struct sem_array *sma, int cmd) | |||
5732 | case IPC_INFO: | 5732 | case IPC_INFO: |
5733 | case SEM_INFO: | 5733 | case SEM_INFO: |
5734 | /* No specific object, just general system-wide information. */ | 5734 | /* No specific object, just general system-wide information. */ |
5735 | return task_has_system(current, SYSTEM__IPC_INFO); | 5735 | return avc_has_perm(current_sid(), SECINITSID_KERNEL, |
5736 | SECCLASS_SYSTEM, SYSTEM__IPC_INFO, NULL); | ||
5736 | case GETPID: | 5737 | case GETPID: |
5737 | case GETNCNT: | 5738 | case GETNCNT: |
5738 | case GETZCNT: | 5739 | case GETZCNT: |
@@ -5813,15 +5814,16 @@ static int selinux_getprocattr(struct task_struct *p, | |||
5813 | int error; | 5814 | int error; |
5814 | unsigned len; | 5815 | unsigned len; |
5815 | 5816 | ||
5817 | rcu_read_lock(); | ||
5818 | __tsec = __task_cred(p)->security; | ||
5819 | |||
5816 | if (current != p) { | 5820 | if (current != p) { |
5817 | error = current_has_perm(p, PROCESS__GETATTR); | 5821 | error = avc_has_perm(current_sid(), __tsec->sid, |
5822 | SECCLASS_PROCESS, PROCESS__GETATTR, NULL); | ||
5818 | if (error) | 5823 | if (error) |
5819 | return error; | 5824 | goto bad; |
5820 | } | 5825 | } |
5821 | 5826 | ||
5822 | rcu_read_lock(); | ||
5823 | __tsec = __task_cred(p)->security; | ||
5824 | |||
5825 | if (!strcmp(name, "current")) | 5827 | if (!strcmp(name, "current")) |
5826 | sid = __tsec->sid; | 5828 | sid = __tsec->sid; |
5827 | else if (!strcmp(name, "prev")) | 5829 | else if (!strcmp(name, "prev")) |
@@ -5834,8 +5836,10 @@ static int selinux_getprocattr(struct task_struct *p, | |||
5834 | sid = __tsec->keycreate_sid; | 5836 | sid = __tsec->keycreate_sid; |
5835 | else if (!strcmp(name, "sockcreate")) | 5837 | else if (!strcmp(name, "sockcreate")) |
5836 | sid = __tsec->sockcreate_sid; | 5838 | sid = __tsec->sockcreate_sid; |
5837 | else | 5839 | else { |
5838 | goto invalid; | 5840 | error = -EINVAL; |
5841 | goto bad; | ||
5842 | } | ||
5839 | rcu_read_unlock(); | 5843 | rcu_read_unlock(); |
5840 | 5844 | ||
5841 | if (!sid) | 5845 | if (!sid) |
@@ -5846,48 +5850,44 @@ static int selinux_getprocattr(struct task_struct *p, | |||
5846 | return error; | 5850 | return error; |
5847 | return len; | 5851 | return len; |
5848 | 5852 | ||
5849 | invalid: | 5853 | bad: |
5850 | rcu_read_unlock(); | 5854 | rcu_read_unlock(); |
5851 | return -EINVAL; | 5855 | return error; |
5852 | } | 5856 | } |
5853 | 5857 | ||
5854 | static int selinux_setprocattr(struct task_struct *p, | 5858 | static int selinux_setprocattr(const char *name, void *value, size_t size) |
5855 | char *name, void *value, size_t size) | ||
5856 | { | 5859 | { |
5857 | struct task_security_struct *tsec; | 5860 | struct task_security_struct *tsec; |
5858 | struct cred *new; | 5861 | struct cred *new; |
5859 | u32 sid = 0, ptsid; | 5862 | u32 mysid = current_sid(), sid = 0, ptsid; |
5860 | int error; | 5863 | int error; |
5861 | char *str = value; | 5864 | char *str = value; |
5862 | 5865 | ||
5863 | if (current != p) { | ||
5864 | /* SELinux only allows a process to change its own | ||
5865 | security attributes. */ | ||
5866 | return -EACCES; | ||
5867 | } | ||
5868 | |||
5869 | /* | 5866 | /* |
5870 | * Basic control over ability to set these attributes at all. | 5867 | * Basic control over ability to set these attributes at all. |
5871 | * current == p, but we'll pass them separately in case the | ||
5872 | * above restriction is ever removed. | ||
5873 | */ | 5868 | */ |
5874 | if (!strcmp(name, "exec")) | 5869 | if (!strcmp(name, "exec")) |
5875 | error = current_has_perm(p, PROCESS__SETEXEC); | 5870 | error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS, |
5871 | PROCESS__SETEXEC, NULL); | ||
5876 | else if (!strcmp(name, "fscreate")) | 5872 | else if (!strcmp(name, "fscreate")) |
5877 | error = current_has_perm(p, PROCESS__SETFSCREATE); | 5873 | error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS, |
5874 | PROCESS__SETFSCREATE, NULL); | ||
5878 | else if (!strcmp(name, "keycreate")) | 5875 | else if (!strcmp(name, "keycreate")) |
5879 | error = current_has_perm(p, PROCESS__SETKEYCREATE); | 5876 | error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS, |
5877 | PROCESS__SETKEYCREATE, NULL); | ||
5880 | else if (!strcmp(name, "sockcreate")) | 5878 | else if (!strcmp(name, "sockcreate")) |
5881 | error = current_has_perm(p, PROCESS__SETSOCKCREATE); | 5879 | error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS, |
5880 | PROCESS__SETSOCKCREATE, NULL); | ||
5882 | else if (!strcmp(name, "current")) | 5881 | else if (!strcmp(name, "current")) |
5883 | error = current_has_perm(p, PROCESS__SETCURRENT); | 5882 | error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS, |
5883 | PROCESS__SETCURRENT, NULL); | ||
5884 | else | 5884 | else |
5885 | error = -EINVAL; | 5885 | error = -EINVAL; |
5886 | if (error) | 5886 | if (error) |
5887 | return error; | 5887 | return error; |
5888 | 5888 | ||
5889 | /* Obtain a SID for the context, if one was specified. */ | 5889 | /* Obtain a SID for the context, if one was specified. */ |
5890 | if (size && str[1] && str[1] != '\n') { | 5890 | if (size && str[0] && str[0] != '\n') { |
5891 | if (str[size-1] == '\n') { | 5891 | if (str[size-1] == '\n') { |
5892 | str[size-1] = 0; | 5892 | str[size-1] = 0; |
5893 | size--; | 5893 | size--; |
@@ -5934,7 +5934,8 @@ static int selinux_setprocattr(struct task_struct *p, | |||
5934 | } else if (!strcmp(name, "fscreate")) { | 5934 | } else if (!strcmp(name, "fscreate")) { |
5935 | tsec->create_sid = sid; | 5935 | tsec->create_sid = sid; |
5936 | } else if (!strcmp(name, "keycreate")) { | 5936 | } else if (!strcmp(name, "keycreate")) { |
5937 | error = may_create_key(sid, p); | 5937 | error = avc_has_perm(mysid, sid, SECCLASS_KEY, KEY__CREATE, |
5938 | NULL); | ||
5938 | if (error) | 5939 | if (error) |
5939 | goto abort_change; | 5940 | goto abort_change; |
5940 | tsec->keycreate_sid = sid; | 5941 | tsec->keycreate_sid = sid; |
@@ -5961,7 +5962,7 @@ static int selinux_setprocattr(struct task_struct *p, | |||
5961 | 5962 | ||
5962 | /* Check for ptracing, and update the task SID if ok. | 5963 | /* Check for ptracing, and update the task SID if ok. |
5963 | Otherwise, leave SID unchanged and fail. */ | 5964 | Otherwise, leave SID unchanged and fail. */ |
5964 | ptsid = ptrace_parent_sid(p); | 5965 | ptsid = ptrace_parent_sid(); |
5965 | if (ptsid != 0) { | 5966 | if (ptsid != 0) { |
5966 | error = avc_has_perm(ptsid, sid, SECCLASS_PROCESS, | 5967 | error = avc_has_perm(ptsid, sid, SECCLASS_PROCESS, |
5967 | PROCESS__PTRACE, NULL); | 5968 | PROCESS__PTRACE, NULL); |
@@ -6209,7 +6210,6 @@ static struct security_hook_list selinux_hooks[] = { | |||
6209 | LSM_HOOK_INIT(task_getscheduler, selinux_task_getscheduler), | 6210 | LSM_HOOK_INIT(task_getscheduler, selinux_task_getscheduler), |
6210 | LSM_HOOK_INIT(task_movememory, selinux_task_movememory), | 6211 | LSM_HOOK_INIT(task_movememory, selinux_task_movememory), |
6211 | LSM_HOOK_INIT(task_kill, selinux_task_kill), | 6212 | LSM_HOOK_INIT(task_kill, selinux_task_kill), |
6212 | LSM_HOOK_INIT(task_wait, selinux_task_wait), | ||
6213 | LSM_HOOK_INIT(task_to_inode, selinux_task_to_inode), | 6213 | LSM_HOOK_INIT(task_to_inode, selinux_task_to_inode), |
6214 | 6214 | ||
6215 | LSM_HOOK_INIT(ipc_permission, selinux_ipc_permission), | 6215 | LSM_HOOK_INIT(ipc_permission, selinux_ipc_permission), |
@@ -6349,7 +6349,7 @@ static __init int selinux_init(void) | |||
6349 | 0, SLAB_PANIC, NULL); | 6349 | 0, SLAB_PANIC, NULL); |
6350 | avc_init(); | 6350 | avc_init(); |
6351 | 6351 | ||
6352 | security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks)); | 6352 | security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks), "selinux"); |
6353 | 6353 | ||
6354 | if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET)) | 6354 | if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET)) |
6355 | panic("SELinux: Unable to register AVC netcache callback\n"); | 6355 | panic("SELinux: Unable to register AVC netcache callback\n"); |