aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/connector/cn_proc.c25
-rw-r--r--include/linux/cn_proc.h4
-rw-r--r--include/uapi/linux/cn_proc.h10
-rw-r--r--kernel/signal.c2
4 files changed, 40 insertions, 1 deletions
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 1110478dd0fd..08ae128cce9b 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -232,6 +232,31 @@ void proc_comm_connector(struct task_struct *task)
232 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); 232 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
233} 233}
234 234
235void proc_coredump_connector(struct task_struct *task)
236{
237 struct cn_msg *msg;
238 struct proc_event *ev;
239 __u8 buffer[CN_PROC_MSG_SIZE];
240 struct timespec ts;
241
242 if (atomic_read(&proc_event_num_listeners) < 1)
243 return;
244
245 msg = (struct cn_msg *)buffer;
246 ev = (struct proc_event *)msg->data;
247 get_seq(&msg->seq, &ev->cpu);
248 ktime_get_ts(&ts); /* get high res monotonic timestamp */
249 put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
250 ev->what = PROC_EVENT_COREDUMP;
251 ev->event_data.coredump.process_pid = task->pid;
252 ev->event_data.coredump.process_tgid = task->tgid;
253
254 memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
255 msg->ack = 0; /* not used */
256 msg->len = sizeof(*ev);
257 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
258}
259
235void proc_exit_connector(struct task_struct *task) 260void proc_exit_connector(struct task_struct *task)
236{ 261{
237 struct cn_msg *msg; 262 struct cn_msg *msg;
diff --git a/include/linux/cn_proc.h b/include/linux/cn_proc.h
index 2c1bc1ea04ee..1d5b02a96c46 100644
--- a/include/linux/cn_proc.h
+++ b/include/linux/cn_proc.h
@@ -26,6 +26,7 @@ void proc_id_connector(struct task_struct *task, int which_id);
26void proc_sid_connector(struct task_struct *task); 26void proc_sid_connector(struct task_struct *task);
27void proc_ptrace_connector(struct task_struct *task, int which_id); 27void proc_ptrace_connector(struct task_struct *task, int which_id);
28void proc_comm_connector(struct task_struct *task); 28void proc_comm_connector(struct task_struct *task);
29void proc_coredump_connector(struct task_struct *task);
29void proc_exit_connector(struct task_struct *task); 30void proc_exit_connector(struct task_struct *task);
30#else 31#else
31static inline void proc_fork_connector(struct task_struct *task) 32static inline void proc_fork_connector(struct task_struct *task)
@@ -48,6 +49,9 @@ static inline void proc_ptrace_connector(struct task_struct *task,
48 int ptrace_id) 49 int ptrace_id)
49{} 50{}
50 51
52static inline void proc_coredump_connector(struct task_struct *task)
53{}
54
51static inline void proc_exit_connector(struct task_struct *task) 55static inline void proc_exit_connector(struct task_struct *task)
52{} 56{}
53#endif /* CONFIG_PROC_EVENTS */ 57#endif /* CONFIG_PROC_EVENTS */
diff --git a/include/uapi/linux/cn_proc.h b/include/uapi/linux/cn_proc.h
index 0d7b49973bb3..f6c271035bbd 100644
--- a/include/uapi/linux/cn_proc.h
+++ b/include/uapi/linux/cn_proc.h
@@ -56,7 +56,9 @@ struct proc_event {
56 PROC_EVENT_PTRACE = 0x00000100, 56 PROC_EVENT_PTRACE = 0x00000100,
57 PROC_EVENT_COMM = 0x00000200, 57 PROC_EVENT_COMM = 0x00000200,
58 /* "next" should be 0x00000400 */ 58 /* "next" should be 0x00000400 */
59 /* "last" is the last process event: exit */ 59 /* "last" is the last process event: exit,
60 * while "next to last" is coredumping event */
61 PROC_EVENT_COREDUMP = 0x40000000,
60 PROC_EVENT_EXIT = 0x80000000 62 PROC_EVENT_EXIT = 0x80000000
61 } what; 63 } what;
62 __u32 cpu; 64 __u32 cpu;
@@ -110,11 +112,17 @@ struct proc_event {
110 char comm[16]; 112 char comm[16];
111 } comm; 113 } comm;
112 114
115 struct coredump_proc_event {
116 __kernel_pid_t process_pid;
117 __kernel_pid_t process_tgid;
118 } coredump;
119
113 struct exit_proc_event { 120 struct exit_proc_event {
114 __kernel_pid_t process_pid; 121 __kernel_pid_t process_pid;
115 __kernel_pid_t process_tgid; 122 __kernel_pid_t process_tgid;
116 __u32 exit_code, exit_signal; 123 __u32 exit_code, exit_signal;
117 } exit; 124 } exit;
125
118 } event_data; 126 } event_data;
119}; 127};
120 128
diff --git a/kernel/signal.c b/kernel/signal.c
index dd72567767d9..497330ec2ae9 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -32,6 +32,7 @@
32#include <linux/user_namespace.h> 32#include <linux/user_namespace.h>
33#include <linux/uprobes.h> 33#include <linux/uprobes.h>
34#include <linux/compat.h> 34#include <linux/compat.h>
35#include <linux/cn_proc.h>
35#define CREATE_TRACE_POINTS 36#define CREATE_TRACE_POINTS
36#include <trace/events/signal.h> 37#include <trace/events/signal.h>
37 38
@@ -2350,6 +2351,7 @@ relock:
2350 if (sig_kernel_coredump(signr)) { 2351 if (sig_kernel_coredump(signr)) {
2351 if (print_fatal_signals) 2352 if (print_fatal_signals)
2352 print_fatal_signal(info->si_signo); 2353 print_fatal_signal(info->si_signo);
2354 proc_coredump_connector(current);
2353 /* 2355 /*
2354 * If it was able to dump core, this kills all 2356 * If it was able to dump core, this kills all
2355 * other threads in the group and synchronizes with 2357 * other threads in the group and synchronizes with