diff options
author | Stephen Smalley <sds@tycho.nsa.gov> | 2005-05-20 19:15:52 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@shinybook.infradead.org> | 2005-05-20 19:15:52 -0400 |
commit | 011161051bbc25f7f8b7df059dbd934c534443f0 (patch) | |
tree | f1ca3727e4130cacad86dfdae65e7533fcb67784 /kernel | |
parent | fb19b4c6aa024837a0071f07baa07dbf49d07151 (diff) |
AUDIT: Avoid sleeping function in SElinux AVC audit.
This patch changes the SELinux AVC to defer logging of paths to the audit
framework upon syscall exit, by saving a reference to the (dentry,vfsmount)
pair in an auxiliary audit item on the current audit context for processing
by audit_log_exit.
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/auditsc.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 78d7a13fc86f..8dc5b2767145 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <asm/types.h> | 34 | #include <asm/types.h> |
35 | #include <linux/mm.h> | 35 | #include <linux/mm.h> |
36 | #include <linux/module.h> | 36 | #include <linux/module.h> |
37 | #include <linux/mount.h> | ||
37 | #include <linux/socket.h> | 38 | #include <linux/socket.h> |
38 | #include <linux/audit.h> | 39 | #include <linux/audit.h> |
39 | #include <linux/personality.h> | 40 | #include <linux/personality.h> |
@@ -124,6 +125,11 @@ struct audit_aux_data_sockaddr { | |||
124 | char a[0]; | 125 | char a[0]; |
125 | }; | 126 | }; |
126 | 127 | ||
128 | struct audit_aux_data_path { | ||
129 | struct audit_aux_data d; | ||
130 | struct dentry *dentry; | ||
131 | struct vfsmount *mnt; | ||
132 | }; | ||
127 | 133 | ||
128 | /* The per-task audit context. */ | 134 | /* The per-task audit context. */ |
129 | struct audit_context { | 135 | struct audit_context { |
@@ -553,6 +559,11 @@ static inline void audit_free_aux(struct audit_context *context) | |||
553 | struct audit_aux_data *aux; | 559 | struct audit_aux_data *aux; |
554 | 560 | ||
555 | while ((aux = context->aux)) { | 561 | while ((aux = context->aux)) { |
562 | if (aux->type == AUDIT_AVC_PATH) { | ||
563 | struct audit_aux_data_path *axi = (void *)aux; | ||
564 | dput(axi->dentry); | ||
565 | mntput(axi->mnt); | ||
566 | } | ||
556 | context->aux = aux->next; | 567 | context->aux = aux->next; |
557 | kfree(aux); | 568 | kfree(aux); |
558 | } | 569 | } |
@@ -724,6 +735,14 @@ static void audit_log_exit(struct audit_context *context) | |||
724 | audit_log_format(ab, "saddr="); | 735 | audit_log_format(ab, "saddr="); |
725 | audit_log_hex(ab, axs->a, axs->len); | 736 | audit_log_hex(ab, axs->a, axs->len); |
726 | break; } | 737 | break; } |
738 | |||
739 | case AUDIT_AVC_PATH: { | ||
740 | struct audit_aux_data_path *axi = (void *)aux; | ||
741 | audit_log_d_path(ab, "path=", axi->dentry, axi->mnt); | ||
742 | dput(axi->dentry); | ||
743 | mntput(axi->mnt); | ||
744 | break; } | ||
745 | |||
727 | } | 746 | } |
728 | audit_log_end(ab); | 747 | audit_log_end(ab); |
729 | 748 | ||
@@ -1124,6 +1143,27 @@ int audit_sockaddr(int len, void *a) | |||
1124 | return 0; | 1143 | return 0; |
1125 | } | 1144 | } |
1126 | 1145 | ||
1146 | int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt) | ||
1147 | { | ||
1148 | struct audit_aux_data_path *ax; | ||
1149 | struct audit_context *context = current->audit_context; | ||
1150 | |||
1151 | if (likely(!context)) | ||
1152 | return 0; | ||
1153 | |||
1154 | ax = kmalloc(sizeof(*ax), GFP_ATOMIC); | ||
1155 | if (!ax) | ||
1156 | return -ENOMEM; | ||
1157 | |||
1158 | ax->dentry = dget(dentry); | ||
1159 | ax->mnt = mntget(mnt); | ||
1160 | |||
1161 | ax->d.type = AUDIT_AVC_PATH; | ||
1162 | ax->d.next = context->aux; | ||
1163 | context->aux = (void *)ax; | ||
1164 | return 0; | ||
1165 | } | ||
1166 | |||
1127 | void audit_signal_info(int sig, struct task_struct *t) | 1167 | void audit_signal_info(int sig, struct task_struct *t) |
1128 | { | 1168 | { |
1129 | extern pid_t audit_sig_pid; | 1169 | extern pid_t audit_sig_pid; |