Commit e1396065 authored by Al Viro's avatar Al Viro

[PATCH] collect sid of those who send signals to auditd

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 473ae30b
...@@ -278,6 +278,7 @@ struct audit_rule { /* for AUDIT_LIST, AUDIT_ADD, and AUDIT_DEL */ ...@@ -278,6 +278,7 @@ struct audit_rule { /* for AUDIT_LIST, AUDIT_ADD, and AUDIT_DEL */
struct audit_sig_info { struct audit_sig_info {
uid_t uid; uid_t uid;
pid_t pid; pid_t pid;
char ctx[0];
}; };
struct audit_buffer; struct audit_buffer;
...@@ -328,7 +329,6 @@ extern int audit_bprm(struct linux_binprm *bprm); ...@@ -328,7 +329,6 @@ extern int audit_bprm(struct linux_binprm *bprm);
extern int audit_socketcall(int nargs, unsigned long *args); extern int audit_socketcall(int nargs, unsigned long *args);
extern int audit_sockaddr(int len, void *addr); extern int audit_sockaddr(int len, void *addr);
extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt); 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); extern int audit_set_macxattr(const char *name);
#else #else
#define audit_alloc(t) ({ 0; }) #define audit_alloc(t) ({ 0; })
...@@ -349,7 +349,6 @@ extern int audit_set_macxattr(const char *name); ...@@ -349,7 +349,6 @@ extern int audit_set_macxattr(const char *name);
#define audit_socketcall(n,a) ({ 0; }) #define audit_socketcall(n,a) ({ 0; })
#define audit_sockaddr(len, addr) ({ 0; }) #define audit_sockaddr(len, addr) ({ 0; })
#define audit_avc_path(dentry, mnt) ({ 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) #define audit_set_macxattr(n) do { ; } while (0)
#endif #endif
......
...@@ -89,6 +89,7 @@ static int audit_backlog_wait_overflow = 0; ...@@ -89,6 +89,7 @@ static int audit_backlog_wait_overflow = 0;
/* The identity of the user shutting down the audit system. */ /* The identity of the user shutting down the audit system. */
uid_t audit_sig_uid = -1; uid_t audit_sig_uid = -1;
pid_t audit_sig_pid = -1; pid_t audit_sig_pid = -1;
u32 audit_sig_sid = 0;
/* Records can be lost in several ways: /* Records can be lost in several ways:
0) [suppressed in audit_alloc] 0) [suppressed in audit_alloc]
...@@ -479,7 +480,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) ...@@ -479,7 +480,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
struct audit_buffer *ab; struct audit_buffer *ab;
u16 msg_type = nlh->nlmsg_type; u16 msg_type = nlh->nlmsg_type;
uid_t loginuid; /* loginuid of sender */ 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); err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type);
if (err) if (err)
...@@ -531,12 +534,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) ...@@ -531,12 +534,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
if (status_get->mask & AUDIT_STATUS_PID) { if (status_get->mask & AUDIT_STATUS_PID) {
int old = audit_pid; int old = audit_pid;
if (sid) { if (sid) {
char *ctx = NULL; if ((err = selinux_ctxid_to_string(
u32 len;
int rc;
if ((rc = selinux_ctxid_to_string(
sid, &ctx, &len))) sid, &ctx, &len)))
return rc; return err;
else else
audit_log(NULL, GFP_KERNEL, audit_log(NULL, GFP_KERNEL,
AUDIT_CONFIG_CHANGE, AUDIT_CONFIG_CHANGE,
...@@ -572,8 +572,6 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) ...@@ -572,8 +572,6 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
"user pid=%d uid=%u auid=%u", "user pid=%d uid=%u auid=%u",
pid, uid, loginuid); pid, uid, loginuid);
if (sid) { if (sid) {
char *ctx = NULL;
u32 len;
if (selinux_ctxid_to_string( if (selinux_ctxid_to_string(
sid, &ctx, &len)) { sid, &ctx, &len)) {
audit_log_format(ab, audit_log_format(ab,
...@@ -612,10 +610,21 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) ...@@ -612,10 +610,21 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
loginuid, sid); loginuid, sid);
break; break;
case AUDIT_SIGNAL_INFO: case AUDIT_SIGNAL_INFO:
sig_data.uid = audit_sig_uid; err = selinux_ctxid_to_string(audit_sig_sid, &ctx, &len);
sig_data.pid = audit_sig_pid; 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, 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; break;
default: default:
err = -EINVAL; err = -EINVAL;
......
...@@ -101,3 +101,14 @@ struct audit_netlink_list { ...@@ -101,3 +101,14 @@ struct audit_netlink_list {
int audit_send_list(void *); int audit_send_list(void *);
extern int selinux_audit_rule_update(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
...@@ -1376,19 +1376,20 @@ int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt) ...@@ -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) * If the audit subsystem is being terminated, record the task (pid)
* and uid that is doing that. * 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 pid_t audit_sig_pid;
extern uid_t audit_sig_uid; extern uid_t audit_sig_uid;
extern u32 audit_sig_sid;
if (unlikely(audit_pid && t->tgid == audit_pid)) { if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1) {
if (sig == SIGTERM || sig == SIGHUP) { struct task_struct *tsk = current;
struct audit_context *ctx = current->audit_context; struct audit_context *ctx = tsk->audit_context;
audit_sig_pid = current->pid; audit_sig_pid = tsk->pid;
if (ctx) if (ctx)
audit_sig_uid = ctx->loginuid; audit_sig_uid = ctx->loginuid;
else else
audit_sig_uid = current->uid; audit_sig_uid = tsk->uid;
} selinux_get_task_sid(tsk, &audit_sig_sid);
} }
} }
...@@ -23,12 +23,12 @@ ...@@ -23,12 +23,12 @@
#include <linux/syscalls.h> #include <linux/syscalls.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/audit.h>
#include <linux/capability.h> #include <linux/capability.h>
#include <asm/param.h> #include <asm/param.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/unistd.h> #include <asm/unistd.h>
#include <asm/siginfo.h> #include <asm/siginfo.h>
#include "audit.h" /* audit_signal_info() */
/* /*
* SLAB caches for signal bits. * SLAB caches for signal bits.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment