aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/connector
diff options
context:
space:
mode:
authorVladimir Zapolskiy <vzapolskiy@gmail.com>2011-07-15 13:45:18 -0400
committerOleg Nesterov <oleg@redhat.com>2011-07-18 15:38:33 -0400
commitf701e5b73a1a79ea62ffd45d9e2bed4c7d5c1fd2 (patch)
tree10940ea680a1c8c69cbd9f9aa9aca23a1199aa0e /drivers/connector
parentd184d6eb1dc3c9869e25a8e422be5c55ab0db4ac (diff)
connector: add an event for monitoring process tracers
This change adds a procfs connector event, which is emitted on every successful process tracer attach or detach. If some process connects to other one, kernelspace connector reports process id and thread group id of both these involved processes. On disconnection null process id is returned. Such an event allows to create a simple automated userspace mechanism to be aware about processes connecting to others, therefore predefined process policies can be applied to them if needed. Note, a detach signal is emitted only in case, if a tracer process explicitly executes PTRACE_DETACH request. In other cases like tracee or tracer exit detach event from proc connector is not reported. Signed-off-by: Vladimir Zapolskiy <vzapolskiy@gmail.com> Acked-by: Evgeniy Polyakov <zbr@ioremap.net> Cc: David S. Miller <davem@davemloft.net> Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Diffstat (limited to 'drivers/connector')
-rw-r--r--drivers/connector/cn_proc.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 2b46a7efa0ac..281902d3f7ec 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -28,6 +28,7 @@
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/connector.h> 29#include <linux/connector.h>
30#include <linux/gfp.h> 30#include <linux/gfp.h>
31#include <linux/ptrace.h>
31#include <asm/atomic.h> 32#include <asm/atomic.h>
32#include <asm/unaligned.h> 33#include <asm/unaligned.h>
33 34
@@ -166,6 +167,40 @@ void proc_sid_connector(struct task_struct *task)
166 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); 167 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
167} 168}
168 169
170void proc_ptrace_connector(struct task_struct *task, int ptrace_id)
171{
172 struct cn_msg *msg;
173 struct proc_event *ev;
174 struct timespec ts;
175 __u8 buffer[CN_PROC_MSG_SIZE];
176 struct task_struct *tracer;
177
178 if (atomic_read(&proc_event_num_listeners) < 1)
179 return;
180
181 msg = (struct cn_msg *)buffer;
182 ev = (struct proc_event *)msg->data;
183 get_seq(&msg->seq, &ev->cpu);
184 ktime_get_ts(&ts); /* get high res monotonic timestamp */
185 put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
186 ev->what = PROC_EVENT_PTRACE;
187 ev->event_data.ptrace.process_pid = task->pid;
188 ev->event_data.ptrace.process_tgid = task->tgid;
189 if (ptrace_id == PTRACE_ATTACH) {
190 ev->event_data.ptrace.tracer_pid = current->pid;
191 ev->event_data.ptrace.tracer_tgid = current->tgid;
192 } else if (ptrace_id == PTRACE_DETACH) {
193 ev->event_data.ptrace.tracer_pid = 0;
194 ev->event_data.ptrace.tracer_tgid = 0;
195 } else
196 return;
197
198 memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
199 msg->ack = 0; /* not used */
200 msg->len = sizeof(*ev);
201 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
202}
203
169void proc_exit_connector(struct task_struct *task) 204void proc_exit_connector(struct task_struct *task)
170{ 205{
171 struct cn_msg *msg; 206 struct cn_msg *msg;