SELINUX: Make selinux cache VFS RCU walks safe

Now that the security modules can decide whether they support the
dcache RCU walk or not it's possible to make selinux a bit more
RCU friendly. The SELinux AVC and security server access decision
code is RCU safe. A specific piece of the LSM audit code may not
be RCU safe.

This patch makes the VFS RCU walk retry if it would hit the non RCU
safe chunk of code. It will normally just work under RCU. This is
done simply by passing the VFS RCU state as a flag down into the
avc_audit() code and returning ECHILD there if it would have an issue.

Based-on-patch-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Eric Paris <eparis@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by Eric Paris and committed by Linus Torvalds 9ade0cf4 1879fd6a

+55 -25
+29 -7
security/selinux/avc.c
··· 471 471 * @avd: access vector decisions 472 472 * @result: result from avc_has_perm_noaudit 473 473 * @a: auxiliary audit data 474 + * @flags: VFS walk flags 474 475 * 475 476 * Audit the granting or denial of permissions in accordance 476 477 * with the policy. This function is typically called by ··· 482 481 * be performed under a lock, to allow the lock to be released 483 482 * before calling the auditing code. 484 483 */ 485 - void avc_audit(u32 ssid, u32 tsid, 484 + int avc_audit(u32 ssid, u32 tsid, 486 485 u16 tclass, u32 requested, 487 - struct av_decision *avd, int result, struct common_audit_data *a) 486 + struct av_decision *avd, int result, struct common_audit_data *a, 487 + unsigned flags) 488 488 { 489 489 struct common_audit_data stack_data; 490 490 u32 denied, audited; ··· 517 515 else 518 516 audited = requested & avd->auditallow; 519 517 if (!audited) 520 - return; 518 + return 0; 519 + 521 520 if (!a) { 522 521 a = &stack_data; 523 522 COMMON_AUDIT_DATA_INIT(a, NONE); 524 523 } 524 + 525 + /* 526 + * When in a RCU walk do the audit on the RCU retry. This is because 527 + * the collection of the dname in an inode audit message is not RCU 528 + * safe. Note this may drop some audits when the situation changes 529 + * during retry. However this is logically just as if the operation 530 + * happened a little later. 531 + */ 532 + if ((a->type == LSM_AUDIT_DATA_FS) && 533 + (flags & IPERM_FLAG_RCU)) 534 + return -ECHILD; 535 + 525 536 a->selinux_audit_data.tclass = tclass; 526 537 a->selinux_audit_data.requested = requested; 527 538 a->selinux_audit_data.ssid = ssid; ··· 544 529 a->lsm_pre_audit = avc_audit_pre_callback; 545 530 a->lsm_post_audit = avc_audit_post_callback; 546 531 common_lsm_audit(a); 532 + return 0; 547 533 } 548 534 549 535 /** ··· 809 793 * @tclass: target security class 810 794 * @requested: requested permissions, interpreted based on @tclass 811 795 * @auditdata: auxiliary audit data 796 + * @flags: VFS walk flags 812 797 * 813 798 * Check the AVC to determine whether the @requested permissions are granted 814 799 * for the SID pair (@ssid, @tsid), interpreting the permissions ··· 819 802 * permissions are granted, -%EACCES if any permissions are denied, or 820 803 * another -errno upon other errors. 821 804 */ 822 - int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, 823 - u32 requested, struct common_audit_data *auditdata) 805 + int avc_has_perm_flags(u32 ssid, u32 tsid, u16 tclass, 806 + u32 requested, struct common_audit_data *auditdata, 807 + unsigned flags) 824 808 { 825 809 struct av_decision avd; 826 - int rc; 810 + int rc, rc2; 827 811 828 812 rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, 0, &avd); 829 - avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata); 813 + 814 + rc2 = avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata, 815 + flags); 816 + if (rc2) 817 + return rc2; 830 818 return rc; 831 819 } 832 820
+13 -13
security/selinux/hooks.c
··· 1446 1446 } 1447 1447 1448 1448 rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd); 1449 - if (audit == SECURITY_CAP_AUDIT) 1450 - avc_audit(sid, sid, sclass, av, &avd, rc, &ad); 1449 + if (audit == SECURITY_CAP_AUDIT) { 1450 + int rc2 = avc_audit(sid, sid, sclass, av, &avd, rc, &ad, 0); 1451 + if (rc2) 1452 + return rc2; 1453 + } 1451 1454 return rc; 1452 1455 } 1453 1456 ··· 1470 1467 static int inode_has_perm(const struct cred *cred, 1471 1468 struct inode *inode, 1472 1469 u32 perms, 1473 - struct common_audit_data *adp) 1470 + struct common_audit_data *adp, 1471 + unsigned flags) 1474 1472 { 1475 1473 struct inode_security_struct *isec; 1476 1474 struct common_audit_data ad; ··· 1491 1487 ad.u.fs.inode = inode; 1492 1488 } 1493 1489 1494 - return avc_has_perm(sid, isec->sid, isec->sclass, perms, adp); 1490 + return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags); 1495 1491 } 1496 1492 1497 1493 /* Same as inode_has_perm, but pass explicit audit data containing ··· 1508 1504 COMMON_AUDIT_DATA_INIT(&ad, FS); 1509 1505 ad.u.fs.path.mnt = mnt; 1510 1506 ad.u.fs.path.dentry = dentry; 1511 - return inode_has_perm(cred, inode, av, &ad); 1507 + return inode_has_perm(cred, inode, av, &ad, 0); 1512 1508 } 1513 1509 1514 1510 /* Check whether a task can use an open file descriptor to ··· 1544 1540 /* av is zero if only checking access to the descriptor. */ 1545 1541 rc = 0; 1546 1542 if (av) 1547 - rc = inode_has_perm(cred, inode, av, &ad); 1543 + rc = inode_has_perm(cred, inode, av, &ad, 0); 1548 1544 1549 1545 out: 1550 1546 return rc; ··· 2107 2103 file = file_priv->file; 2108 2104 inode = file->f_path.dentry->d_inode; 2109 2105 if (inode_has_perm(cred, inode, 2110 - FILE__READ | FILE__WRITE, NULL)) { 2106 + FILE__READ | FILE__WRITE, NULL, 0)) { 2111 2107 drop_tty = 1; 2112 2108 } 2113 2109 } ··· 2653 2649 if (!mask) 2654 2650 return 0; 2655 2651 2656 - /* May be droppable after audit */ 2657 - if (flags & IPERM_FLAG_RCU) 2658 - return -ECHILD; 2659 - 2660 2652 COMMON_AUDIT_DATA_INIT(&ad, FS); 2661 2653 ad.u.fs.inode = inode; 2662 2654 ··· 2661 2661 2662 2662 perms = file_mask_to_av(inode->i_mode, mask); 2663 2663 2664 - return inode_has_perm(cred, inode, perms, &ad); 2664 + return inode_has_perm(cred, inode, perms, &ad, flags); 2665 2665 } 2666 2666 2667 2667 static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) ··· 3209 3209 * new inode label or new policy. 3210 3210 * This check is not redundant - do not remove. 3211 3211 */ 3212 - return inode_has_perm(cred, inode, open_file_to_av(file), NULL); 3212 + return inode_has_perm(cred, inode, open_file_to_av(file), NULL, 0); 3213 3213 } 3214 3214 3215 3215 /* task security operations */
+13 -5
security/selinux/include/avc.h
··· 54 54 55 55 void __init avc_init(void); 56 56 57 - void avc_audit(u32 ssid, u32 tsid, 57 + int avc_audit(u32 ssid, u32 tsid, 58 58 u16 tclass, u32 requested, 59 59 struct av_decision *avd, 60 60 int result, 61 - struct common_audit_data *a); 61 + struct common_audit_data *a, unsigned flags); 62 62 63 63 #define AVC_STRICT 1 /* Ignore permissive mode. */ 64 64 int avc_has_perm_noaudit(u32 ssid, u32 tsid, ··· 66 66 unsigned flags, 67 67 struct av_decision *avd); 68 68 69 - int avc_has_perm(u32 ssid, u32 tsid, 70 - u16 tclass, u32 requested, 71 - struct common_audit_data *auditdata); 69 + int avc_has_perm_flags(u32 ssid, u32 tsid, 70 + u16 tclass, u32 requested, 71 + struct common_audit_data *auditdata, 72 + unsigned); 73 + 74 + static inline int avc_has_perm(u32 ssid, u32 tsid, 75 + u16 tclass, u32 requested, 76 + struct common_audit_data *auditdata) 77 + { 78 + return avc_has_perm_flags(ssid, tsid, tclass, requested, auditdata, 0); 79 + } 72 80 73 81 u32 avc_policy_seqno(void); 74 82