diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2006-05-25 10:19:47 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2006-06-20 05:25:21 -0400 |
commit | e1396065e0489f98b35021b97907ab4edbfb24e1 (patch) | |
tree | a276ea0a2ece9132d435adf1a1f82d0ada1ae938 | |
parent | 473ae30bc7b1dda5c5791c773f95e9424ddfead9 (diff) |
[PATCH] collect sid of those who send signals to auditd
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | include/linux/audit.h | 3 | ||||
-rw-r--r-- | kernel/audit.c | 31 | ||||
-rw-r--r-- | kernel/audit.h | 11 | ||||
-rw-r--r-- | kernel/auditsc.c | 23 | ||||
-rw-r--r-- | kernel/signal.c | 2 |
5 files changed, 45 insertions, 25 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h index 1a221b65f7b7..1057e90bd3e3 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -278,6 +278,7 @@ struct audit_rule { /* for AUDIT_LIST, AUDIT_ADD, and AUDIT_DEL */ struct audit_sig_info { uid_t uid; pid_t pid; + char ctx[0]; }; struct audit_buffer; @@ -328,7 +329,6 @@ extern int audit_bprm(struct linux_binprm *bprm); extern int audit_socketcall(int nargs, unsigned long *args); extern int audit_sockaddr(int len, void *addr); extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt); -extern void audit_signal_info(int sig, struct task_struct *t); extern int audit_set_macxattr(const char *name); #else #define audit_alloc(t) ({ 0; }) @@ -349,7 +349,6 @@ extern int audit_set_macxattr(const char *name); #define audit_socketcall(n,a) ({ 0; }) #define audit_sockaddr(len, addr) ({ 0; }) #define audit_avc_path(dentry, mnt) ({ 0; }) -#define audit_signal_info(s,t) do { ; } while (0) #define audit_set_macxattr(n) do { ; } while (0) #endif diff --git a/kernel/audit.c b/kernel/audit.c index d09f131b111a..bb20922d08cc 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -89,6 +89,7 @@ static int audit_backlog_wait_overflow = 0; /* The identity of the user shutting down the audit system. */ uid_t audit_sig_uid = -1; pid_t audit_sig_pid = -1; +u32 audit_sig_sid = 0; /* Records can be lost in several ways: 0) [suppressed in audit_alloc] @@ -479,7 +480,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) struct audit_buffer *ab; u16 msg_type = nlh->nlmsg_type; uid_t loginuid; /* loginuid of sender */ - struct audit_sig_info sig_data; + struct audit_sig_info *sig_data; + char *ctx; + u32 len; err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type); if (err) @@ -531,12 +534,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) if (status_get->mask & AUDIT_STATUS_PID) { int old = audit_pid; if (sid) { - char *ctx = NULL; - u32 len; - int rc; - if ((rc = selinux_ctxid_to_string( + if ((err = selinux_ctxid_to_string( sid, &ctx, &len))) - return rc; + return err; else audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, @@ -572,8 +572,6 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) "user pid=%d uid=%u auid=%u", pid, uid, loginuid); if (sid) { - char *ctx = NULL; - u32 len; if (selinux_ctxid_to_string( sid, &ctx, &len)) { audit_log_format(ab, @@ -612,10 +610,21 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) loginuid, sid); break; case AUDIT_SIGNAL_INFO: - sig_data.uid = audit_sig_uid; - sig_data.pid = audit_sig_pid; + err = selinux_ctxid_to_string(audit_sig_sid, &ctx, &len); + if (err) + return err; + sig_data = kmalloc(sizeof(*sig_data) + len, GFP_KERNEL); + if (!sig_data) { + kfree(ctx); + return -ENOMEM; + } + sig_data->uid = audit_sig_uid; + sig_data->pid = audit_sig_pid; + memcpy(sig_data->ctx, ctx, len); + kfree(ctx); audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO, - 0, 0, &sig_data, sizeof(sig_data)); + 0, 0, sig_data, sizeof(*sig_data) + len); + kfree(sig_data); break; default: err = -EINVAL; diff --git a/kernel/audit.h b/kernel/audit.h index 8948fc1e9e54..52cb1e31d522 100644 --- a/kernel/audit.h +++ b/kernel/audit.h @@ -101,3 +101,14 @@ struct audit_netlink_list { int audit_send_list(void *); extern int selinux_audit_rule_update(void); + +#ifdef CONFIG_AUDITSYSCALL +extern void __audit_signal_info(int sig, struct task_struct *t); +static inline void audit_signal_info(int sig, struct task_struct *t) +{ + if (unlikely(audit_pid && t->tgid == audit_pid)) + __audit_signal_info(sig, t); +} +#else +#define audit_signal_info(s,t) +#endif diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 114f921979ec..4ca913daa7da 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1376,19 +1376,20 @@ int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt) * If the audit subsystem is being terminated, record the task (pid) * and uid that is doing that. */ -void audit_signal_info(int sig, struct task_struct *t) +void __audit_signal_info(int sig, struct task_struct *t) { extern pid_t audit_sig_pid; extern uid_t audit_sig_uid; - - if (unlikely(audit_pid && t->tgid == audit_pid)) { - if (sig == SIGTERM || sig == SIGHUP) { - struct audit_context *ctx = current->audit_context; - audit_sig_pid = current->pid; - if (ctx) - audit_sig_uid = ctx->loginuid; - else - audit_sig_uid = current->uid; - } + extern u32 audit_sig_sid; + + if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1) { + struct task_struct *tsk = current; + struct audit_context *ctx = tsk->audit_context; + audit_sig_pid = tsk->pid; + if (ctx) + audit_sig_uid = ctx->loginuid; + else + audit_sig_uid = tsk->uid; + selinux_get_task_sid(tsk, &audit_sig_sid); } } diff --git a/kernel/signal.c b/kernel/signal.c index e5f8aea78ffe..1b3c921737e2 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -23,12 +23,12 @@ #include <linux/syscalls.h> #include <linux/ptrace.h> #include <linux/signal.h> -#include <linux/audit.h> #include <linux/capability.h> #include <asm/param.h> #include <asm/uaccess.h> #include <asm/unistd.h> #include <asm/siginfo.h> +#include "audit.h" /* audit_signal_info() */ /* * SLAB caches for signal bits. |