diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index c3ee902306d8..c99027dc0b36 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -2684,6 +2684,11 @@ static int selinux_inode_permission(struct inode *inode, int mask) | |||
2684 | u32 perms; | 2684 | u32 perms; |
2685 | bool from_access; | 2685 | bool from_access; |
2686 | unsigned flags = mask & MAY_NOT_BLOCK; | 2686 | unsigned flags = mask & MAY_NOT_BLOCK; |
2687 | struct inode_security_struct *isec; | ||
2688 | u32 sid; | ||
2689 | struct av_decision avd; | ||
2690 | int rc, rc2; | ||
2691 | u32 audited, denied; | ||
2687 | 2692 | ||
2688 | from_access = mask & MAY_ACCESS; | 2693 | from_access = mask & MAY_ACCESS; |
2689 | mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND); | 2694 | mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND); |
@@ -2692,6 +2697,23 @@ static int selinux_inode_permission(struct inode *inode, int mask) | |||
2692 | if (!mask) | 2697 | if (!mask) |
2693 | return 0; | 2698 | return 0; |
2694 | 2699 | ||
2700 | validate_creds(cred); | ||
2701 | |||
2702 | if (unlikely(IS_PRIVATE(inode))) | ||
2703 | return 0; | ||
2704 | |||
2705 | perms = file_mask_to_av(inode->i_mode, mask); | ||
2706 | |||
2707 | sid = cred_sid(cred); | ||
2708 | isec = inode->i_security; | ||
2709 | |||
2710 | rc = avc_has_perm_noaudit(sid, isec->sid, isec->sclass, perms, 0, &avd); | ||
2711 | audited = avc_audit_required(perms, &avd, rc, | ||
2712 | from_access ? FILE__AUDIT_ACCESS : 0, | ||
2713 | &denied); | ||
2714 | if (likely(!audited)) | ||
2715 | return rc; | ||
2716 | |||
2695 | COMMON_AUDIT_DATA_INIT(&ad, INODE); | 2717 | COMMON_AUDIT_DATA_INIT(&ad, INODE); |
2696 | ad.selinux_audit_data = &sad; | 2718 | ad.selinux_audit_data = &sad; |
2697 | ad.u.inode = inode; | 2719 | ad.u.inode = inode; |
@@ -2699,9 +2721,11 @@ static int selinux_inode_permission(struct inode *inode, int mask) | |||
2699 | if (from_access) | 2721 | if (from_access) |
2700 | ad.selinux_audit_data->auditdeny |= FILE__AUDIT_ACCESS; | 2722 | ad.selinux_audit_data->auditdeny |= FILE__AUDIT_ACCESS; |
2701 | 2723 | ||
2702 | perms = file_mask_to_av(inode->i_mode, mask); | 2724 | rc2 = slow_avc_audit(sid, isec->sid, isec->sclass, perms, |
2703 | 2725 | audited, denied, &ad, flags); | |
2704 | return inode_has_perm(cred, inode, perms, &ad, flags); | 2726 | if (rc2) |
2727 | return rc2; | ||
2728 | return rc; | ||
2705 | } | 2729 | } |
2706 | 2730 | ||
2707 | static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) | 2731 | static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) |