aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Grubb <sgrubb@redhat.com>2005-05-06 07:38:39 -0400
committerDavid Woodhouse <dwmw2@shinybook.infradead.org>2005-05-06 07:38:39 -0400
commitc2f0c7c356dc9ae15419f00c725a2fcc58eeff58 (patch)
tree2b765b791115e0e85b45bc98800fd2650b23155b
parent2512809255d018744fe6c2f5e996c83769846c07 (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>
-rw-r--r--include/linux/audit.h25
-rw-r--r--kernel/audit.c14
-rw-r--r--kernel/auditsc.c19
-rw-r--r--kernel/signal.c7
-rw-r--r--security/selinux/nlmsgtab.c1
5 files changed, 56 insertions, 10 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 19f04b049798..baa80760824c 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -28,14 +28,16 @@
28#include <linux/elf.h> 28#include <linux/elf.h>
29 29
30/* Request and reply types */ 30/* Request and reply types */
31#define AUDIT_GET 1000 /* Get status */ 31#define AUDIT_GET 1000 /* Get status */
32#define AUDIT_SET 1001 /* Set status (enable/disable/auditd) */ 32#define AUDIT_SET 1001 /* Set status (enable/disable/auditd) */
33#define AUDIT_LIST 1002 /* List filtering rules */ 33#define AUDIT_LIST 1002 /* List filtering rules */
34#define AUDIT_ADD 1003 /* Add filtering rule */ 34#define AUDIT_ADD 1003 /* Add filtering rule */
35#define AUDIT_DEL 1004 /* Delete filtering rule */ 35#define AUDIT_DEL 1004 /* Delete filtering rule */
36#define AUDIT_USER 1005 /* Send a message from user-space */ 36#define AUDIT_USER 1005 /* Send a message from user-space */
37#define AUDIT_LOGIN 1006 /* Define the login id and informaiton */ 37#define AUDIT_LOGIN 1006 /* Define the login id and information */
38#define AUDIT_KERNEL 2000 /* Asynchronous audit record. NOT A REQUEST. */ 38#define AUDIT_SIGNAL_INFO 1010 /* Get information about sender of signal*/
39
40#define AUDIT_KERNEL 2000 /* Asynchronous audit record. NOT A REQUEST. */
39 41
40/* Rule flags */ 42/* Rule flags */
41#define AUDIT_PER_TASK 0x01 /* Apply rule at task creation (not syscall) */ 43#define AUDIT_PER_TASK 0x01 /* Apply rule at task creation (not syscall) */
@@ -161,6 +163,11 @@ struct audit_rule { /* for AUDIT_LIST, AUDIT_ADD, and AUDIT_DEL */
161 163
162#ifdef __KERNEL__ 164#ifdef __KERNEL__
163 165
166struct audit_sig_info {
167 uid_t uid;
168 pid_t pid;
169};
170
164struct audit_buffer; 171struct audit_buffer;
165struct audit_context; 172struct audit_context;
166struct inode; 173struct inode;
@@ -190,6 +197,7 @@ extern void audit_get_stamp(struct audit_context *ctx,
190extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid); 197extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid);
191extern uid_t audit_get_loginuid(struct audit_context *ctx); 198extern uid_t audit_get_loginuid(struct audit_context *ctx);
192extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode); 199extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
200extern void audit_signal_info(int sig, struct task_struct *t);
193#else 201#else
194#define audit_alloc(t) ({ 0; }) 202#define audit_alloc(t) ({ 0; })
195#define audit_free(t) do { ; } while (0) 203#define audit_free(t) do { ; } while (0)
@@ -200,6 +208,7 @@ extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mo
200#define audit_inode(n,i) do { ; } while (0) 208#define audit_inode(n,i) do { ; } while (0)
201#define audit_get_loginuid(c) ({ -1; }) 209#define audit_get_loginuid(c) ({ -1; })
202#define audit_ipc_perms(q,u,g,m) ({ 0; }) 210#define audit_ipc_perms(q,u,g,m) ({ 0; })
211#define audit_signal_info(s,t) do { ; } while (0)
203#endif 212#endif
204 213
205#ifdef CONFIG_AUDIT 214#ifdef CONFIG_AUDIT
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. */
71static int audit_pid; 71int 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;
79static int audit_backlog_limit = 64; 79static int audit_backlog_limit = 64;
80static atomic_t audit_backlog = ATOMIC_INIT(0); 80static atomic_t audit_backlog = ATOMIC_INIT(0);
81 81
82/* The identity of the user shutting down the audit system. */
83uid_t audit_sig_uid = -1;
84pid_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
1060void 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 */
diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c
index b3adb481bc25..deac14367d43 100644
--- a/security/selinux/nlmsgtab.c
+++ b/security/selinux/nlmsgtab.c
@@ -97,6 +97,7 @@ static struct nlmsg_perm nlmsg_audit_perms[] =
97 { AUDIT_ADD, NETLINK_AUDIT_SOCKET__NLMSG_WRITE }, 97 { AUDIT_ADD, NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
98 { AUDIT_DEL, NETLINK_AUDIT_SOCKET__NLMSG_WRITE }, 98 { AUDIT_DEL, NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
99 { AUDIT_USER, NETLINK_AUDIT_SOCKET__NLMSG_RELAY }, 99 { AUDIT_USER, NETLINK_AUDIT_SOCKET__NLMSG_RELAY },
100 { AUDIT_SIGNAL_INFO, NETLINK_AUDIT_SOCKET__NLMSG_READ },
100}; 101};
101 102
102 103