diff options
-rw-r--r-- | include/linux/audit.h | 3 | ||||
-rw-r--r-- | kernel/audit.c | 31 | ||||
-rw-r--r-- | kernel/audit.h | 11 | ||||
-rw-r--r-- | kernel/auditsc.c | 23 | ||||
-rw-r--r-- | kernel/signal.c | 2 |
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 */ | |||
278 | struct audit_sig_info { | 278 | struct audit_sig_info { |
279 | uid_t uid; | 279 | uid_t uid; |
280 | pid_t pid; | 280 | pid_t pid; |
281 | char ctx[0]; | ||
281 | }; | 282 | }; |
282 | 283 | ||
283 | struct audit_buffer; | 284 | struct audit_buffer; |
@@ -328,7 +329,6 @@ extern int audit_bprm(struct linux_binprm *bprm); | |||
328 | extern int audit_socketcall(int nargs, unsigned long *args); | 329 | extern int audit_socketcall(int nargs, unsigned long *args); |
329 | extern int audit_sockaddr(int len, void *addr); | 330 | extern int audit_sockaddr(int len, void *addr); |
330 | extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt); | 331 | extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt); |
331 | extern void audit_signal_info(int sig, struct task_struct *t); | ||
332 | extern int audit_set_macxattr(const char *name); | 332 | extern int audit_set_macxattr(const char *name); |
333 | #else | 333 | #else |
334 | #define audit_alloc(t) ({ 0; }) | 334 | #define audit_alloc(t) ({ 0; }) |
@@ -349,7 +349,6 @@ extern int audit_set_macxattr(const char *name); | |||
349 | #define audit_socketcall(n,a) ({ 0; }) | 349 | #define audit_socketcall(n,a) ({ 0; }) |
350 | #define audit_sockaddr(len, addr) ({ 0; }) | 350 | #define audit_sockaddr(len, addr) ({ 0; }) |
351 | #define audit_avc_path(dentry, mnt) ({ 0; }) | 351 | #define audit_avc_path(dentry, mnt) ({ 0; }) |
352 | #define audit_signal_info(s,t) do { ; } while (0) | ||
353 | #define audit_set_macxattr(n) do { ; } while (0) | 352 | #define audit_set_macxattr(n) do { ; } while (0) |
354 | #endif | 353 | #endif |
355 | 354 | ||
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; | |||
89 | /* The identity of the user shutting down the audit system. */ | 89 | /* The identity of the user shutting down the audit system. */ |
90 | uid_t audit_sig_uid = -1; | 90 | uid_t audit_sig_uid = -1; |
91 | pid_t audit_sig_pid = -1; | 91 | pid_t audit_sig_pid = -1; |
92 | u32 audit_sig_sid = 0; | ||
92 | 93 | ||
93 | /* Records can be lost in several ways: | 94 | /* Records can be lost in several ways: |
94 | 0) [suppressed in audit_alloc] | 95 | 0) [suppressed in audit_alloc] |
@@ -479,7 +480,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
479 | struct audit_buffer *ab; | 480 | struct audit_buffer *ab; |
480 | u16 msg_type = nlh->nlmsg_type; | 481 | u16 msg_type = nlh->nlmsg_type; |
481 | uid_t loginuid; /* loginuid of sender */ | 482 | uid_t loginuid; /* loginuid of sender */ |
482 | struct audit_sig_info sig_data; | 483 | struct audit_sig_info *sig_data; |
484 | char *ctx; | ||
485 | u32 len; | ||
483 | 486 | ||
484 | err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type); | 487 | err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type); |
485 | if (err) | 488 | if (err) |
@@ -531,12 +534,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
531 | if (status_get->mask & AUDIT_STATUS_PID) { | 534 | if (status_get->mask & AUDIT_STATUS_PID) { |
532 | int old = audit_pid; | 535 | int old = audit_pid; |
533 | if (sid) { | 536 | if (sid) { |
534 | char *ctx = NULL; | 537 | if ((err = selinux_ctxid_to_string( |
535 | u32 len; | ||
536 | int rc; | ||
537 | if ((rc = selinux_ctxid_to_string( | ||
538 | sid, &ctx, &len))) | 538 | sid, &ctx, &len))) |
539 | return rc; | 539 | return err; |
540 | else | 540 | else |
541 | audit_log(NULL, GFP_KERNEL, | 541 | audit_log(NULL, GFP_KERNEL, |
542 | AUDIT_CONFIG_CHANGE, | 542 | AUDIT_CONFIG_CHANGE, |
@@ -572,8 +572,6 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
572 | "user pid=%d uid=%u auid=%u", | 572 | "user pid=%d uid=%u auid=%u", |
573 | pid, uid, loginuid); | 573 | pid, uid, loginuid); |
574 | if (sid) { | 574 | if (sid) { |
575 | char *ctx = NULL; | ||
576 | u32 len; | ||
577 | if (selinux_ctxid_to_string( | 575 | if (selinux_ctxid_to_string( |
578 | sid, &ctx, &len)) { | 576 | sid, &ctx, &len)) { |
579 | audit_log_format(ab, | 577 | audit_log_format(ab, |
@@ -612,10 +610,21 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
612 | loginuid, sid); | 610 | loginuid, sid); |
613 | break; | 611 | break; |
614 | case AUDIT_SIGNAL_INFO: | 612 | case AUDIT_SIGNAL_INFO: |
615 | sig_data.uid = audit_sig_uid; | 613 | err = selinux_ctxid_to_string(audit_sig_sid, &ctx, &len); |
616 | sig_data.pid = audit_sig_pid; | 614 | if (err) |
615 | return err; | ||
616 | sig_data = kmalloc(sizeof(*sig_data) + len, GFP_KERNEL); | ||
617 | if (!sig_data) { | ||
618 | kfree(ctx); | ||
619 | return -ENOMEM; | ||
620 | } | ||
621 | sig_data->uid = audit_sig_uid; | ||
622 | sig_data->pid = audit_sig_pid; | ||
623 | memcpy(sig_data->ctx, ctx, len); | ||
624 | kfree(ctx); | ||
617 | audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO, | 625 | audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO, |
618 | 0, 0, &sig_data, sizeof(sig_data)); | 626 | 0, 0, sig_data, sizeof(*sig_data) + len); |
627 | kfree(sig_data); | ||
619 | break; | 628 | break; |
620 | default: | 629 | default: |
621 | err = -EINVAL; | 630 | 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 { | |||
101 | int audit_send_list(void *); | 101 | int audit_send_list(void *); |
102 | 102 | ||
103 | extern int selinux_audit_rule_update(void); | 103 | extern int selinux_audit_rule_update(void); |
104 | |||
105 | #ifdef CONFIG_AUDITSYSCALL | ||
106 | extern void __audit_signal_info(int sig, struct task_struct *t); | ||
107 | static inline void audit_signal_info(int sig, struct task_struct *t) | ||
108 | { | ||
109 | if (unlikely(audit_pid && t->tgid == audit_pid)) | ||
110 | __audit_signal_info(sig, t); | ||
111 | } | ||
112 | #else | ||
113 | #define audit_signal_info(s,t) | ||
114 | #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) | |||
1376 | * If the audit subsystem is being terminated, record the task (pid) | 1376 | * If the audit subsystem is being terminated, record the task (pid) |
1377 | * and uid that is doing that. | 1377 | * and uid that is doing that. |
1378 | */ | 1378 | */ |
1379 | void audit_signal_info(int sig, struct task_struct *t) | 1379 | void __audit_signal_info(int sig, struct task_struct *t) |
1380 | { | 1380 | { |
1381 | extern pid_t audit_sig_pid; | 1381 | extern pid_t audit_sig_pid; |
1382 | extern uid_t audit_sig_uid; | 1382 | extern uid_t audit_sig_uid; |
1383 | 1383 | extern u32 audit_sig_sid; | |
1384 | if (unlikely(audit_pid && t->tgid == audit_pid)) { | 1384 | |
1385 | if (sig == SIGTERM || sig == SIGHUP) { | 1385 | if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1) { |
1386 | struct audit_context *ctx = current->audit_context; | 1386 | struct task_struct *tsk = current; |
1387 | audit_sig_pid = current->pid; | 1387 | struct audit_context *ctx = tsk->audit_context; |
1388 | if (ctx) | 1388 | audit_sig_pid = tsk->pid; |
1389 | audit_sig_uid = ctx->loginuid; | 1389 | if (ctx) |
1390 | else | 1390 | audit_sig_uid = ctx->loginuid; |
1391 | audit_sig_uid = current->uid; | 1391 | else |
1392 | } | 1392 | audit_sig_uid = tsk->uid; |
1393 | selinux_get_task_sid(tsk, &audit_sig_sid); | ||
1393 | } | 1394 | } |
1394 | } | 1395 | } |
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 @@ | |||
23 | #include <linux/syscalls.h> | 23 | #include <linux/syscalls.h> |
24 | #include <linux/ptrace.h> | 24 | #include <linux/ptrace.h> |
25 | #include <linux/signal.h> | 25 | #include <linux/signal.h> |
26 | #include <linux/audit.h> | ||
27 | #include <linux/capability.h> | 26 | #include <linux/capability.h> |
28 | #include <asm/param.h> | 27 | #include <asm/param.h> |
29 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
30 | #include <asm/unistd.h> | 29 | #include <asm/unistd.h> |
31 | #include <asm/siginfo.h> | 30 | #include <asm/siginfo.h> |
31 | #include "audit.h" /* audit_signal_info() */ | ||
32 | 32 | ||
33 | /* | 33 | /* |
34 | * SLAB caches for signal bits. | 34 | * SLAB caches for signal bits. |