diff options
-rw-r--r-- | drivers/connector/cn_proc.c | 25 | ||||
-rw-r--r-- | include/linux/cn_proc.h | 4 | ||||
-rw-r--r-- | include/uapi/linux/cn_proc.h | 10 | ||||
-rw-r--r-- | kernel/signal.c | 2 |
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 | ||
235 | void 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 | |||
235 | void proc_exit_connector(struct task_struct *task) | 260 | void 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); | |||
26 | void proc_sid_connector(struct task_struct *task); | 26 | void proc_sid_connector(struct task_struct *task); |
27 | void proc_ptrace_connector(struct task_struct *task, int which_id); | 27 | void proc_ptrace_connector(struct task_struct *task, int which_id); |
28 | void proc_comm_connector(struct task_struct *task); | 28 | void proc_comm_connector(struct task_struct *task); |
29 | void proc_coredump_connector(struct task_struct *task); | ||
29 | void proc_exit_connector(struct task_struct *task); | 30 | void proc_exit_connector(struct task_struct *task); |
30 | #else | 31 | #else |
31 | static inline void proc_fork_connector(struct task_struct *task) | 32 | static 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 | ||
52 | static inline void proc_coredump_connector(struct task_struct *task) | ||
53 | {} | ||
54 | |||
51 | static inline void proc_exit_connector(struct task_struct *task) | 55 | static 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 |