diff options
Diffstat (limited to 'security/selinux/hooks.c')
-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) |