summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2006-05-25 10:19:47 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2006-06-20 05:25:21 -0400
commite1396065e0489f98b35021b97907ab4edbfb24e1 (patch)
treea276ea0a2ece9132d435adf1a1f82d0ada1ae938
parent473ae30bc7b1dda5c5791c773f95e9424ddfead9 (diff)
downloadlinux-e1396065e0489f98b35021b97907ab4edbfb24e1.tar.bz2
[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.h3
-rw-r--r--kernel/audit.c31
-rw-r--r--kernel/audit.h11
-rw-r--r--kernel/auditsc.c23
-rw-r--r--kernel/signal.c2
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.