diff options
| author | David Howells <dhowells@redhat.com> | 2008-11-13 18:39:19 -0500 |
|---|---|---|
| committer | James Morris <jmorris@namei.org> | 2008-11-13 18:39:19 -0500 |
| commit | 275bb41e9d058fbb327e7642f077e1beaeac162e (patch) | |
| tree | 049fdbb39ca43e7b3b9abf36ad279b31488121bc /security | |
| parent | c69e8d9c01db2adc503464993c358901c9af9de4 (diff) | |
CRED: Wrap access to SELinux's task SID
Wrap access to SELinux's task SID, using task_sid() and current_sid() as
appropriate.
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security')
| -rw-r--r-- | security/selinux/hooks.c | 412 |
1 files changed, 218 insertions, 194 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 658435dce37c..3f3de565c242 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -172,10 +172,35 @@ static int cred_alloc_security(struct cred *cred) | |||
| 172 | return 0; | 172 | return 0; |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | /* | ||
| 176 | * get the security ID of a task | ||
| 177 | */ | ||
| 178 | static inline u32 task_sid(const struct task_struct *task) | ||
| 179 | { | ||
| 180 | const struct task_security_struct *tsec; | ||
| 181 | u32 sid; | ||
| 182 | |||
| 183 | rcu_read_lock(); | ||
| 184 | tsec = __task_cred(task)->security; | ||
| 185 | sid = tsec->sid; | ||
| 186 | rcu_read_unlock(); | ||
| 187 | return sid; | ||
| 188 | } | ||
| 189 | |||
| 190 | /* | ||
| 191 | * get the security ID of the current task | ||
| 192 | */ | ||
| 193 | static inline u32 current_sid(void) | ||
| 194 | { | ||
| 195 | const struct task_security_struct *tsec = current_cred()->security; | ||
| 196 | |||
| 197 | return tsec->sid; | ||
| 198 | } | ||
| 199 | |||
| 175 | static int inode_alloc_security(struct inode *inode) | 200 | static int inode_alloc_security(struct inode *inode) |
| 176 | { | 201 | { |
| 177 | struct task_security_struct *tsec = current->cred->security; | ||
| 178 | struct inode_security_struct *isec; | 202 | struct inode_security_struct *isec; |
| 203 | u32 sid = current_sid(); | ||
| 179 | 204 | ||
| 180 | isec = kmem_cache_zalloc(sel_inode_cache, GFP_NOFS); | 205 | isec = kmem_cache_zalloc(sel_inode_cache, GFP_NOFS); |
| 181 | if (!isec) | 206 | if (!isec) |
| @@ -186,7 +211,7 @@ static int inode_alloc_security(struct inode *inode) | |||
| 186 | isec->inode = inode; | 211 | isec->inode = inode; |
| 187 | isec->sid = SECINITSID_UNLABELED; | 212 | isec->sid = SECINITSID_UNLABELED; |
| 188 | isec->sclass = SECCLASS_FILE; | 213 | isec->sclass = SECCLASS_FILE; |
| 189 | isec->task_sid = tsec->sid; | 214 | isec->task_sid = sid; |
| 190 | inode->i_security = isec; | 215 | inode->i_security = isec; |
| 191 | 216 | ||
| 192 | return 0; | 217 | return 0; |
| @@ -208,15 +233,15 @@ static void inode_free_security(struct inode *inode) | |||
| 208 | 233 | ||
| 209 | static int file_alloc_security(struct file *file) | 234 | static int file_alloc_security(struct file *file) |
| 210 | { | 235 | { |
| 211 | struct task_security_struct *tsec = current->cred->security; | ||
| 212 | struct file_security_struct *fsec; | 236 | struct file_security_struct *fsec; |
| 237 | u32 sid = current_sid(); | ||
| 213 | 238 | ||
| 214 | fsec = kzalloc(sizeof(struct file_security_struct), GFP_KERNEL); | 239 | fsec = kzalloc(sizeof(struct file_security_struct), GFP_KERNEL); |
| 215 | if (!fsec) | 240 | if (!fsec) |
| 216 | return -ENOMEM; | 241 | return -ENOMEM; |
| 217 | 242 | ||
| 218 | fsec->sid = tsec->sid; | 243 | fsec->sid = sid; |
| 219 | fsec->fown_sid = tsec->sid; | 244 | fsec->fown_sid = sid; |
| 220 | file->f_security = fsec; | 245 | file->f_security = fsec; |
| 221 | 246 | ||
| 222 | return 0; | 247 | return 0; |
| @@ -331,8 +356,9 @@ static const match_table_t tokens = { | |||
| 331 | 356 | ||
| 332 | static int may_context_mount_sb_relabel(u32 sid, | 357 | static int may_context_mount_sb_relabel(u32 sid, |
| 333 | struct superblock_security_struct *sbsec, | 358 | struct superblock_security_struct *sbsec, |
| 334 | struct task_security_struct *tsec) | 359 | const struct cred *cred) |
| 335 | { | 360 | { |
| 361 | const struct task_security_struct *tsec = cred->security; | ||
| 336 | int rc; | 362 | int rc; |
| 337 | 363 | ||
| 338 | rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM, | 364 | rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM, |
| @@ -347,8 +373,9 @@ static int may_context_mount_sb_relabel(u32 sid, | |||
| 347 | 373 | ||
| 348 | static int may_context_mount_inode_relabel(u32 sid, | 374 | static int may_context_mount_inode_relabel(u32 sid, |
| 349 | struct superblock_security_struct *sbsec, | 375 | struct superblock_security_struct *sbsec, |
| 350 | struct task_security_struct *tsec) | 376 | const struct cred *cred) |
| 351 | { | 377 | { |
| 378 | const struct task_security_struct *tsec = cred->security; | ||
| 352 | int rc; | 379 | int rc; |
| 353 | rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM, | 380 | rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM, |
| 354 | FILESYSTEM__RELABELFROM, NULL); | 381 | FILESYSTEM__RELABELFROM, NULL); |
| @@ -546,8 +573,8 @@ static int bad_option(struct superblock_security_struct *sbsec, char flag, | |||
| 546 | static int selinux_set_mnt_opts(struct super_block *sb, | 573 | static int selinux_set_mnt_opts(struct super_block *sb, |
| 547 | struct security_mnt_opts *opts) | 574 | struct security_mnt_opts *opts) |
| 548 | { | 575 | { |
| 576 | const struct cred *cred = current_cred(); | ||
| 549 | int rc = 0, i; | 577 | int rc = 0, i; |
| 550 | struct task_security_struct *tsec = current->cred->security; | ||
| 551 | struct superblock_security_struct *sbsec = sb->s_security; | 578 | struct superblock_security_struct *sbsec = sb->s_security; |
| 552 | const char *name = sb->s_type->name; | 579 | const char *name = sb->s_type->name; |
| 553 | struct inode *inode = sbsec->sb->s_root->d_inode; | 580 | struct inode *inode = sbsec->sb->s_root->d_inode; |
| @@ -673,8 +700,7 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
| 673 | 700 | ||
| 674 | /* sets the context of the superblock for the fs being mounted. */ | 701 | /* sets the context of the superblock for the fs being mounted. */ |
| 675 | if (fscontext_sid) { | 702 | if (fscontext_sid) { |
| 676 | 703 | rc = may_context_mount_sb_relabel(fscontext_sid, sbsec, cred); | |
| 677 | rc = may_context_mount_sb_relabel(fscontext_sid, sbsec, tsec); | ||
| 678 | if (rc) | 704 | if (rc) |
| 679 | goto out; | 705 | goto out; |
| 680 | 706 | ||
| @@ -688,12 +714,14 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
| 688 | */ | 714 | */ |
| 689 | if (context_sid) { | 715 | if (context_sid) { |
| 690 | if (!fscontext_sid) { | 716 | if (!fscontext_sid) { |
| 691 | rc = may_context_mount_sb_relabel(context_sid, sbsec, tsec); | 717 | rc = may_context_mount_sb_relabel(context_sid, sbsec, |
| 718 | cred); | ||
| 692 | if (rc) | 719 | if (rc) |
| 693 | goto out; | 720 | goto out; |
| 694 | sbsec->sid = context_sid; | 721 | sbsec->sid = context_sid; |
| 695 | } else { | 722 | } else { |
| 696 | rc = may_context_mount_inode_relabel(context_sid, sbsec, tsec); | 723 | rc = may_context_mount_inode_relabel(context_sid, sbsec, |
| 724 | cred); | ||
| 697 | if (rc) | 725 | if (rc) |
| 698 | goto out; | 726 | goto out; |
| 699 | } | 727 | } |
| @@ -705,7 +733,8 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
| 705 | } | 733 | } |
| 706 | 734 | ||
| 707 | if (rootcontext_sid) { | 735 | if (rootcontext_sid) { |
| 708 | rc = may_context_mount_inode_relabel(rootcontext_sid, sbsec, tsec); | 736 | rc = may_context_mount_inode_relabel(rootcontext_sid, sbsec, |
| 737 | cred); | ||
| 709 | if (rc) | 738 | if (rc) |
| 710 | goto out; | 739 | goto out; |
| 711 | 740 | ||
| @@ -723,7 +752,7 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
| 723 | 752 | ||
| 724 | if (defcontext_sid != sbsec->def_sid) { | 753 | if (defcontext_sid != sbsec->def_sid) { |
| 725 | rc = may_context_mount_inode_relabel(defcontext_sid, | 754 | rc = may_context_mount_inode_relabel(defcontext_sid, |
| 726 | sbsec, tsec); | 755 | sbsec, cred); |
| 727 | if (rc) | 756 | if (rc) |
| 728 | goto out; | 757 | goto out; |
| 729 | } | 758 | } |
| @@ -1338,18 +1367,23 @@ static inline u32 signal_to_av(int sig) | |||
| 1338 | return perm; | 1367 | return perm; |
| 1339 | } | 1368 | } |
| 1340 | 1369 | ||
| 1341 | /* Check permission betweeen a pair of tasks, e.g. signal checks, | 1370 | /* |
| 1342 | fork check, ptrace check, etc. */ | 1371 | * Check permission betweeen a pair of tasks, e.g. signal checks, |
| 1343 | static int task_has_perm(struct task_struct *tsk1, | 1372 | * fork check, ptrace check, etc. |
| 1344 | struct task_struct *tsk2, | 1373 | * tsk1 is the actor and tsk2 is the target |
| 1374 | */ | ||
| 1375 | static int task_has_perm(const struct task_struct *tsk1, | ||
| 1376 | const struct task_struct *tsk2, | ||
| 1345 | u32 perms) | 1377 | u32 perms) |
| 1346 | { | 1378 | { |
| 1347 | struct task_security_struct *tsec1, *tsec2; | 1379 | const struct task_security_struct *__tsec1, *__tsec2; |
| 1380 | u32 sid1, sid2; | ||
| 1348 | 1381 | ||
| 1349 | tsec1 = tsk1->cred->security; | 1382 | rcu_read_lock(); |
| 1350 | tsec2 = tsk2->cred->security; | 1383 | __tsec1 = __task_cred(tsk1)->security; sid1 = __tsec1->sid; |
| 1351 | return avc_has_perm(tsec1->sid, tsec2->sid, | 1384 | __tsec2 = __task_cred(tsk2)->security; sid2 = __tsec2->sid; |
| 1352 | SECCLASS_PROCESS, perms, NULL); | 1385 | rcu_read_unlock(); |
| 1386 | return avc_has_perm(sid1, sid2, SECCLASS_PROCESS, perms, NULL); | ||
| 1353 | } | 1387 | } |
| 1354 | 1388 | ||
| 1355 | #if CAP_LAST_CAP > 63 | 1389 | #if CAP_LAST_CAP > 63 |
| @@ -1360,15 +1394,13 @@ static int task_has_perm(struct task_struct *tsk1, | |||
| 1360 | static int task_has_capability(struct task_struct *tsk, | 1394 | static int task_has_capability(struct task_struct *tsk, |
| 1361 | int cap, int audit) | 1395 | int cap, int audit) |
| 1362 | { | 1396 | { |
| 1363 | struct task_security_struct *tsec; | ||
| 1364 | struct avc_audit_data ad; | 1397 | struct avc_audit_data ad; |
| 1365 | struct av_decision avd; | 1398 | struct av_decision avd; |
| 1366 | u16 sclass; | 1399 | u16 sclass; |
| 1400 | u32 sid = task_sid(tsk); | ||
| 1367 | u32 av = CAP_TO_MASK(cap); | 1401 | u32 av = CAP_TO_MASK(cap); |
| 1368 | int rc; | 1402 | int rc; |
| 1369 | 1403 | ||
| 1370 | tsec = tsk->cred->security; | ||
| 1371 | |||
| 1372 | AVC_AUDIT_DATA_INIT(&ad, CAP); | 1404 | AVC_AUDIT_DATA_INIT(&ad, CAP); |
| 1373 | ad.tsk = tsk; | 1405 | ad.tsk = tsk; |
| 1374 | ad.u.cap = cap; | 1406 | ad.u.cap = cap; |
| @@ -1386,9 +1418,9 @@ static int task_has_capability(struct task_struct *tsk, | |||
| 1386 | BUG(); | 1418 | BUG(); |
| 1387 | } | 1419 | } |
| 1388 | 1420 | ||
| 1389 | rc = avc_has_perm_noaudit(tsec->sid, tsec->sid, sclass, av, 0, &avd); | 1421 | rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd); |
| 1390 | if (audit == SECURITY_CAP_AUDIT) | 1422 | if (audit == SECURITY_CAP_AUDIT) |
| 1391 | avc_audit(tsec->sid, tsec->sid, sclass, av, &avd, rc, &ad); | 1423 | avc_audit(sid, sid, sclass, av, &avd, rc, &ad); |
| 1392 | return rc; | 1424 | return rc; |
| 1393 | } | 1425 | } |
| 1394 | 1426 | ||
| @@ -1396,11 +1428,9 @@ static int task_has_capability(struct task_struct *tsk, | |||
| 1396 | static int task_has_system(struct task_struct *tsk, | 1428 | static int task_has_system(struct task_struct *tsk, |
| 1397 | u32 perms) | 1429 | u32 perms) |
| 1398 | { | 1430 | { |
| 1399 | struct task_security_struct *tsec; | 1431 | u32 sid = task_sid(tsk); |
| 1400 | |||
| 1401 | tsec = tsk->cred->security; | ||
| 1402 | 1432 | ||
| 1403 | return avc_has_perm(tsec->sid, SECINITSID_KERNEL, | 1433 | return avc_has_perm(sid, SECINITSID_KERNEL, |
| 1404 | SECCLASS_SYSTEM, perms, NULL); | 1434 | SECCLASS_SYSTEM, perms, NULL); |
| 1405 | } | 1435 | } |
| 1406 | 1436 | ||
| @@ -1412,14 +1442,14 @@ static int inode_has_perm(struct task_struct *tsk, | |||
| 1412 | u32 perms, | 1442 | u32 perms, |
| 1413 | struct avc_audit_data *adp) | 1443 | struct avc_audit_data *adp) |
| 1414 | { | 1444 | { |
| 1415 | struct task_security_struct *tsec; | ||
| 1416 | struct inode_security_struct *isec; | 1445 | struct inode_security_struct *isec; |
| 1417 | struct avc_audit_data ad; | 1446 | struct avc_audit_data ad; |
| 1447 | u32 sid; | ||
| 1418 | 1448 | ||
| 1419 | if (unlikely(IS_PRIVATE(inode))) | 1449 | if (unlikely(IS_PRIVATE(inode))) |
| 1420 | return 0; | 1450 | return 0; |
| 1421 | 1451 | ||
| 1422 | tsec = tsk->cred->security; | 1452 | sid = task_sid(tsk); |
| 1423 | isec = inode->i_security; | 1453 | isec = inode->i_security; |
| 1424 | 1454 | ||
| 1425 | if (!adp) { | 1455 | if (!adp) { |
| @@ -1428,7 +1458,7 @@ static int inode_has_perm(struct task_struct *tsk, | |||
| 1428 | ad.u.fs.inode = inode; | 1458 | ad.u.fs.inode = inode; |
| 1429 | } | 1459 | } |
| 1430 | 1460 | ||
| 1431 | return avc_has_perm(tsec->sid, isec->sid, isec->sclass, perms, adp); | 1461 | return avc_has_perm(sid, isec->sid, isec->sclass, perms, adp); |
| 1432 | } | 1462 | } |
| 1433 | 1463 | ||
| 1434 | /* Same as inode_has_perm, but pass explicit audit data containing | 1464 | /* Same as inode_has_perm, but pass explicit audit data containing |
| @@ -1459,17 +1489,17 @@ static int file_has_perm(struct task_struct *tsk, | |||
| 1459 | struct file *file, | 1489 | struct file *file, |
| 1460 | u32 av) | 1490 | u32 av) |
| 1461 | { | 1491 | { |
| 1462 | struct task_security_struct *tsec = tsk->cred->security; | ||
| 1463 | struct file_security_struct *fsec = file->f_security; | 1492 | struct file_security_struct *fsec = file->f_security; |
| 1464 | struct inode *inode = file->f_path.dentry->d_inode; | 1493 | struct inode *inode = file->f_path.dentry->d_inode; |
| 1465 | struct avc_audit_data ad; | 1494 | struct avc_audit_data ad; |
| 1495 | u32 sid = task_sid(tsk); | ||
| 1466 | int rc; | 1496 | int rc; |
| 1467 | 1497 | ||
| 1468 | AVC_AUDIT_DATA_INIT(&ad, FS); | 1498 | AVC_AUDIT_DATA_INIT(&ad, FS); |
| 1469 | ad.u.fs.path = file->f_path; | 1499 | ad.u.fs.path = file->f_path; |
| 1470 | 1500 | ||
| 1471 | if (tsec->sid != fsec->sid) { | 1501 | if (sid != fsec->sid) { |
| 1472 | rc = avc_has_perm(tsec->sid, fsec->sid, | 1502 | rc = avc_has_perm(sid, fsec->sid, |
| 1473 | SECCLASS_FD, | 1503 | SECCLASS_FD, |
| 1474 | FD__USE, | 1504 | FD__USE, |
| 1475 | &ad); | 1505 | &ad); |
| @@ -1489,36 +1519,36 @@ static int may_create(struct inode *dir, | |||
| 1489 | struct dentry *dentry, | 1519 | struct dentry *dentry, |
| 1490 | u16 tclass) | 1520 | u16 tclass) |
| 1491 | { | 1521 | { |
| 1492 | struct task_security_struct *tsec; | 1522 | const struct cred *cred = current_cred(); |
| 1523 | const struct task_security_struct *tsec = cred->security; | ||
| 1493 | struct inode_security_struct *dsec; | 1524 | struct inode_security_struct *dsec; |
| 1494 | struct superblock_security_struct *sbsec; | 1525 | struct superblock_security_struct *sbsec; |
| 1495 | u32 newsid; | 1526 | u32 sid, newsid; |
| 1496 | struct avc_audit_data ad; | 1527 | struct avc_audit_data ad; |
| 1497 | int rc; | 1528 | int rc; |
| 1498 | 1529 | ||
| 1499 | tsec = current->cred->security; | ||
| 1500 | dsec = dir->i_security; | 1530 | dsec = dir->i_security; |
| 1501 | sbsec = dir->i_sb->s_security; | 1531 | sbsec = dir->i_sb->s_security; |
| 1502 | 1532 | ||
| 1533 | sid = tsec->sid; | ||
| 1534 | newsid = tsec->create_sid; | ||
| 1535 | |||
| 1503 | AVC_AUDIT_DATA_INIT(&ad, FS); | 1536 | AVC_AUDIT_DATA_INIT(&ad, FS); |
| 1504 | ad.u.fs.path.dentry = dentry; | 1537 | ad.u.fs.path.dentry = dentry; |
| 1505 | 1538 | ||
| 1506 | rc = avc_has_perm(tsec->sid, dsec->sid, SECCLASS_DIR, | 1539 | rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR, |
| 1507 | DIR__ADD_NAME | DIR__SEARCH, | 1540 | DIR__ADD_NAME | DIR__SEARCH, |
| 1508 | &ad); | 1541 | &ad); |
| 1509 | if (rc) | 1542 | if (rc) |
| 1510 | return rc; | 1543 | return rc; |
| 1511 | 1544 | ||
| 1512 | if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) { | 1545 | if (!newsid || sbsec->behavior == SECURITY_FS_USE_MNTPOINT) { |
| 1513 | newsid = tsec->create_sid; | 1546 | rc = security_transition_sid(sid, dsec->sid, tclass, &newsid); |
| 1514 | } else { | ||
| 1515 | rc = security_transition_sid(tsec->sid, dsec->sid, tclass, | ||
| 1516 | &newsid); | ||
| 1517 | if (rc) | 1547 | if (rc) |
| 1518 | return rc; | 1548 | return rc; |
| 1519 | } | 1549 | } |
| 1520 | 1550 | ||
| 1521 | rc = avc_has_perm(tsec->sid, newsid, tclass, FILE__CREATE, &ad); | 1551 | rc = avc_has_perm(sid, newsid, tclass, FILE__CREATE, &ad); |
| 1522 | if (rc) | 1552 | if (rc) |
| 1523 | return rc; | 1553 | return rc; |
| 1524 | 1554 | ||
| @@ -1531,11 +1561,9 @@ static int may_create(struct inode *dir, | |||
| 1531 | static int may_create_key(u32 ksid, | 1561 | static int may_create_key(u32 ksid, |
| 1532 | struct task_struct *ctx) | 1562 | struct task_struct *ctx) |
| 1533 | { | 1563 | { |
| 1534 | struct task_security_struct *tsec; | 1564 | u32 sid = task_sid(ctx); |
| 1535 | |||
| 1536 | tsec = ctx->cred->security; | ||
| 1537 | 1565 | ||
| 1538 | return avc_has_perm(tsec->sid, ksid, SECCLASS_KEY, KEY__CREATE, NULL); | 1566 | return avc_has_perm(sid, ksid, SECCLASS_KEY, KEY__CREATE, NULL); |
| 1539 | } | 1567 | } |
| 1540 | 1568 | ||
| 1541 | #define MAY_LINK 0 | 1569 | #define MAY_LINK 0 |
| @@ -1548,13 +1576,12 @@ static int may_link(struct inode *dir, | |||
| 1548 | int kind) | 1576 | int kind) |
| 1549 | 1577 | ||
| 1550 | { | 1578 | { |
| 1551 | struct task_security_struct *tsec; | ||
| 1552 | struct inode_security_struct *dsec, *isec; | 1579 | struct inode_security_struct *dsec, *isec; |
| 1553 | struct avc_audit_data ad; | 1580 | struct avc_audit_data ad; |
| 1581 | u32 sid = current_sid(); | ||
| 1554 | u32 av; | 1582 | u32 av; |
| 1555 | int rc; | 1583 | int rc; |
| 1556 | 1584 | ||
| 1557 | tsec = current->cred->security; | ||
| 1558 | dsec = dir->i_security; | 1585 | dsec = dir->i_security; |
| 1559 | isec = dentry->d_inode->i_security; | 1586 | isec = dentry->d_inode->i_security; |
| 1560 | 1587 | ||
| @@ -1563,7 +1590,7 @@ static int may_link(struct inode *dir, | |||
| 1563 | 1590 | ||
| 1564 | av = DIR__SEARCH; | 1591 | av = DIR__SEARCH; |
| 1565 | av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME); | 1592 | av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME); |
| 1566 | rc = avc_has_perm(tsec->sid, dsec->sid, SECCLASS_DIR, av, &ad); | 1593 | rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR, av, &ad); |
| 1567 | if (rc) | 1594 | if (rc) |
| 1568 | return rc; | 1595 | return rc; |
| 1569 | 1596 | ||
| @@ -1583,7 +1610,7 @@ static int may_link(struct inode *dir, | |||
| 1583 | return 0; | 1610 | return 0; |
| 1584 | } | 1611 | } |
| 1585 | 1612 | ||
| 1586 | rc = avc_has_perm(tsec->sid, isec->sid, isec->sclass, av, &ad); | 1613 | rc = avc_has_perm(sid, isec->sid, isec->sclass, av, &ad); |
| 1587 | return rc; | 1614 | return rc; |
| 1588 | } | 1615 | } |
| 1589 | 1616 | ||
| @@ -1592,14 +1619,13 @@ static inline int may_rename(struct inode *old_dir, | |||
| 1592 | struct inode *new_dir, | 1619 | struct inode *new_dir, |
| 1593 | struct dentry *new_dentry) | 1620 | struct dentry *new_dentry) |
| 1594 | { | 1621 | { |
| 1595 | struct task_security_struct *tsec; | ||
| 1596 | struct inode_security_struct *old_dsec, *new_dsec, *old_isec, *new_isec; | 1622 | struct inode_security_struct *old_dsec, *new_dsec, *old_isec, *new_isec; |
| 1597 | struct avc_audit_data ad; | 1623 | struct avc_audit_data ad; |
| 1624 | u32 sid = current_sid(); | ||
| 1598 | u32 av; | 1625 | u32 av; |
| 1599 | int old_is_dir, new_is_dir; | 1626 | int old_is_dir, new_is_dir; |
| 1600 | int rc; | 1627 | int rc; |
| 1601 | 1628 | ||
| 1602 | tsec = current->cred->security; | ||
| 1603 | old_dsec = old_dir->i_security; | 1629 | old_dsec = old_dir->i_security; |
| 1604 | old_isec = old_dentry->d_inode->i_security; | 1630 | old_isec = old_dentry->d_inode->i_security; |
| 1605 | old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode); | 1631 | old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode); |
| @@ -1608,16 +1634,16 @@ static inline int may_rename(struct inode *old_dir, | |||
| 1608 | AVC_AUDIT_DATA_INIT(&ad, FS); | 1634 | AVC_AUDIT_DATA_INIT(&ad, FS); |
| 1609 | 1635 | ||
| 1610 | ad.u.fs.path.dentry = old_dentry; | 1636 | ad.u.fs.path.dentry = old_dentry; |
| 1611 | rc = avc_has_perm(tsec->sid, old_dsec->sid, SECCLASS_DIR, | 1637 | rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR, |
| 1612 | DIR__REMOVE_NAME | DIR__SEARCH, &ad); | 1638 | DIR__REMOVE_NAME | DIR__SEARCH, &ad); |
| 1613 | if (rc) | 1639 | if (rc) |
| 1614 | return rc; | 1640 | return rc; |
| 1615 | rc = avc_has_perm(tsec->sid, old_isec->sid, | 1641 | rc = avc_has_perm(sid, old_isec->sid, |
| 1616 | old_isec->sclass, FILE__RENAME, &ad); | 1642 | old_isec->sclass, FILE__RENAME, &ad); |
| 1617 | if (rc) | 1643 | if (rc) |
| 1618 | return rc; | 1644 | return rc; |
| 1619 | if (old_is_dir && new_dir != old_dir) { | 1645 | if (old_is_dir && new_dir != old_dir) { |
| 1620 | rc = avc_has_perm(tsec->sid, old_isec->sid, | 1646 | rc = avc_has_perm(sid, old_isec->sid, |
| 1621 | old_isec->sclass, DIR__REPARENT, &ad); | 1647 | old_isec->sclass, DIR__REPARENT, &ad); |
| 1622 | if (rc) | 1648 | if (rc) |
| 1623 | return rc; | 1649 | return rc; |
| @@ -1627,13 +1653,13 @@ static inline int may_rename(struct inode *old_dir, | |||
| 1627 | av = DIR__ADD_NAME | DIR__SEARCH; | 1653 | av = DIR__ADD_NAME | DIR__SEARCH; |
| 1628 | if (new_dentry->d_inode) | 1654 | if (new_dentry->d_inode) |
| 1629 | av |= DIR__REMOVE_NAME; | 1655 | av |= DIR__REMOVE_NAME; |
| 1630 | rc = avc_has_perm(tsec->sid, new_dsec->sid, SECCLASS_DIR, av, &ad); | 1656 | rc = avc_has_perm(sid, new_dsec->sid, SECCLASS_DIR, av, &ad); |
| 1631 | if (rc) | 1657 | if (rc) |
| 1632 | return rc; | 1658 | return rc; |
| 1633 | if (new_dentry->d_inode) { | 1659 | if (new_dentry->d_inode) { |
| 1634 | new_isec = new_dentry->d_inode->i_security; | 1660 | new_isec = new_dentry->d_inode->i_security; |
| 1635 | new_is_dir = S_ISDIR(new_dentry->d_inode->i_mode); | 1661 | new_is_dir = S_ISDIR(new_dentry->d_inode->i_mode); |
| 1636 | rc = avc_has_perm(tsec->sid, new_isec->sid, | 1662 | rc = avc_has_perm(sid, new_isec->sid, |
| 1637 | new_isec->sclass, | 1663 | new_isec->sclass, |
| 1638 | (new_is_dir ? DIR__RMDIR : FILE__UNLINK), &ad); | 1664 | (new_is_dir ? DIR__RMDIR : FILE__UNLINK), &ad); |
| 1639 | if (rc) | 1665 | if (rc) |
| @@ -1649,13 +1675,11 @@ static int superblock_has_perm(struct task_struct *tsk, | |||
| 1649 | u32 perms, | 1675 | u32 perms, |
| 1650 | struct avc_audit_data *ad) | 1676 | struct avc_audit_data *ad) |
| 1651 | { | 1677 | { |
| 1652 | struct task_security_struct *tsec; | ||
| 1653 | struct superblock_security_struct *sbsec; | 1678 | struct superblock_security_struct *sbsec; |
| 1679 | u32 sid = task_sid(tsk); | ||
| 1654 | 1680 | ||
| 1655 | tsec = tsk->cred->security; | ||
| 1656 | sbsec = sb->s_security; | 1681 | sbsec = sb->s_security; |
| 1657 | return avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM, | 1682 | return avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM, perms, ad); |
| 1658 | perms, ad); | ||
| 1659 | } | 1683 | } |
| 1660 | 1684 | ||
| 1661 | /* Convert a Linux mode and permission mask to an access vector. */ | 1685 | /* Convert a Linux mode and permission mask to an access vector. */ |
| @@ -1751,10 +1775,9 @@ static int selinux_ptrace_may_access(struct task_struct *child, | |||
| 1751 | return rc; | 1775 | return rc; |
| 1752 | 1776 | ||
| 1753 | if (mode == PTRACE_MODE_READ) { | 1777 | if (mode == PTRACE_MODE_READ) { |
| 1754 | struct task_security_struct *tsec = current->cred->security; | 1778 | u32 sid = current_sid(); |
| 1755 | struct task_security_struct *csec = child->cred->security; | 1779 | u32 csid = task_sid(child); |
| 1756 | return avc_has_perm(tsec->sid, csec->sid, | 1780 | return avc_has_perm(sid, csid, SECCLASS_FILE, FILE__READ, NULL); |
| 1757 | SECCLASS_FILE, FILE__READ, NULL); | ||
| 1758 | } | 1781 | } |
| 1759 | 1782 | ||
| 1760 | return task_has_perm(current, child, PROCESS__PTRACE); | 1783 | return task_has_perm(current, child, PROCESS__PTRACE); |
| @@ -1859,15 +1882,14 @@ static int selinux_sysctl(ctl_table *table, int op) | |||
| 1859 | { | 1882 | { |
| 1860 | int error = 0; | 1883 | int error = 0; |
| 1861 | u32 av; | 1884 | u32 av; |
| 1862 | struct task_security_struct *tsec; | 1885 | u32 tsid, sid; |
| 1863 | u32 tsid; | ||
| 1864 | int rc; | 1886 | int rc; |
| 1865 | 1887 | ||
| 1866 | rc = secondary_ops->sysctl(table, op); | 1888 | rc = secondary_ops->sysctl(table, op); |
| 1867 | if (rc) | 1889 | if (rc) |
| 1868 | return rc; | 1890 | return rc; |
| 1869 | 1891 | ||
| 1870 | tsec = current->cred->security; | 1892 | sid = current_sid(); |
| 1871 | 1893 | ||
| 1872 | rc = selinux_sysctl_get_sid(table, (op == 0001) ? | 1894 | rc = selinux_sysctl_get_sid(table, (op == 0001) ? |
| 1873 | SECCLASS_DIR : SECCLASS_FILE, &tsid); | 1895 | SECCLASS_DIR : SECCLASS_FILE, &tsid); |
| @@ -1879,7 +1901,7 @@ static int selinux_sysctl(ctl_table *table, int op) | |||
| 1879 | /* The op values are "defined" in sysctl.c, thereby creating | 1901 | /* The op values are "defined" in sysctl.c, thereby creating |
| 1880 | * a bad coupling between this module and sysctl.c */ | 1902 | * a bad coupling between this module and sysctl.c */ |
| 1881 | if (op == 001) { | 1903 | if (op == 001) { |
| 1882 | error = avc_has_perm(tsec->sid, tsid, | 1904 | error = avc_has_perm(sid, tsid, |
| 1883 | SECCLASS_DIR, DIR__SEARCH, NULL); | 1905 | SECCLASS_DIR, DIR__SEARCH, NULL); |
| 1884 | } else { | 1906 | } else { |
| 1885 | av = 0; | 1907 | av = 0; |
| @@ -1888,7 +1910,7 @@ static int selinux_sysctl(ctl_table *table, int op) | |||
| 1888 | if (op & 002) | 1910 | if (op & 002) |
| 1889 | av |= FILE__WRITE; | 1911 | av |= FILE__WRITE; |
| 1890 | if (av) | 1912 | if (av) |
| 1891 | error = avc_has_perm(tsec->sid, tsid, | 1913 | error = avc_has_perm(sid, tsid, |
| 1892 | SECCLASS_FILE, av, NULL); | 1914 | SECCLASS_FILE, av, NULL); |
| 1893 | } | 1915 | } |
| 1894 | 1916 | ||
| @@ -2018,7 +2040,7 @@ static int selinux_bprm_set_security(struct linux_binprm *bprm) | |||
| 2018 | if (bsec->set) | 2040 | if (bsec->set) |
| 2019 | return 0; | 2041 | return 0; |
| 2020 | 2042 | ||
| 2021 | tsec = current->cred->security; | 2043 | tsec = current_security(); |
| 2022 | isec = inode->i_security; | 2044 | isec = inode->i_security; |
| 2023 | 2045 | ||
| 2024 | /* Default to the current task SID. */ | 2046 | /* Default to the current task SID. */ |
| @@ -2083,14 +2105,19 @@ static int selinux_bprm_check_security(struct linux_binprm *bprm) | |||
| 2083 | 2105 | ||
| 2084 | static int selinux_bprm_secureexec(struct linux_binprm *bprm) | 2106 | static int selinux_bprm_secureexec(struct linux_binprm *bprm) |
| 2085 | { | 2107 | { |
| 2086 | struct task_security_struct *tsec = current->cred->security; | 2108 | const struct cred *cred = current_cred(); |
| 2109 | const struct task_security_struct *tsec = cred->security; | ||
| 2110 | u32 sid, osid; | ||
| 2087 | int atsecure = 0; | 2111 | int atsecure = 0; |
| 2088 | 2112 | ||
| 2089 | if (tsec->osid != tsec->sid) { | 2113 | sid = tsec->sid; |
| 2114 | osid = tsec->osid; | ||
| 2115 | |||
| 2116 | if (osid != sid) { | ||
| 2090 | /* Enable secure mode for SIDs transitions unless | 2117 | /* Enable secure mode for SIDs transitions unless |
| 2091 | the noatsecure permission is granted between | 2118 | the noatsecure permission is granted between |
| 2092 | the two SIDs, i.e. ahp returns 0. */ | 2119 | the two SIDs, i.e. ahp returns 0. */ |
| 2093 | atsecure = avc_has_perm(tsec->osid, tsec->sid, | 2120 | atsecure = avc_has_perm(osid, sid, |
| 2094 | SECCLASS_PROCESS, | 2121 | SECCLASS_PROCESS, |
| 2095 | PROCESS__NOATSECURE, NULL); | 2122 | PROCESS__NOATSECURE, NULL); |
| 2096 | } | 2123 | } |
| @@ -2207,7 +2234,7 @@ static void selinux_bprm_apply_creds(struct linux_binprm *bprm, int unsafe) | |||
| 2207 | 2234 | ||
| 2208 | secondary_ops->bprm_apply_creds(bprm, unsafe); | 2235 | secondary_ops->bprm_apply_creds(bprm, unsafe); |
| 2209 | 2236 | ||
| 2210 | tsec = current->cred->security; | 2237 | tsec = current_security(); |
| 2211 | 2238 | ||
| 2212 | bsec = bprm->security; | 2239 | bsec = bprm->security; |
| 2213 | sid = bsec->sid; | 2240 | sid = bsec->sid; |
| @@ -2236,7 +2263,7 @@ static void selinux_bprm_apply_creds(struct linux_binprm *bprm, int unsafe) | |||
| 2236 | rcu_read_lock(); | 2263 | rcu_read_lock(); |
| 2237 | tracer = tracehook_tracer_task(current); | 2264 | tracer = tracehook_tracer_task(current); |
| 2238 | if (likely(tracer != NULL)) { | 2265 | if (likely(tracer != NULL)) { |
| 2239 | sec = tracer->cred->security; | 2266 | sec = __task_cred(tracer)->security; |
| 2240 | ptsid = sec->sid; | 2267 | ptsid = sec->sid; |
| 2241 | } | 2268 | } |
| 2242 | rcu_read_unlock(); | 2269 | rcu_read_unlock(); |
| @@ -2267,7 +2294,7 @@ static void selinux_bprm_post_apply_creds(struct linux_binprm *bprm) | |||
| 2267 | int rc, i; | 2294 | int rc, i; |
| 2268 | unsigned long flags; | 2295 | unsigned long flags; |
| 2269 | 2296 | ||
| 2270 | tsec = current->cred->security; | 2297 | tsec = current_security(); |
| 2271 | bsec = bprm->security; | 2298 | bsec = bprm->security; |
| 2272 | 2299 | ||
| 2273 | if (bsec->unsafe) { | 2300 | if (bsec->unsafe) { |
| @@ -2507,21 +2534,22 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, | |||
| 2507 | char **name, void **value, | 2534 | char **name, void **value, |
| 2508 | size_t *len) | 2535 | size_t *len) |
| 2509 | { | 2536 | { |
| 2510 | struct task_security_struct *tsec; | 2537 | const struct cred *cred = current_cred(); |
| 2538 | const struct task_security_struct *tsec = cred->security; | ||
| 2511 | struct inode_security_struct *dsec; | 2539 | struct inode_security_struct *dsec; |
| 2512 | struct superblock_security_struct *sbsec; | 2540 | struct superblock_security_struct *sbsec; |
| 2513 | u32 newsid, clen; | 2541 | u32 sid, newsid, clen; |
| 2514 | int rc; | 2542 | int rc; |
| 2515 | char *namep = NULL, *context; | 2543 | char *namep = NULL, *context; |
| 2516 | 2544 | ||
| 2517 | tsec = current->cred->security; | ||
| 2518 | dsec = dir->i_security; | 2545 | dsec = dir->i_security; |
| 2519 | sbsec = dir->i_sb->s_security; | 2546 | sbsec = dir->i_sb->s_security; |
| 2520 | 2547 | ||
| 2521 | if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) { | 2548 | sid = tsec->sid; |
| 2522 | newsid = tsec->create_sid; | 2549 | newsid = tsec->create_sid; |
| 2523 | } else { | 2550 | |
| 2524 | rc = security_transition_sid(tsec->sid, dsec->sid, | 2551 | if (!newsid || sbsec->behavior == SECURITY_FS_USE_MNTPOINT) { |
| 2552 | rc = security_transition_sid(sid, dsec->sid, | ||
| 2525 | inode_mode_to_security_class(inode->i_mode), | 2553 | inode_mode_to_security_class(inode->i_mode), |
| 2526 | &newsid); | 2554 | &newsid); |
| 2527 | if (rc) { | 2555 | if (rc) { |
| @@ -2699,12 +2727,11 @@ static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name) | |||
| 2699 | static int selinux_inode_setxattr(struct dentry *dentry, const char *name, | 2727 | static int selinux_inode_setxattr(struct dentry *dentry, const char *name, |
| 2700 | const void *value, size_t size, int flags) | 2728 | const void *value, size_t size, int flags) |
| 2701 | { | 2729 | { |
| 2702 | struct task_security_struct *tsec = current->cred->security; | ||
| 2703 | struct inode *inode = dentry->d_inode; | 2730 | struct inode *inode = dentry->d_inode; |
| 2704 | struct inode_security_struct *isec = inode->i_security; | 2731 | struct inode_security_struct *isec = inode->i_security; |
| 2705 | struct superblock_security_struct *sbsec; | 2732 | struct superblock_security_struct *sbsec; |
| 2706 | struct avc_audit_data ad; | 2733 | struct avc_audit_data ad; |
| 2707 | u32 newsid; | 2734 | u32 newsid, sid = current_sid(); |
| 2708 | int rc = 0; | 2735 | int rc = 0; |
| 2709 | 2736 | ||
| 2710 | if (strcmp(name, XATTR_NAME_SELINUX)) | 2737 | if (strcmp(name, XATTR_NAME_SELINUX)) |
| @@ -2720,7 +2747,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, | |||
| 2720 | AVC_AUDIT_DATA_INIT(&ad, FS); | 2747 | AVC_AUDIT_DATA_INIT(&ad, FS); |
| 2721 | ad.u.fs.path.dentry = dentry; | 2748 | ad.u.fs.path.dentry = dentry; |
| 2722 | 2749 | ||
| 2723 | rc = avc_has_perm(tsec->sid, isec->sid, isec->sclass, | 2750 | rc = avc_has_perm(sid, isec->sid, isec->sclass, |
| 2724 | FILE__RELABELFROM, &ad); | 2751 | FILE__RELABELFROM, &ad); |
| 2725 | if (rc) | 2752 | if (rc) |
| 2726 | return rc; | 2753 | return rc; |
| @@ -2734,12 +2761,12 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, | |||
| 2734 | if (rc) | 2761 | if (rc) |
| 2735 | return rc; | 2762 | return rc; |
| 2736 | 2763 | ||
| 2737 | rc = avc_has_perm(tsec->sid, newsid, isec->sclass, | 2764 | rc = avc_has_perm(sid, newsid, isec->sclass, |
| 2738 | FILE__RELABELTO, &ad); | 2765 | FILE__RELABELTO, &ad); |
| 2739 | if (rc) | 2766 | if (rc) |
| 2740 | return rc; | 2767 | return rc; |
| 2741 | 2768 | ||
| 2742 | rc = security_validate_transition(isec->sid, newsid, tsec->sid, | 2769 | rc = security_validate_transition(isec->sid, newsid, sid, |
| 2743 | isec->sclass); | 2770 | isec->sclass); |
| 2744 | if (rc) | 2771 | if (rc) |
| 2745 | return rc; | 2772 | return rc; |
| @@ -2911,16 +2938,16 @@ static int selinux_revalidate_file_permission(struct file *file, int mask) | |||
| 2911 | static int selinux_file_permission(struct file *file, int mask) | 2938 | static int selinux_file_permission(struct file *file, int mask) |
| 2912 | { | 2939 | { |
| 2913 | struct inode *inode = file->f_path.dentry->d_inode; | 2940 | struct inode *inode = file->f_path.dentry->d_inode; |
| 2914 | struct task_security_struct *tsec = current->cred->security; | ||
| 2915 | struct file_security_struct *fsec = file->f_security; | 2941 | struct file_security_struct *fsec = file->f_security; |
| 2916 | struct inode_security_struct *isec = inode->i_security; | 2942 | struct inode_security_struct *isec = inode->i_security; |
| 2943 | u32 sid = current_sid(); | ||
| 2917 | 2944 | ||
| 2918 | if (!mask) { | 2945 | if (!mask) { |
| 2919 | /* No permission to check. Existence test. */ | 2946 | /* No permission to check. Existence test. */ |
| 2920 | return 0; | 2947 | return 0; |
| 2921 | } | 2948 | } |
| 2922 | 2949 | ||
| 2923 | if (tsec->sid == fsec->sid && fsec->isid == isec->sid | 2950 | if (sid == fsec->sid && fsec->isid == isec->sid |
| 2924 | && fsec->pseqno == avc_policy_seqno()) | 2951 | && fsec->pseqno == avc_policy_seqno()) |
| 2925 | return selinux_netlbl_inode_permission(inode, mask); | 2952 | return selinux_netlbl_inode_permission(inode, mask); |
| 2926 | 2953 | ||
| @@ -2988,8 +3015,7 @@ static int selinux_file_mmap(struct file *file, unsigned long reqprot, | |||
| 2988 | unsigned long addr, unsigned long addr_only) | 3015 | unsigned long addr, unsigned long addr_only) |
| 2989 | { | 3016 | { |
| 2990 | int rc = 0; | 3017 | int rc = 0; |
| 2991 | u32 sid = ((struct task_security_struct *) | 3018 | u32 sid = current_sid(); |
| 2992 | (current->cred->security))->sid; | ||
| 2993 | 3019 | ||
| 2994 | if (addr < mmap_min_addr) | 3020 | if (addr < mmap_min_addr) |
| 2995 | rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT, | 3021 | rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT, |
| @@ -3098,12 +3124,10 @@ static int selinux_file_fcntl(struct file *file, unsigned int cmd, | |||
| 3098 | 3124 | ||
| 3099 | static int selinux_file_set_fowner(struct file *file) | 3125 | static int selinux_file_set_fowner(struct file *file) |
| 3100 | { | 3126 | { |
| 3101 | struct task_security_struct *tsec; | ||
| 3102 | struct file_security_struct *fsec; | 3127 | struct file_security_struct *fsec; |
| 3103 | 3128 | ||
| 3104 | tsec = current->cred->security; | ||
| 3105 | fsec = file->f_security; | 3129 | fsec = file->f_security; |
| 3106 | fsec->fown_sid = tsec->sid; | 3130 | fsec->fown_sid = current_sid(); |
| 3107 | 3131 | ||
| 3108 | return 0; | 3132 | return 0; |
| 3109 | } | 3133 | } |
| @@ -3112,14 +3136,13 @@ static int selinux_file_send_sigiotask(struct task_struct *tsk, | |||
| 3112 | struct fown_struct *fown, int signum) | 3136 | struct fown_struct *fown, int signum) |
| 3113 | { | 3137 | { |
| 3114 | struct file *file; | 3138 | struct file *file; |
| 3139 | u32 sid = current_sid(); | ||
| 3115 | u32 perm; | 3140 | u32 perm; |
| 3116 | struct task_security_struct *tsec; | ||
| 3117 | struct file_security_struct *fsec; | 3141 | struct file_security_struct *fsec; |
| 3118 | 3142 | ||
| 3119 | /* struct fown_struct is never outside the context of a struct file */ | 3143 | /* struct fown_struct is never outside the context of a struct file */ |
| 3120 | file = container_of(fown, struct file, f_owner); | 3144 | file = container_of(fown, struct file, f_owner); |
| 3121 | 3145 | ||
| 3122 | tsec = tsk->cred->security; | ||
| 3123 | fsec = file->f_security; | 3146 | fsec = file->f_security; |
| 3124 | 3147 | ||
| 3125 | if (!signum) | 3148 | if (!signum) |
| @@ -3127,7 +3150,7 @@ static int selinux_file_send_sigiotask(struct task_struct *tsk, | |||
| 3127 | else | 3150 | else |
| 3128 | perm = signal_to_av(signum); | 3151 | perm = signal_to_av(signum); |
| 3129 | 3152 | ||
| 3130 | return avc_has_perm(fsec->fown_sid, tsec->sid, | 3153 | return avc_has_perm(fsec->fown_sid, sid, |
| 3131 | SECCLASS_PROCESS, perm, NULL); | 3154 | SECCLASS_PROCESS, perm, NULL); |
| 3132 | } | 3155 | } |
| 3133 | 3156 | ||
| @@ -3182,7 +3205,7 @@ static int selinux_cred_alloc_security(struct cred *cred) | |||
| 3182 | struct task_security_struct *tsec1, *tsec2; | 3205 | struct task_security_struct *tsec1, *tsec2; |
| 3183 | int rc; | 3206 | int rc; |
| 3184 | 3207 | ||
| 3185 | tsec1 = current->cred->security; | 3208 | tsec1 = current_security(); |
| 3186 | 3209 | ||
| 3187 | rc = cred_alloc_security(cred); | 3210 | rc = cred_alloc_security(cred); |
| 3188 | if (rc) | 3211 | if (rc) |
| @@ -3250,8 +3273,7 @@ static int selinux_task_getsid(struct task_struct *p) | |||
| 3250 | 3273 | ||
| 3251 | static void selinux_task_getsecid(struct task_struct *p, u32 *secid) | 3274 | static void selinux_task_getsecid(struct task_struct *p, u32 *secid) |
| 3252 | { | 3275 | { |
| 3253 | struct task_security_struct *tsec = p->cred->security; | 3276 | *secid = task_sid(p); |
| 3254 | *secid = tsec->sid; | ||
| 3255 | } | 3277 | } |
| 3256 | 3278 | ||
| 3257 | static int selinux_task_setgroups(struct group_info *group_info) | 3279 | static int selinux_task_setgroups(struct group_info *group_info) |
| @@ -3332,7 +3354,6 @@ static int selinux_task_kill(struct task_struct *p, struct siginfo *info, | |||
| 3332 | { | 3354 | { |
| 3333 | u32 perm; | 3355 | u32 perm; |
| 3334 | int rc; | 3356 | int rc; |
| 3335 | struct task_security_struct *tsec; | ||
| 3336 | 3357 | ||
| 3337 | rc = secondary_ops->task_kill(p, info, sig, secid); | 3358 | rc = secondary_ops->task_kill(p, info, sig, secid); |
| 3338 | if (rc) | 3359 | if (rc) |
| @@ -3342,9 +3363,9 @@ static int selinux_task_kill(struct task_struct *p, struct siginfo *info, | |||
| 3342 | perm = PROCESS__SIGNULL; /* null signal; existence test */ | 3363 | perm = PROCESS__SIGNULL; /* null signal; existence test */ |
| 3343 | else | 3364 | else |
| 3344 | perm = signal_to_av(sig); | 3365 | perm = signal_to_av(sig); |
| 3345 | tsec = p->cred->security; | ||
| 3346 | if (secid) | 3366 | if (secid) |
| 3347 | rc = avc_has_perm(secid, tsec->sid, SECCLASS_PROCESS, perm, NULL); | 3367 | rc = avc_has_perm(secid, task_sid(p), |
| 3368 | SECCLASS_PROCESS, perm, NULL); | ||
| 3348 | else | 3369 | else |
| 3349 | rc = task_has_perm(current, p, perm); | 3370 | rc = task_has_perm(current, p, perm); |
| 3350 | return rc; | 3371 | return rc; |
| @@ -3383,12 +3404,11 @@ static void selinux_task_reparent_to_init(struct task_struct *p) | |||
| 3383 | static void selinux_task_to_inode(struct task_struct *p, | 3404 | static void selinux_task_to_inode(struct task_struct *p, |
| 3384 | struct inode *inode) | 3405 | struct inode *inode) |
| 3385 | { | 3406 | { |
| 3386 | struct task_security_struct *tsec = p->cred->security; | ||
| 3387 | struct inode_security_struct *isec = inode->i_security; | 3407 | struct inode_security_struct *isec = inode->i_security; |
| 3408 | u32 sid = task_sid(p); | ||
| 3388 | 3409 | ||
| 3389 | isec->sid = tsec->sid; | 3410 | isec->sid = sid; |
| 3390 | isec->initialized = 1; | 3411 | isec->initialized = 1; |
| 3391 | return; | ||
| 3392 | } | 3412 | } |
| 3393 | 3413 | ||
| 3394 | /* Returns error only if unable to parse addresses */ | 3414 | /* Returns error only if unable to parse addresses */ |
| @@ -3627,19 +3647,19 @@ static int socket_has_perm(struct task_struct *task, struct socket *sock, | |||
| 3627 | u32 perms) | 3647 | u32 perms) |
| 3628 | { | 3648 | { |
| 3629 | struct inode_security_struct *isec; | 3649 | struct inode_security_struct *isec; |
| 3630 | struct task_security_struct *tsec; | ||
| 3631 | struct avc_audit_data ad; | 3650 | struct avc_audit_data ad; |
| 3651 | u32 sid; | ||
| 3632 | int err = 0; | 3652 | int err = 0; |
| 3633 | 3653 | ||
| 3634 | tsec = task->cred->security; | ||
| 3635 | isec = SOCK_INODE(sock)->i_security; | 3654 | isec = SOCK_INODE(sock)->i_security; |
| 3636 | 3655 | ||
| 3637 | if (isec->sid == SECINITSID_KERNEL) | 3656 | if (isec->sid == SECINITSID_KERNEL) |
| 3638 | goto out; | 3657 | goto out; |
| 3658 | sid = task_sid(task); | ||
| 3639 | 3659 | ||
| 3640 | AVC_AUDIT_DATA_INIT(&ad, NET); | 3660 | AVC_AUDIT_DATA_INIT(&ad, NET); |
| 3641 | ad.u.net.sk = sock->sk; | 3661 | ad.u.net.sk = sock->sk; |
| 3642 | err = avc_has_perm(tsec->sid, isec->sid, isec->sclass, perms, &ad); | 3662 | err = avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad); |
| 3643 | 3663 | ||
| 3644 | out: | 3664 | out: |
| 3645 | return err; | 3665 | return err; |
| @@ -3648,18 +3668,20 @@ out: | |||
| 3648 | static int selinux_socket_create(int family, int type, | 3668 | static int selinux_socket_create(int family, int type, |
| 3649 | int protocol, int kern) | 3669 | int protocol, int kern) |
| 3650 | { | 3670 | { |
| 3671 | const struct cred *cred = current_cred(); | ||
| 3672 | const struct task_security_struct *tsec = cred->security; | ||
| 3673 | u32 sid, newsid; | ||
| 3674 | u16 secclass; | ||
| 3651 | int err = 0; | 3675 | int err = 0; |
| 3652 | struct task_security_struct *tsec; | ||
| 3653 | u32 newsid; | ||
| 3654 | 3676 | ||
| 3655 | if (kern) | 3677 | if (kern) |
| 3656 | goto out; | 3678 | goto out; |
| 3657 | 3679 | ||
| 3658 | tsec = current->cred->security; | 3680 | sid = tsec->sid; |
| 3659 | newsid = tsec->sockcreate_sid ? : tsec->sid; | 3681 | newsid = tsec->sockcreate_sid ?: sid; |
| 3660 | err = avc_has_perm(tsec->sid, newsid, | 3682 | |
| 3661 | socket_type_to_security_class(family, type, | 3683 | secclass = socket_type_to_security_class(family, type, protocol); |
| 3662 | protocol), SOCKET__CREATE, NULL); | 3684 | err = avc_has_perm(sid, newsid, secclass, SOCKET__CREATE, NULL); |
| 3663 | 3685 | ||
| 3664 | out: | 3686 | out: |
| 3665 | return err; | 3687 | return err; |
| @@ -3668,18 +3690,26 @@ out: | |||
| 3668 | static int selinux_socket_post_create(struct socket *sock, int family, | 3690 | static int selinux_socket_post_create(struct socket *sock, int family, |
| 3669 | int type, int protocol, int kern) | 3691 | int type, int protocol, int kern) |
| 3670 | { | 3692 | { |
| 3671 | int err = 0; | 3693 | const struct cred *cred = current_cred(); |
| 3694 | const struct task_security_struct *tsec = cred->security; | ||
| 3672 | struct inode_security_struct *isec; | 3695 | struct inode_security_struct *isec; |
| 3673 | struct task_security_struct *tsec; | ||
| 3674 | struct sk_security_struct *sksec; | 3696 | struct sk_security_struct *sksec; |
| 3675 | u32 newsid; | 3697 | u32 sid, newsid; |
| 3698 | int err = 0; | ||
| 3699 | |||
| 3700 | sid = tsec->sid; | ||
| 3701 | newsid = tsec->sockcreate_sid; | ||
| 3676 | 3702 | ||
| 3677 | isec = SOCK_INODE(sock)->i_security; | 3703 | isec = SOCK_INODE(sock)->i_security; |
| 3678 | 3704 | ||
| 3679 | tsec = current->cred->security; | 3705 | if (kern) |
| 3680 | newsid = tsec->sockcreate_sid ? : tsec->sid; | 3706 | isec->sid = SECINITSID_KERNEL; |
| 3707 | else if (newsid) | ||
| 3708 | isec->sid = newsid; | ||
| 3709 | else | ||
| 3710 | isec->sid = sid; | ||
| 3711 | |||
| 3681 | isec->sclass = socket_type_to_security_class(family, type, protocol); | 3712 | isec->sclass = socket_type_to_security_class(family, type, protocol); |
| 3682 | isec->sid = kern ? SECINITSID_KERNEL : newsid; | ||
| 3683 | isec->initialized = 1; | 3713 | isec->initialized = 1; |
| 3684 | 3714 | ||
| 3685 | if (sock->sk) { | 3715 | if (sock->sk) { |
| @@ -3714,7 +3744,6 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
| 3714 | if (family == PF_INET || family == PF_INET6) { | 3744 | if (family == PF_INET || family == PF_INET6) { |
| 3715 | char *addrp; | 3745 | char *addrp; |
| 3716 | struct inode_security_struct *isec; | 3746 | struct inode_security_struct *isec; |
| 3717 | struct task_security_struct *tsec; | ||
| 3718 | struct avc_audit_data ad; | 3747 | struct avc_audit_data ad; |
| 3719 | struct sockaddr_in *addr4 = NULL; | 3748 | struct sockaddr_in *addr4 = NULL; |
| 3720 | struct sockaddr_in6 *addr6 = NULL; | 3749 | struct sockaddr_in6 *addr6 = NULL; |
| @@ -3722,7 +3751,6 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
| 3722 | struct sock *sk = sock->sk; | 3751 | struct sock *sk = sock->sk; |
| 3723 | u32 sid, node_perm; | 3752 | u32 sid, node_perm; |
| 3724 | 3753 | ||
| 3725 | tsec = current->cred->security; | ||
| 3726 | isec = SOCK_INODE(sock)->i_security; | 3754 | isec = SOCK_INODE(sock)->i_security; |
| 3727 | 3755 | ||
| 3728 | if (family == PF_INET) { | 3756 | if (family == PF_INET) { |
| @@ -4763,15 +4791,16 @@ static int ipc_alloc_security(struct task_struct *task, | |||
| 4763 | struct kern_ipc_perm *perm, | 4791 | struct kern_ipc_perm *perm, |
| 4764 | u16 sclass) | 4792 | u16 sclass) |
| 4765 | { | 4793 | { |
| 4766 | struct task_security_struct *tsec = task->cred->security; | ||
| 4767 | struct ipc_security_struct *isec; | 4794 | struct ipc_security_struct *isec; |
| 4795 | u32 sid; | ||
| 4768 | 4796 | ||
| 4769 | isec = kzalloc(sizeof(struct ipc_security_struct), GFP_KERNEL); | 4797 | isec = kzalloc(sizeof(struct ipc_security_struct), GFP_KERNEL); |
| 4770 | if (!isec) | 4798 | if (!isec) |
| 4771 | return -ENOMEM; | 4799 | return -ENOMEM; |
| 4772 | 4800 | ||
| 4801 | sid = task_sid(task); | ||
| 4773 | isec->sclass = sclass; | 4802 | isec->sclass = sclass; |
| 4774 | isec->sid = tsec->sid; | 4803 | isec->sid = sid; |
| 4775 | perm->security = isec; | 4804 | perm->security = isec; |
| 4776 | 4805 | ||
| 4777 | return 0; | 4806 | return 0; |
| @@ -4809,17 +4838,16 @@ static void msg_msg_free_security(struct msg_msg *msg) | |||
| 4809 | static int ipc_has_perm(struct kern_ipc_perm *ipc_perms, | 4838 | static int ipc_has_perm(struct kern_ipc_perm *ipc_perms, |
| 4810 | u32 perms) | 4839 | u32 perms) |
| 4811 | { | 4840 | { |
| 4812 | struct task_security_struct *tsec; | ||
| 4813 | struct ipc_security_struct *isec; | 4841 | struct ipc_security_struct *isec; |
| 4814 | struct avc_audit_data ad; | 4842 | struct avc_audit_data ad; |
| 4843 | u32 sid = current_sid(); | ||
| 4815 | 4844 | ||
| 4816 | tsec = current->cred->security; | ||
| 4817 | isec = ipc_perms->security; | 4845 | isec = ipc_perms->security; |
| 4818 | 4846 | ||
| 4819 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 4847 | AVC_AUDIT_DATA_INIT(&ad, IPC); |
| 4820 | ad.u.ipc_id = ipc_perms->key; | 4848 | ad.u.ipc_id = ipc_perms->key; |
| 4821 | 4849 | ||
| 4822 | return avc_has_perm(tsec->sid, isec->sid, isec->sclass, perms, &ad); | 4850 | return avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad); |
| 4823 | } | 4851 | } |
| 4824 | 4852 | ||
| 4825 | static int selinux_msg_msg_alloc_security(struct msg_msg *msg) | 4853 | static int selinux_msg_msg_alloc_security(struct msg_msg *msg) |
| @@ -4835,22 +4863,21 @@ static void selinux_msg_msg_free_security(struct msg_msg *msg) | |||
| 4835 | /* message queue security operations */ | 4863 | /* message queue security operations */ |
| 4836 | static int selinux_msg_queue_alloc_security(struct msg_queue *msq) | 4864 | static int selinux_msg_queue_alloc_security(struct msg_queue *msq) |
| 4837 | { | 4865 | { |
| 4838 | struct task_security_struct *tsec; | ||
| 4839 | struct ipc_security_struct *isec; | 4866 | struct ipc_security_struct *isec; |
| 4840 | struct avc_audit_data ad; | 4867 | struct avc_audit_data ad; |
| 4868 | u32 sid = current_sid(); | ||
| 4841 | int rc; | 4869 | int rc; |
| 4842 | 4870 | ||
| 4843 | rc = ipc_alloc_security(current, &msq->q_perm, SECCLASS_MSGQ); | 4871 | rc = ipc_alloc_security(current, &msq->q_perm, SECCLASS_MSGQ); |
| 4844 | if (rc) | 4872 | if (rc) |
| 4845 | return rc; | 4873 | return rc; |
| 4846 | 4874 | ||
| 4847 | tsec = current->cred->security; | ||
| 4848 | isec = msq->q_perm.security; | 4875 | isec = msq->q_perm.security; |
| 4849 | 4876 | ||
| 4850 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 4877 | AVC_AUDIT_DATA_INIT(&ad, IPC); |
| 4851 | ad.u.ipc_id = msq->q_perm.key; | 4878 | ad.u.ipc_id = msq->q_perm.key; |
| 4852 | 4879 | ||
| 4853 | rc = avc_has_perm(tsec->sid, isec->sid, SECCLASS_MSGQ, | 4880 | rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, |
| 4854 | MSGQ__CREATE, &ad); | 4881 | MSGQ__CREATE, &ad); |
| 4855 | if (rc) { | 4882 | if (rc) { |
| 4856 | ipc_free_security(&msq->q_perm); | 4883 | ipc_free_security(&msq->q_perm); |
| @@ -4866,17 +4893,16 @@ static void selinux_msg_queue_free_security(struct msg_queue *msq) | |||
| 4866 | 4893 | ||
| 4867 | static int selinux_msg_queue_associate(struct msg_queue *msq, int msqflg) | 4894 | static int selinux_msg_queue_associate(struct msg_queue *msq, int msqflg) |
| 4868 | { | 4895 | { |
| 4869 | struct task_security_struct *tsec; | ||
| 4870 | struct ipc_security_struct *isec; | 4896 | struct ipc_security_struct *isec; |
| 4871 | struct avc_audit_data ad; | 4897 | struct avc_audit_data ad; |
| 4898 | u32 sid = current_sid(); | ||
| 4872 | 4899 | ||
| 4873 | tsec = current->cred->security; | ||
| 4874 | isec = msq->q_perm.security; | 4900 | isec = msq->q_perm.security; |
| 4875 | 4901 | ||
| 4876 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 4902 | AVC_AUDIT_DATA_INIT(&ad, IPC); |
| 4877 | ad.u.ipc_id = msq->q_perm.key; | 4903 | ad.u.ipc_id = msq->q_perm.key; |
| 4878 | 4904 | ||
| 4879 | return avc_has_perm(tsec->sid, isec->sid, SECCLASS_MSGQ, | 4905 | return avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, |
| 4880 | MSGQ__ASSOCIATE, &ad); | 4906 | MSGQ__ASSOCIATE, &ad); |
| 4881 | } | 4907 | } |
| 4882 | 4908 | ||
| @@ -4910,13 +4936,12 @@ static int selinux_msg_queue_msgctl(struct msg_queue *msq, int cmd) | |||
| 4910 | 4936 | ||
| 4911 | static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, int msqflg) | 4937 | static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, int msqflg) |
| 4912 | { | 4938 | { |
| 4913 | struct task_security_struct *tsec; | ||
| 4914 | struct ipc_security_struct *isec; | 4939 | struct ipc_security_struct *isec; |
| 4915 | struct msg_security_struct *msec; | 4940 | struct msg_security_struct *msec; |
| 4916 | struct avc_audit_data ad; | 4941 | struct avc_audit_data ad; |
| 4942 | u32 sid = current_sid(); | ||
| 4917 | int rc; | 4943 | int rc; |
| 4918 | 4944 | ||
| 4919 | tsec = current->cred->security; | ||
| 4920 | isec = msq->q_perm.security; | 4945 | isec = msq->q_perm.security; |
| 4921 | msec = msg->security; | 4946 | msec = msg->security; |
| 4922 | 4947 | ||
| @@ -4928,9 +4953,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, | |||
| 4928 | * Compute new sid based on current process and | 4953 | * Compute new sid based on current process and |
| 4929 | * message queue this message will be stored in | 4954 | * message queue this message will be stored in |
| 4930 | */ | 4955 | */ |
| 4931 | rc = security_transition_sid(tsec->sid, | 4956 | rc = security_transition_sid(sid, isec->sid, SECCLASS_MSG, |
| 4932 | isec->sid, | ||
| 4933 | SECCLASS_MSG, | ||
| 4934 | &msec->sid); | 4957 | &msec->sid); |
| 4935 | if (rc) | 4958 | if (rc) |
| 4936 | return rc; | 4959 | return rc; |
| @@ -4940,16 +4963,16 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, | |||
| 4940 | ad.u.ipc_id = msq->q_perm.key; | 4963 | ad.u.ipc_id = msq->q_perm.key; |
| 4941 | 4964 | ||
| 4942 | /* Can this process write to the queue? */ | 4965 | /* Can this process write to the queue? */ |
| 4943 | rc = avc_has_perm(tsec->sid, isec->sid, SECCLASS_MSGQ, | 4966 | rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, |
| 4944 | MSGQ__WRITE, &ad); | 4967 | MSGQ__WRITE, &ad); |
| 4945 | if (!rc) | 4968 | if (!rc) |
| 4946 | /* Can this process send the message */ | 4969 | /* Can this process send the message */ |
| 4947 | rc = avc_has_perm(tsec->sid, msec->sid, | 4970 | rc = avc_has_perm(sid, msec->sid, SECCLASS_MSG, |
| 4948 | SECCLASS_MSG, MSG__SEND, &ad); | 4971 | MSG__SEND, &ad); |
| 4949 | if (!rc) | 4972 | if (!rc) |
| 4950 | /* Can the message be put in the queue? */ | 4973 | /* Can the message be put in the queue? */ |
| 4951 | rc = avc_has_perm(msec->sid, isec->sid, | 4974 | rc = avc_has_perm(msec->sid, isec->sid, SECCLASS_MSGQ, |
| 4952 | SECCLASS_MSGQ, MSGQ__ENQUEUE, &ad); | 4975 | MSGQ__ENQUEUE, &ad); |
| 4953 | 4976 | ||
| 4954 | return rc; | 4977 | return rc; |
| 4955 | } | 4978 | } |
| @@ -4958,23 +4981,22 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, | |||
| 4958 | struct task_struct *target, | 4981 | struct task_struct *target, |
| 4959 | long type, int mode) | 4982 | long type, int mode) |
| 4960 | { | 4983 | { |
| 4961 | struct task_security_struct *tsec; | ||
| 4962 | struct ipc_security_struct *isec; | 4984 | struct ipc_security_struct *isec; |
| 4963 | struct msg_security_struct *msec; | 4985 | struct msg_security_struct *msec; |
| 4964 | struct avc_audit_data ad; | 4986 | struct avc_audit_data ad; |
| 4987 | u32 sid = task_sid(target); | ||
| 4965 | int rc; | 4988 | int rc; |
| 4966 | 4989 | ||
| 4967 | tsec = target->cred->security; | ||
| 4968 | isec = msq->q_perm.security; | 4990 | isec = msq->q_perm.security; |
| 4969 | msec = msg->security; | 4991 | msec = msg->security; |
| 4970 | 4992 | ||
| 4971 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 4993 | AVC_AUDIT_DATA_INIT(&ad, IPC); |
| 4972 | ad.u.ipc_id = msq->q_perm.key; | 4994 | ad.u.ipc_id = msq->q_perm.key; |
| 4973 | 4995 | ||
| 4974 | rc = avc_has_perm(tsec->sid, isec->sid, | 4996 | rc = avc_has_perm(sid, isec->sid, |
| 4975 | SECCLASS_MSGQ, MSGQ__READ, &ad); | 4997 | SECCLASS_MSGQ, MSGQ__READ, &ad); |
| 4976 | if (!rc) | 4998 | if (!rc) |
| 4977 | rc = avc_has_perm(tsec->sid, msec->sid, | 4999 | rc = avc_has_perm(sid, msec->sid, |
| 4978 | SECCLASS_MSG, MSG__RECEIVE, &ad); | 5000 | SECCLASS_MSG, MSG__RECEIVE, &ad); |
| 4979 | return rc; | 5001 | return rc; |
| 4980 | } | 5002 | } |
| @@ -4982,22 +5004,21 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, | |||
| 4982 | /* Shared Memory security operations */ | 5004 | /* Shared Memory security operations */ |
| 4983 | static int selinux_shm_alloc_security(struct shmid_kernel *shp) | 5005 | static int selinux_shm_alloc_security(struct shmid_kernel *shp) |
| 4984 | { | 5006 | { |
| 4985 | struct task_security_struct *tsec; | ||
| 4986 | struct ipc_security_struct *isec; | 5007 | struct ipc_security_struct *isec; |
| 4987 | struct avc_audit_data ad; | 5008 | struct avc_audit_data ad; |
| 5009 | u32 sid = current_sid(); | ||
| 4988 | int rc; | 5010 | int rc; |
| 4989 | 5011 | ||
| 4990 | rc = ipc_alloc_security(current, &shp->shm_perm, SECCLASS_SHM); | 5012 | rc = ipc_alloc_security(current, &shp->shm_perm, SECCLASS_SHM); |
| 4991 | if (rc) | 5013 | if (rc) |
| 4992 | return rc; | 5014 | return rc; |
| 4993 | 5015 | ||
| 4994 | tsec = current->cred->security; | ||
| 4995 | isec = shp->shm_perm.security; | 5016 | isec = shp->shm_perm.security; |
| 4996 | 5017 | ||
| 4997 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 5018 | AVC_AUDIT_DATA_INIT(&ad, IPC); |
| 4998 | ad.u.ipc_id = shp->shm_perm.key; | 5019 | ad.u.ipc_id = shp->shm_perm.key; |
| 4999 | 5020 | ||
| 5000 | rc = avc_has_perm(tsec->sid, isec->sid, SECCLASS_SHM, | 5021 | rc = avc_has_perm(sid, isec->sid, SECCLASS_SHM, |
| 5001 | SHM__CREATE, &ad); | 5022 | SHM__CREATE, &ad); |
| 5002 | if (rc) { | 5023 | if (rc) { |
| 5003 | ipc_free_security(&shp->shm_perm); | 5024 | ipc_free_security(&shp->shm_perm); |
| @@ -5013,17 +5034,16 @@ static void selinux_shm_free_security(struct shmid_kernel *shp) | |||
| 5013 | 5034 | ||
| 5014 | static int selinux_shm_associate(struct shmid_kernel *shp, int shmflg) | 5035 | static int selinux_shm_associate(struct shmid_kernel *shp, int shmflg) |
| 5015 | { | 5036 | { |
| 5016 | struct task_security_struct *tsec; | ||
| 5017 | struct ipc_security_struct *isec; | 5037 | struct ipc_security_struct *isec; |
| 5018 | struct avc_audit_data ad; | 5038 | struct avc_audit_data ad; |
| 5039 | u32 sid = current_sid(); | ||
| 5019 | 5040 | ||
| 5020 | tsec = current->cred->security; | ||
| 5021 | isec = shp->shm_perm.security; | 5041 | isec = shp->shm_perm.security; |
| 5022 | 5042 | ||
| 5023 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 5043 | AVC_AUDIT_DATA_INIT(&ad, IPC); |
| 5024 | ad.u.ipc_id = shp->shm_perm.key; | 5044 | ad.u.ipc_id = shp->shm_perm.key; |
| 5025 | 5045 | ||
| 5026 | return avc_has_perm(tsec->sid, isec->sid, SECCLASS_SHM, | 5046 | return avc_has_perm(sid, isec->sid, SECCLASS_SHM, |
| 5027 | SHM__ASSOCIATE, &ad); | 5047 | SHM__ASSOCIATE, &ad); |
| 5028 | } | 5048 | } |
| 5029 | 5049 | ||
| @@ -5081,22 +5101,21 @@ static int selinux_shm_shmat(struct shmid_kernel *shp, | |||
| 5081 | /* Semaphore security operations */ | 5101 | /* Semaphore security operations */ |
| 5082 | static int selinux_sem_alloc_security(struct sem_array *sma) | 5102 | static int selinux_sem_alloc_security(struct sem_array *sma) |
| 5083 | { | 5103 | { |
| 5084 | struct task_security_struct *tsec; | ||
| 5085 | struct ipc_security_struct *isec; | 5104 | struct ipc_security_struct *isec; |
| 5086 | struct avc_audit_data ad; | 5105 | struct avc_audit_data ad; |
| 5106 | u32 sid = current_sid(); | ||
| 5087 | int rc; | 5107 | int rc; |
| 5088 | 5108 | ||
| 5089 | rc = ipc_alloc_security(current, &sma->sem_perm, SECCLASS_SEM); | 5109 | rc = ipc_alloc_security(current, &sma->sem_perm, SECCLASS_SEM); |
| 5090 | if (rc) | 5110 | if (rc) |
| 5091 | return rc; | 5111 | return rc; |
| 5092 | 5112 | ||
| 5093 | tsec = current->cred->security; | ||
| 5094 | isec = sma->sem_perm.security; | 5113 | isec = sma->sem_perm.security; |
| 5095 | 5114 | ||
| 5096 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 5115 | AVC_AUDIT_DATA_INIT(&ad, IPC); |
| 5097 | ad.u.ipc_id = sma->sem_perm.key; | 5116 | ad.u.ipc_id = sma->sem_perm.key; |
| 5098 | 5117 | ||
| 5099 | rc = avc_has_perm(tsec->sid, isec->sid, SECCLASS_SEM, | 5118 | rc = avc_has_perm(sid, isec->sid, SECCLASS_SEM, |
| 5100 | SEM__CREATE, &ad); | 5119 | SEM__CREATE, &ad); |
| 5101 | if (rc) { | 5120 | if (rc) { |
| 5102 | ipc_free_security(&sma->sem_perm); | 5121 | ipc_free_security(&sma->sem_perm); |
| @@ -5112,17 +5131,16 @@ static void selinux_sem_free_security(struct sem_array *sma) | |||
| 5112 | 5131 | ||
| 5113 | static int selinux_sem_associate(struct sem_array *sma, int semflg) | 5132 | static int selinux_sem_associate(struct sem_array *sma, int semflg) |
| 5114 | { | 5133 | { |
| 5115 | struct task_security_struct *tsec; | ||
| 5116 | struct ipc_security_struct *isec; | 5134 | struct ipc_security_struct *isec; |
| 5117 | struct avc_audit_data ad; | 5135 | struct avc_audit_data ad; |
| 5136 | u32 sid = current_sid(); | ||
| 5118 | 5137 | ||
| 5119 | tsec = current->cred->security; | ||
| 5120 | isec = sma->sem_perm.security; | 5138 | isec = sma->sem_perm.security; |
| 5121 | 5139 | ||
| 5122 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 5140 | AVC_AUDIT_DATA_INIT(&ad, IPC); |
| 5123 | ad.u.ipc_id = sma->sem_perm.key; | 5141 | ad.u.ipc_id = sma->sem_perm.key; |
| 5124 | 5142 | ||
| 5125 | return avc_has_perm(tsec->sid, isec->sid, SECCLASS_SEM, | 5143 | return avc_has_perm(sid, isec->sid, SECCLASS_SEM, |
| 5126 | SEM__ASSOCIATE, &ad); | 5144 | SEM__ASSOCIATE, &ad); |
| 5127 | } | 5145 | } |
| 5128 | 5146 | ||
| @@ -5212,7 +5230,7 @@ static void selinux_d_instantiate(struct dentry *dentry, struct inode *inode) | |||
| 5212 | static int selinux_getprocattr(struct task_struct *p, | 5230 | static int selinux_getprocattr(struct task_struct *p, |
| 5213 | char *name, char **value) | 5231 | char *name, char **value) |
| 5214 | { | 5232 | { |
| 5215 | struct task_security_struct *tsec; | 5233 | const struct task_security_struct *__tsec; |
| 5216 | u32 sid; | 5234 | u32 sid; |
| 5217 | int error; | 5235 | int error; |
| 5218 | unsigned len; | 5236 | unsigned len; |
| @@ -5223,22 +5241,24 @@ static int selinux_getprocattr(struct task_struct *p, | |||
| 5223 | return error; | 5241 | return error; |
| 5224 | } | 5242 | } |
| 5225 | 5243 | ||
| 5226 | tsec = p->cred->security; | 5244 | rcu_read_lock(); |
| 5245 | __tsec = __task_cred(p)->security; | ||
| 5227 | 5246 | ||
| 5228 | if (!strcmp(name, "current")) | 5247 | if (!strcmp(name, "current")) |
| 5229 | sid = tsec->sid; | 5248 | sid = __tsec->sid; |
| 5230 | else if (!strcmp(name, "prev")) | 5249 | else if (!strcmp(name, "prev")) |
| 5231 | sid = tsec->osid; | 5250 | sid = __tsec->osid; |
| 5232 | else if (!strcmp(name, "exec")) | 5251 | else if (!strcmp(name, "exec")) |
| 5233 | sid = tsec->exec_sid; | 5252 | sid = __tsec->exec_sid; |
| 5234 | else if (!strcmp(name, "fscreate")) | 5253 | else if (!strcmp(name, "fscreate")) |
| 5235 | sid = tsec->create_sid; | 5254 | sid = __tsec->create_sid; |
| 5236 | else if (!strcmp(name, "keycreate")) | 5255 | else if (!strcmp(name, "keycreate")) |
| 5237 | sid = tsec->keycreate_sid; | 5256 | sid = __tsec->keycreate_sid; |
| 5238 | else if (!strcmp(name, "sockcreate")) | 5257 | else if (!strcmp(name, "sockcreate")) |
| 5239 | sid = tsec->sockcreate_sid; | 5258 | sid = __tsec->sockcreate_sid; |
| 5240 | else | 5259 | else |
| 5241 | return -EINVAL; | 5260 | goto invalid; |
| 5261 | rcu_read_unlock(); | ||
| 5242 | 5262 | ||
| 5243 | if (!sid) | 5263 | if (!sid) |
| 5244 | return 0; | 5264 | return 0; |
| @@ -5247,6 +5267,10 @@ static int selinux_getprocattr(struct task_struct *p, | |||
| 5247 | if (error) | 5267 | if (error) |
| 5248 | return error; | 5268 | return error; |
| 5249 | return len; | 5269 | return len; |
| 5270 | |||
| 5271 | invalid: | ||
| 5272 | rcu_read_unlock(); | ||
| 5273 | return -EINVAL; | ||
| 5250 | } | 5274 | } |
| 5251 | 5275 | ||
| 5252 | static int selinux_setprocattr(struct task_struct *p, | 5276 | static int selinux_setprocattr(struct task_struct *p, |
| @@ -5360,9 +5384,7 @@ boundary_ok: | |||
| 5360 | rcu_read_lock(); | 5384 | rcu_read_lock(); |
| 5361 | tracer = tracehook_tracer_task(p); | 5385 | tracer = tracehook_tracer_task(p); |
| 5362 | if (tracer != NULL) { | 5386 | if (tracer != NULL) { |
| 5363 | struct task_security_struct *ptsec = | 5387 | u32 ptsid = task_sid(tracer); |
| 5364 | tracer->cred->security; | ||
| 5365 | u32 ptsid = ptsec->sid; | ||
| 5366 | rcu_read_unlock(); | 5388 | rcu_read_unlock(); |
| 5367 | error = avc_has_perm_noaudit(ptsid, sid, | 5389 | error = avc_has_perm_noaudit(ptsid, sid, |
| 5368 | SECCLASS_PROCESS, | 5390 | SECCLASS_PROCESS, |
| @@ -5405,19 +5427,22 @@ static void selinux_release_secctx(char *secdata, u32 seclen) | |||
| 5405 | static int selinux_key_alloc(struct key *k, struct task_struct *tsk, | 5427 | static int selinux_key_alloc(struct key *k, struct task_struct *tsk, |
| 5406 | unsigned long flags) | 5428 | unsigned long flags) |
| 5407 | { | 5429 | { |
| 5408 | struct task_security_struct *tsec = tsk->cred->security; | 5430 | const struct task_security_struct *__tsec; |
| 5409 | struct key_security_struct *ksec; | 5431 | struct key_security_struct *ksec; |
| 5410 | 5432 | ||
| 5411 | ksec = kzalloc(sizeof(struct key_security_struct), GFP_KERNEL); | 5433 | ksec = kzalloc(sizeof(struct key_security_struct), GFP_KERNEL); |
| 5412 | if (!ksec) | 5434 | if (!ksec) |
| 5413 | return -ENOMEM; | 5435 | return -ENOMEM; |
| 5414 | 5436 | ||
| 5415 | if (tsec->keycreate_sid) | 5437 | rcu_read_lock(); |
| 5416 | ksec->sid = tsec->keycreate_sid; | 5438 | __tsec = __task_cred(tsk)->security; |
| 5439 | if (__tsec->keycreate_sid) | ||
| 5440 | ksec->sid = __tsec->keycreate_sid; | ||
| 5417 | else | 5441 | else |
| 5418 | ksec->sid = tsec->sid; | 5442 | ksec->sid = __tsec->sid; |
| 5419 | k->security = ksec; | 5443 | rcu_read_unlock(); |
| 5420 | 5444 | ||
| 5445 | k->security = ksec; | ||
| 5421 | return 0; | 5446 | return 0; |
| 5422 | } | 5447 | } |
| 5423 | 5448 | ||
| @@ -5434,13 +5459,8 @@ static int selinux_key_permission(key_ref_t key_ref, | |||
| 5434 | key_perm_t perm) | 5459 | key_perm_t perm) |
| 5435 | { | 5460 | { |
| 5436 | struct key *key; | 5461 | struct key *key; |
| 5437 | struct task_security_struct *tsec; | ||
| 5438 | struct key_security_struct *ksec; | 5462 | struct key_security_struct *ksec; |
| 5439 | 5463 | u32 sid; | |
| 5440 | key = key_ref_to_ptr(key_ref); | ||
| 5441 | |||
| 5442 | tsec = ctx->cred->security; | ||
| 5443 | ksec = key->security; | ||
| 5444 | 5464 | ||
| 5445 | /* if no specific permissions are requested, we skip the | 5465 | /* if no specific permissions are requested, we skip the |
| 5446 | permission check. No serious, additional covert channels | 5466 | permission check. No serious, additional covert channels |
| @@ -5448,8 +5468,12 @@ static int selinux_key_permission(key_ref_t key_ref, | |||
| 5448 | if (perm == 0) | 5468 | if (perm == 0) |
| 5449 | return 0; | 5469 | return 0; |
| 5450 | 5470 | ||
| 5451 | return avc_has_perm(tsec->sid, ksec->sid, | 5471 | sid = task_sid(ctx); |
| 5452 | SECCLASS_KEY, perm, NULL); | 5472 | |
| 5473 | key = key_ref_to_ptr(key_ref); | ||
| 5474 | ksec = key->security; | ||
| 5475 | |||
| 5476 | return avc_has_perm(sid, ksec->sid, SECCLASS_KEY, perm, NULL); | ||
| 5453 | } | 5477 | } |
| 5454 | 5478 | ||
| 5455 | static int selinux_key_getsecurity(struct key *key, char **_buffer) | 5479 | static int selinux_key_getsecurity(struct key *key, char **_buffer) |
