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