diff options
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 */ |