diff options
author | Steve Grubb <sgrubb@redhat.com> | 2005-05-06 07:38:39 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@shinybook.infradead.org> | 2005-05-06 07:38:39 -0400 |
commit | c2f0c7c356dc9ae15419f00c725a2fcc58eeff58 (patch) | |
tree | 2b765b791115e0e85b45bc98800fd2650b23155b /kernel | |
parent | 2512809255d018744fe6c2f5e996c83769846c07 (diff) |
The attached patch addresses the problem with getting the audit daemon
shutdown credential information. It creates a new message type
AUDIT_TERM_INFO, which is used by the audit daemon to query who issued the
shutdown.
It requires the placement of a hook function that gathers the information. The
hook is after the DAC & MAC checks and before the function returns. Racing
threads could overwrite the uid & pid - but they would have to be root and
have policy that allows signalling the audit daemon. That should be a
manageable risk.
The userspace component will be released later in audit 0.7.2. When it
receives the TERM signal, it queries the kernel for shutdown information.
When it receives it, it writes the message and exits. The message looks
like this:
type=DAEMON msg=auditd(1114551182.000) auditd normal halt, sending pid=2650
uid=525, auditd pid=1685
Signed-off-by: Steve Grubb <sgrubb@redhat.com>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/audit.c | 14 | ||||
-rw-r--r-- | kernel/auditsc.c | 19 | ||||
-rw-r--r-- | kernel/signal.c | 7 |
3 files changed, 38 insertions, 2 deletions
diff --git a/kernel/audit.c b/kernel/audit.c index 9c4f1af0c794..6f344b44d3d3 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
@@ -68,7 +68,7 @@ static int audit_failure = AUDIT_FAIL_PRINTK; | |||
68 | 68 | ||
69 | /* If audit records are to be written to the netlink socket, audit_pid | 69 | /* If audit records are to be written to the netlink socket, audit_pid |
70 | * contains the (non-zero) pid. */ | 70 | * contains the (non-zero) pid. */ |
71 | static int audit_pid; | 71 | int audit_pid; |
72 | 72 | ||
73 | /* If audit_limit is non-zero, limit the rate of sending audit records | 73 | /* If audit_limit is non-zero, limit the rate of sending audit records |
74 | * to that number per second. This prevents DoS attacks, but results in | 74 | * to that number per second. This prevents DoS attacks, but results in |
@@ -79,6 +79,10 @@ static int audit_rate_limit; | |||
79 | static int audit_backlog_limit = 64; | 79 | static int audit_backlog_limit = 64; |
80 | static atomic_t audit_backlog = ATOMIC_INIT(0); | 80 | static atomic_t audit_backlog = ATOMIC_INIT(0); |
81 | 81 | ||
82 | /* The identity of the user shutting down the audit system. */ | ||
83 | uid_t audit_sig_uid = -1; | ||
84 | pid_t audit_sig_pid = -1; | ||
85 | |||
82 | /* Records can be lost in several ways: | 86 | /* Records can be lost in several ways: |
83 | 0) [suppressed in audit_alloc] | 87 | 0) [suppressed in audit_alloc] |
84 | 1) out of memory in audit_log_start [kmalloc of struct audit_buffer] | 88 | 1) out of memory in audit_log_start [kmalloc of struct audit_buffer] |
@@ -321,6 +325,7 @@ static int audit_netlink_ok(kernel_cap_t eff_cap, u16 msg_type) | |||
321 | case AUDIT_SET: | 325 | case AUDIT_SET: |
322 | case AUDIT_ADD: | 326 | case AUDIT_ADD: |
323 | case AUDIT_DEL: | 327 | case AUDIT_DEL: |
328 | case AUDIT_SIGNAL_INFO: | ||
324 | if (!cap_raised(eff_cap, CAP_AUDIT_CONTROL)) | 329 | if (!cap_raised(eff_cap, CAP_AUDIT_CONTROL)) |
325 | err = -EPERM; | 330 | err = -EPERM; |
326 | break; | 331 | break; |
@@ -344,6 +349,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
344 | struct audit_buffer *ab; | 349 | struct audit_buffer *ab; |
345 | u16 msg_type = nlh->nlmsg_type; | 350 | u16 msg_type = nlh->nlmsg_type; |
346 | uid_t loginuid; /* loginuid of sender */ | 351 | uid_t loginuid; /* loginuid of sender */ |
352 | struct audit_sig_info sig_data; | ||
347 | 353 | ||
348 | err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type); | 354 | err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type); |
349 | if (err) | 355 | if (err) |
@@ -419,6 +425,12 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
419 | err = -EOPNOTSUPP; | 425 | err = -EOPNOTSUPP; |
420 | #endif | 426 | #endif |
421 | break; | 427 | break; |
428 | case AUDIT_SIGNAL_INFO: | ||
429 | sig_data.uid = audit_sig_uid; | ||
430 | sig_data.pid = audit_sig_pid; | ||
431 | audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO, | ||
432 | 0, 0, &sig_data, sizeof(sig_data)); | ||
433 | break; | ||
422 | default: | 434 | default: |
423 | err = -EINVAL; | 435 | err = -EINVAL; |
424 | break; | 436 | break; |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 37b3ac94bc47..f1bf66510cd3 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -1056,3 +1056,22 @@ int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode) | |||
1056 | context->aux = (void *)ax; | 1056 | context->aux = (void *)ax; |
1057 | return 0; | 1057 | return 0; |
1058 | } | 1058 | } |
1059 | |||
1060 | void audit_signal_info(int sig, struct task_struct *t) | ||
1061 | { | ||
1062 | extern pid_t audit_sig_pid; | ||
1063 | extern uid_t audit_sig_uid; | ||
1064 | extern int audit_pid; | ||
1065 | |||
1066 | if (unlikely(audit_pid && t->pid == audit_pid)) { | ||
1067 | if (sig == SIGTERM || sig == SIGHUP) { | ||
1068 | struct audit_context *ctx = current->audit_context; | ||
1069 | audit_sig_pid = current->pid; | ||
1070 | if (ctx) | ||
1071 | audit_sig_uid = ctx->loginuid; | ||
1072 | else | ||
1073 | audit_sig_uid = current->uid; | ||
1074 | } | ||
1075 | } | ||
1076 | } | ||
1077 | |||
diff --git a/kernel/signal.c b/kernel/signal.c index 8f3debc77c5b..293e189d8bc3 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/ptrace.h> | 24 | #include <linux/ptrace.h> |
25 | #include <linux/posix-timers.h> | 25 | #include <linux/posix-timers.h> |
26 | #include <linux/signal.h> | 26 | #include <linux/signal.h> |
27 | #include <linux/audit.h> | ||
27 | #include <asm/param.h> | 28 | #include <asm/param.h> |
28 | #include <asm/uaccess.h> | 29 | #include <asm/uaccess.h> |
29 | #include <asm/unistd.h> | 30 | #include <asm/unistd.h> |
@@ -658,7 +659,11 @@ static int check_kill_permission(int sig, struct siginfo *info, | |||
658 | && (current->uid ^ t->suid) && (current->uid ^ t->uid) | 659 | && (current->uid ^ t->suid) && (current->uid ^ t->uid) |
659 | && !capable(CAP_KILL)) | 660 | && !capable(CAP_KILL)) |
660 | return error; | 661 | return error; |
661 | return security_task_kill(t, info, sig); | 662 | |
663 | error = security_task_kill(t, info, sig); | ||
664 | if (!error) | ||
665 | audit_signal_info(sig, t); /* Let audit system see the signal */ | ||
666 | return error; | ||
662 | } | 667 | } |
663 | 668 | ||
664 | /* forward decl */ | 669 | /* forward decl */ |