aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/lsm_audit.h5
-rw-r--r--security/selinux/avc.c24
-rw-r--r--security/selinux/hooks.c20
-rw-r--r--security/selinux/include/classmap.h2
4 files changed, 43 insertions, 8 deletions
diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
index 6907251d5200..788f0ab937aa 100644
--- a/include/linux/lsm_audit.h
+++ b/include/linux/lsm_audit.h
@@ -90,6 +90,11 @@ struct common_audit_data {
90 u32 requested; 90 u32 requested;
91 u32 audited; 91 u32 audited;
92 u32 denied; 92 u32 denied;
93 /*
94 * auditdeny is a bit tricky and unintuitive. See the
95 * comments in avc.c for it's meaning and usage.
96 */
97 u32 auditdeny;
93 struct av_decision *avd; 98 struct av_decision *avd;
94 int result; 99 int result;
95 } selinux_audit_data; 100 } selinux_audit_data;
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 3662b0f15ec5..9da6420e2056 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -488,9 +488,29 @@ void avc_audit(u32 ssid, u32 tsid,
488 struct common_audit_data stack_data; 488 struct common_audit_data stack_data;
489 u32 denied, audited; 489 u32 denied, audited;
490 denied = requested & ~avd->allowed; 490 denied = requested & ~avd->allowed;
491 if (denied) 491 if (denied) {
492 audited = denied & avd->auditdeny; 492 audited = denied & avd->auditdeny;
493 else if (result) 493 /*
494 * a->selinux_audit_data.auditdeny is TRICKY! Setting a bit in
495 * this field means that ANY denials should NOT be audited if
496 * the policy contains an explicit dontaudit rule for that
497 * permission. Take notice that this is unrelated to the
498 * actual permissions that were denied. As an example lets
499 * assume:
500 *
501 * denied == READ
502 * avd.auditdeny & ACCESS == 0 (not set means explicit rule)
503 * selinux_audit_data.auditdeny & ACCESS == 1
504 *
505 * We will NOT audit the denial even though the denied
506 * permission was READ and the auditdeny checks were for
507 * ACCESS
508 */
509 if (a &&
510 a->selinux_audit_data.auditdeny &&
511 !(a->selinux_audit_data.auditdeny & avd->auditdeny))
512 audited = 0;
513 } else if (result)
494 audited = denied = requested; 514 audited = denied = requested;
495 else 515 else
496 audited = requested & avd->auditallow; 516 audited = requested & avd->auditallow;
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 0c98846f188d..650947a72a2b 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2644,16 +2644,26 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *na
2644static int selinux_inode_permission(struct inode *inode, int mask) 2644static int selinux_inode_permission(struct inode *inode, int mask)
2645{ 2645{
2646 const struct cred *cred = current_cred(); 2646 const struct cred *cred = current_cred();
2647 struct common_audit_data ad;
2648 u32 perms;
2649 bool from_access;
2647 2650
2651 from_access = mask & MAY_ACCESS;
2648 mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND); 2652 mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND);
2649 2653
2650 if (!mask) { 2654 /* No permission to check. Existence test. */
2651 /* No permission to check. Existence test. */ 2655 if (!mask)
2652 return 0; 2656 return 0;
2653 }
2654 2657
2655 return inode_has_perm(cred, inode, 2658 COMMON_AUDIT_DATA_INIT(&ad, FS);
2656 file_mask_to_av(inode->i_mode, mask), NULL); 2659 ad.u.fs.inode = inode;
2660
2661 if (from_access)
2662 ad.selinux_audit_data.auditdeny |= FILE__AUDIT_ACCESS;
2663
2664 perms = file_mask_to_av(inode->i_mode, mask);
2665
2666 return inode_has_perm(cred, inode, perms, &ad);
2657} 2667}
2658 2668
2659static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) 2669static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index 8b32e959bb2e..d64603e10dbe 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -2,7 +2,7 @@
2 "getattr", "setattr", "lock", "relabelfrom", "relabelto", "append" 2 "getattr", "setattr", "lock", "relabelfrom", "relabelto", "append"
3 3
4#define COMMON_FILE_PERMS COMMON_FILE_SOCK_PERMS, "unlink", "link", \ 4#define COMMON_FILE_PERMS COMMON_FILE_SOCK_PERMS, "unlink", "link", \
5 "rename", "execute", "swapon", "quotaon", "mounton" 5 "rename", "execute", "swapon", "quotaon", "mounton", "audit_access"
6 6
7#define COMMON_SOCK_PERMS COMMON_FILE_SOCK_PERMS, "bind", "connect", \ 7#define COMMON_SOCK_PERMS COMMON_FILE_SOCK_PERMS, "bind", "connect", \
8 "listen", "accept", "getopt", "setopt", "shutdown", "recvfrom", \ 8 "listen", "accept", "getopt", "setopt", "shutdown", "recvfrom", \