aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Liu <tliu@redhat.com>2009-07-14 12:14:09 -0400
committerJames Morris <jmorris@namei.org>2009-08-16 18:37:18 -0400
commit2bf49690325b62480a42f7afed5e9f164173c570 (patch)
treebc8525f6a45ea3ffaed9449084df7644bcd4e3c2
parentf322abf83feddc3c37c3a91794e0c5aece4af18e (diff)
SELinux: Convert avc_audit to use lsm_audit.h
Convert avc_audit in security/selinux/avc.c to use lsm_audit.h, for better maintainability. - changed selinux to use common_audit_data instead of avc_audit_data - eliminated code in avc.c and used code from lsm_audit.h instead. Had to add a LSM_AUDIT_NO_AUDIT to lsm_audit.h so that avc_audit can call common_lsm_audit and do the pre and post callbacks without doing the actual dump. This makes it so that the patched version behaves the same way as the unpatched version. Also added a denied field to the selinux_audit_data private space, once again to make it so that the patched version behaves like the unpatched. I've tested and confirmed that AVCs look the same before and after this patch. Signed-off-by: Thomas Liu <tliu@redhat.com> Acked-by: Stephen Smalley <sds@tycho.nsa.gov> Signed-off-by: James Morris <jmorris@namei.org>
-rw-r--r--include/linux/lsm_audit.h2
-rw-r--r--security/Makefile4
-rw-r--r--security/lsm_audit.c2
-rw-r--r--security/selinux/avc.c197
-rw-r--r--security/selinux/hooks.c142
-rw-r--r--security/selinux/include/avc.h49
-rw-r--r--security/selinux/include/netlabel.h4
-rw-r--r--security/selinux/include/xfrm.h8
-rw-r--r--security/selinux/netlabel.c2
-rw-r--r--security/selinux/xfrm.c4
10 files changed, 131 insertions, 283 deletions
diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
index a5514a3a4f17..190c37854870 100644
--- a/include/linux/lsm_audit.h
+++ b/include/linux/lsm_audit.h
@@ -33,6 +33,7 @@ struct common_audit_data {
33#define LSM_AUDIT_DATA_IPC 4 33#define LSM_AUDIT_DATA_IPC 4
34#define LSM_AUDIT_DATA_TASK 5 34#define LSM_AUDIT_DATA_TASK 5
35#define LSM_AUDIT_DATA_KEY 6 35#define LSM_AUDIT_DATA_KEY 6
36#define LSM_AUDIT_NO_AUDIT 7
36 struct task_struct *tsk; 37 struct task_struct *tsk;
37 union { 38 union {
38 struct { 39 struct {
@@ -86,6 +87,7 @@ struct common_audit_data {
86 u16 tclass; 87 u16 tclass;
87 u32 requested; 88 u32 requested;
88 u32 audited; 89 u32 audited;
90 u32 denied;
89 struct av_decision *avd; 91 struct av_decision *avd;
90 int result; 92 int result;
91 } selinux_audit_data; 93 } selinux_audit_data;
diff --git a/security/Makefile b/security/Makefile
index b56e7f9ecbc2..95ecc06392d7 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -16,9 +16,7 @@ obj-$(CONFIG_SECURITYFS) += inode.o
16# Must precede capability.o in order to stack properly. 16# Must precede capability.o in order to stack properly.
17obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o 17obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
18obj-$(CONFIG_SECURITY_SMACK) += smack/built-in.o 18obj-$(CONFIG_SECURITY_SMACK) += smack/built-in.o
19ifeq ($(CONFIG_AUDIT),y) 19obj-$(CONFIG_AUDIT) += lsm_audit.o
20obj-$(CONFIG_SECURITY_SMACK) += lsm_audit.o
21endif
22obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/built-in.o 20obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/built-in.o
23obj-$(CONFIG_SECURITY_ROOTPLUG) += root_plug.o 21obj-$(CONFIG_SECURITY_ROOTPLUG) += root_plug.o
24obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o 22obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
index 94b868494b31..500aad0ebd6a 100644
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -220,6 +220,8 @@ static void dump_common_audit_data(struct audit_buffer *ab,
220 } 220 }
221 221
222 switch (a->type) { 222 switch (a->type) {
223 case LSM_AUDIT_NO_AUDIT:
224 return;
223 case LSM_AUDIT_DATA_IPC: 225 case LSM_AUDIT_DATA_IPC:
224 audit_log_format(ab, " key=%d ", a->u.ipc_id); 226 audit_log_format(ab, " key=%d ", a->u.ipc_id);
225 break; 227 break;
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 236aaa2ea86d..e3d19014259b 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -492,23 +492,35 @@ out:
492 return node; 492 return node;
493} 493}
494 494
495static inline void avc_print_ipv6_addr(struct audit_buffer *ab, 495/**
496 struct in6_addr *addr, __be16 port, 496 * avc_audit_pre_callback - SELinux specific information
497 char *name1, char *name2) 497 * will be called by generic audit code
498 * @ab: the audit buffer
499 * @a: audit_data
500 */
501static void avc_audit_pre_callback(struct audit_buffer *ab, void *a)
498{ 502{
499 if (!ipv6_addr_any(addr)) 503 struct common_audit_data *ad = a;
500 audit_log_format(ab, " %s=%pI6", name1, addr); 504 audit_log_format(ab, "avc: %s ",
501 if (port) 505 ad->selinux_audit_data.denied ? "denied" : "granted");
502 audit_log_format(ab, " %s=%d", name2, ntohs(port)); 506 avc_dump_av(ab, ad->selinux_audit_data.tclass,
507 ad->selinux_audit_data.audited);
508 audit_log_format(ab, " for ");
503} 509}
504 510
505static inline void avc_print_ipv4_addr(struct audit_buffer *ab, __be32 addr, 511/**
506 __be16 port, char *name1, char *name2) 512 * avc_audit_post_callback - SELinux specific information
513 * will be called by generic audit code
514 * @ab: the audit buffer
515 * @a: audit_data
516 */
517static void avc_audit_post_callback(struct audit_buffer *ab, void *a)
507{ 518{
508 if (addr) 519 struct common_audit_data *ad = a;
509 audit_log_format(ab, " %s=%pI4", name1, &addr); 520 audit_log_format(ab, " ");
510 if (port) 521 avc_dump_query(ab, ad->selinux_audit_data.ssid,
511 audit_log_format(ab, " %s=%d", name2, ntohs(port)); 522 ad->selinux_audit_data.tsid,
523 ad->selinux_audit_data.tclass);
512} 524}
513 525
514/** 526/**
@@ -532,13 +544,10 @@ static inline void avc_print_ipv4_addr(struct audit_buffer *ab, __be32 addr,
532 */ 544 */
533void avc_audit(u32 ssid, u32 tsid, 545void avc_audit(u32 ssid, u32 tsid,
534 u16 tclass, u32 requested, 546 u16 tclass, u32 requested,
535 struct av_decision *avd, int result, struct avc_audit_data *a) 547 struct av_decision *avd, int result, struct common_audit_data *a)
536{ 548{
537 struct task_struct *tsk = current; 549 struct common_audit_data stack_data;
538 struct inode *inode = NULL;
539 u32 denied, audited; 550 u32 denied, audited;
540 struct audit_buffer *ab;
541
542 denied = requested & ~avd->allowed; 551 denied = requested & ~avd->allowed;
543 if (denied) { 552 if (denied) {
544 audited = denied; 553 audited = denied;
@@ -551,144 +560,20 @@ void avc_audit(u32 ssid, u32 tsid,
551 if (!(audited & avd->auditallow)) 560 if (!(audited & avd->auditallow))
552 return; 561 return;
553 } 562 }
554 563 if (!a) {
555 ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_AVC); 564 a = &stack_data;
556 if (!ab) 565 memset(a, 0, sizeof(*a));
557 return; /* audit_panic has been called */ 566 a->type = LSM_AUDIT_NO_AUDIT;
558 audit_log_format(ab, "avc: %s ", denied ? "denied" : "granted");
559 avc_dump_av(ab, tclass, audited);
560 audit_log_format(ab, " for ");
561 if (a && a->tsk)
562 tsk = a->tsk;
563 if (tsk && tsk->pid) {
564 audit_log_format(ab, " pid=%d comm=", tsk->pid);
565 audit_log_untrustedstring(ab, tsk->comm);
566 }
567 if (a) {
568 switch (a->type) {
569 case AVC_AUDIT_DATA_IPC:
570 audit_log_format(ab, " key=%d", a->u.ipc_id);
571 break;
572 case AVC_AUDIT_DATA_CAP:
573 audit_log_format(ab, " capability=%d", a->u.cap);
574 break;
575 case AVC_AUDIT_DATA_FS:
576 if (a->u.fs.path.dentry) {
577 struct dentry *dentry = a->u.fs.path.dentry;
578 if (a->u.fs.path.mnt) {
579 audit_log_d_path(ab, "path=",
580 &a->u.fs.path);
581 } else {
582 audit_log_format(ab, " name=");
583 audit_log_untrustedstring(ab, dentry->d_name.name);
584 }
585 inode = dentry->d_inode;
586 } else if (a->u.fs.inode) {
587 struct dentry *dentry;
588 inode = a->u.fs.inode;
589 dentry = d_find_alias(inode);
590 if (dentry) {
591 audit_log_format(ab, " name=");
592 audit_log_untrustedstring(ab, dentry->d_name.name);
593 dput(dentry);
594 }
595 }
596 if (inode)
597 audit_log_format(ab, " dev=%s ino=%lu",
598 inode->i_sb->s_id,
599 inode->i_ino);
600 break;