aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/connector
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/connector')
-rw-r--r--drivers/connector/cn_proc.c147
-rw-r--r--drivers/connector/connector.c7
2 files changed, 26 insertions, 128 deletions
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 094a710..2b46a7e 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -28,26 +28,12 @@
#include <linux/init.h>
#include <linux/connector.h>
#include <linux/gfp.h>
-#include <linux/ptrace.h>
-#include <linux/atomic.h>
+#include <asm/atomic.h>
+#include <asm/unaligned.h>
#include <linux/cn_proc.h>
-/*
- * Size of a cn_msg followed by a proc_event structure. Since the
- * sizeof struct cn_msg is a multiple of 4 bytes, but not 8 bytes, we
- * add one 4-byte word to the size here, and then start the actual
- * cn_msg structure 4 bytes into the stack buffer. The result is that
- * the immediately following proc_event structure is aligned to 8 bytes.
- */
-#define CN_PROC_MSG_SIZE (sizeof(struct cn_msg) + sizeof(struct proc_event) + 4)
-
-/* See comment above; we test our assumption about sizeof struct cn_msg here. */
-static inline struct cn_msg *buffer_to_cn_msg(__u8 *buffer)
-{
- BUILD_BUG_ON(sizeof(struct cn_msg) != 20);
- return (struct cn_msg *)(buffer + 4);
-}
+#define CN_PROC_MSG_SIZE (sizeof(struct cn_msg) + sizeof(struct proc_event))
static atomic_t proc_event_num_listeners = ATOMIC_INIT(0);
static struct cb_id cn_proc_event_id = { CN_IDX_PROC, CN_VAL_PROC };
@@ -67,32 +53,26 @@ void proc_fork_connector(struct task_struct *task)
{
struct cn_msg *msg;
struct proc_event *ev;
- __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
+ __u8 buffer[CN_PROC_MSG_SIZE];
struct timespec ts;
- struct task_struct *parent;
if (atomic_read(&proc_event_num_listeners) < 1)
return;
- msg = buffer_to_cn_msg(buffer);
+ msg = (struct cn_msg*)buffer;
ev = (struct proc_event*)msg->data;
- memset(&ev->event_data, 0, sizeof(ev->event_data));
get_seq(&msg->seq, &ev->cpu);
ktime_get_ts(&ts); /* get high res monotonic timestamp */
- ev->timestamp_ns = timespec_to_ns(&ts);
+ put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
ev->what = PROC_EVENT_FORK;
- rcu_read_lock();
- parent = rcu_dereference(task->real_parent);
- ev->event_data.fork.parent_pid = parent->pid;
- ev->event_data.fork.parent_tgid = parent->tgid;
- rcu_read_unlock();
+ ev->event_data.fork.parent_pid = task->real_parent->pid;
+ ev->event_data.fork.parent_tgid = task->real_parent->tgid;
ev->event_data.fork.child_pid = task->pid;
ev->event_data.fork.child_tgid = task->tgid;
memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
msg->ack = 0; /* not used */
msg->len = sizeof(*ev);
- msg->flags = 0; /* not used */
/* If cn_netlink_send() failed, the data is not sent */
cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
}
@@ -102,17 +82,16 @@ void proc_exec_connector(struct task_struct *task)
struct cn_msg *msg;
struct proc_event *ev;
struct timespec ts;
- __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
+ __u8 buffer[CN_PROC_MSG_SIZE];
if (atomic_read(&proc_event_num_listeners) < 1)
return;
- msg = buffer_to_cn_msg(buffer);
+ msg = (struct cn_msg*)buffer;
ev = (struct proc_event*)msg->data;
- memset(&ev->event_data, 0, sizeof(ev->event_data));
get_seq(&msg->seq, &ev->cpu);
ktime_get_ts(&ts); /* get high res monotonic timestamp */
- ev->timestamp_ns = timespec_to_ns(&ts);
+ put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
ev->what = PROC_EVENT_EXEC;
ev->event_data.exec.process_pid = task->pid;
ev->event_data.exec.process_tgid = task->tgid;
@@ -120,7 +99,6 @@ void proc_exec_connector(struct task_struct *task)
memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
msg->ack = 0; /* not used */
msg->len = sizeof(*ev);
- msg->flags = 0; /* not used */
cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
}
@@ -128,16 +106,15 @@ void proc_id_connector(struct task_struct *task, int which_id)
{
struct cn_msg *msg;
struct proc_event *ev;
- __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
+ __u8 buffer[CN_PROC_MSG_SIZE];
struct timespec ts;
const struct cred *cred;
if (atomic_read(&proc_event_num_listeners) < 1)
return;
- msg = buffer_to_cn_msg(buffer);
+ msg = (struct cn_msg*)buffer;
ev = (struct proc_event*)msg->data;
- memset(&ev->event_data, 0, sizeof(ev->event_data));
ev->what = which_id;
ev->event_data.id.process_pid = task->pid;
ev->event_data.id.process_tgid = task->tgid;
@@ -156,12 +133,11 @@ void proc_id_connector(struct task_struct *task, int which_id)
rcu_read_unlock();
get_seq(&msg->seq, &ev->cpu);
ktime_get_ts(&ts); /* get high res monotonic timestamp */
- ev->timestamp_ns = timespec_to_ns(&ts);
+ put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
msg->ack = 0; /* not used */
msg->len = sizeof(*ev);
- msg->flags = 0; /* not used */
cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
}
@@ -170,17 +146,16 @@ void proc_sid_connector(struct task_struct *task)
struct cn_msg *msg;
struct proc_event *ev;
struct timespec ts;
- __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
+ __u8 buffer[CN_PROC_MSG_SIZE];
if (atomic_read(&proc_event_num_listeners) < 1)
return;
- msg = buffer_to_cn_msg(buffer);
+ msg = (struct cn_msg *)buffer;
ev = (struct proc_event *)msg->data;
- memset(&ev->event_data, 0, sizeof(ev->event_data));
get_seq(&msg->seq, &ev->cpu);
ktime_get_ts(&ts); /* get high res monotonic timestamp */
- ev->timestamp_ns = timespec_to_ns(&ts);
+ put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
ev->what = PROC_EVENT_SID;
ev->event_data.sid.process_pid = task->pid;
ev->event_data.sid.process_tgid = task->tgid;
@@ -188,70 +163,6 @@ void proc_sid_connector(struct task_struct *task)
memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
msg->ack = 0; /* not used */
msg->len = sizeof(*ev);
- msg->flags = 0; /* not used */
- cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
-}
-
-void proc_ptrace_connector(struct task_struct *task, int ptrace_id)
-{
- struct cn_msg *msg;
- struct proc_event *ev;
- struct timespec ts;
- __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
-
- if (atomic_read(&proc_event_num_listeners) < 1)
- return;
-
- msg = buffer_to_cn_msg(buffer);
- ev = (struct proc_event *)msg->data;
- memset(&ev->event_data, 0, sizeof(ev->event_data));
- get_seq(&msg->seq, &ev->cpu);
- ktime_get_ts(&ts); /* get high res monotonic timestamp */
- ev->timestamp_ns = timespec_to_ns(&ts);
- ev->what = PROC_EVENT_PTRACE;
- ev->event_data.ptrace.process_pid = task->pid;
- ev->event_data.ptrace.process_tgid = task->tgid;
- if (ptrace_id == PTRACE_ATTACH) {
- ev->event_data.ptrace.tracer_pid = current->pid;
- ev->event_data.ptrace.tracer_tgid = current->tgid;
- } else if (ptrace_id == PTRACE_DETACH) {
- ev->event_data.ptrace.tracer_pid = 0;
- ev->event_data.ptrace.tracer_tgid = 0;
- } else
- return;
-
- memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
- msg->ack = 0; /* not used */
- msg->len = sizeof(*ev);
- msg->flags = 0; /* not used */
- cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
-}
-
-void proc_comm_connector(struct task_struct *task)
-{
- struct cn_msg *msg;
- struct proc_event *ev;
- struct timespec ts;
- __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
-
- if (atomic_read(&proc_event_num_listeners) < 1)
- return;
-
- msg = buffer_to_cn_msg(buffer);
- ev = (struct proc_event *)msg->data;
- memset(&ev->event_data, 0, sizeof(ev->event_data));
- get_seq(&msg->seq, &ev->cpu);
- ktime_get_ts(&ts); /* get high res monotonic timestamp */
- ev->timestamp_ns = timespec_to_ns(&ts);
- ev->what = PROC_EVENT_COMM;
- ev->event_data.comm.process_pid = task->pid;
- ev->event_data.comm.process_tgid = task->tgid;
- get_task_comm(ev->event_data.comm.comm, task);
-
- memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
- msg->ack = 0; /* not used */
- msg->len = sizeof(*ev);
- msg->flags = 0; /* not used */
cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
}
@@ -259,18 +170,17 @@ void proc_exit_connector(struct task_struct *task)
{
struct cn_msg *msg;
struct proc_event *ev;
- __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
+ __u8 buffer[CN_PROC_MSG_SIZE];
struct timespec ts;
if (atomic_read(&proc_event_num_listeners) < 1)
return;
- msg = buffer_to_cn_msg(buffer);
+ msg = (struct cn_msg*)buffer;
ev = (struct proc_event*)msg->data;
- memset(&ev->event_data, 0, sizeof(ev->event_data));
get_seq(&msg->seq, &ev->cpu);
ktime_get_ts(&ts); /* get high res monotonic timestamp */
- ev->timestamp_ns = timespec_to_ns(&ts);
+ put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
ev->what = PROC_EVENT_EXIT;
ev->event_data.exit.process_pid = task->pid;
ev->event_data.exit.process_tgid = task->tgid;
@@ -280,7 +190,6 @@ void proc_exit_connector(struct task_struct *task)
memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
msg->ack = 0; /* not used */
msg->len = sizeof(*ev);
- msg->flags = 0; /* not used */
cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
}
@@ -296,25 +205,23 @@ static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack)
{
struct cn_msg *msg;
struct proc_event *ev;
- __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
+ __u8 buffer[CN_PROC_MSG_SIZE];
struct timespec ts;
if (atomic_read(&proc_event_num_listeners) < 1)
return;
- msg = buffer_to_cn_msg(buffer);
+ msg = (struct cn_msg*)buffer;
ev = (struct proc_event*)msg->data;
- memset(&ev->event_data, 0, sizeof(ev->event_data));
msg->seq = rcvd_seq;
ktime_get_ts(&ts); /* get high res monotonic timestamp */
- ev->timestamp_ns = timespec_to_ns(&ts);
+ put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
ev->cpu = -1;
ev->what = PROC_EVENT_NONE;
ev->event_data.ack.err = err;
memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
msg->ack = rcvd_ack + 1;
msg->len = sizeof(*ev);
- msg->flags = 0; /* not used */
cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
}
@@ -331,12 +238,6 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg,
if (msg->len != sizeof(*mc_op))
return;
- /* Can only change if privileged. */
- if (!capable(CAP_NET_ADMIN)) {
- err = EPERM;
- goto out;
- }
-
mc_op = (enum proc_cn_mcast_op*)msg->data;
switch (*mc_op) {
case PROC_CN_MCAST_LISTEN:
@@ -349,8 +250,6 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg,
err = EINVAL;
break;
}
-
-out:
cn_proc_ack(err, msg->seq, msg->ack);
}
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index ea6efe8..dde6a0f 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -157,18 +157,17 @@ static int cn_call_callback(struct sk_buff *skb)
static void cn_rx_skb(struct sk_buff *__skb)
{
struct nlmsghdr *nlh;
+ int err;
struct sk_buff *skb;
- int len, err;
skb = skb_get(__skb);
if (skb->len >= NLMSG_SPACE(0)) {
nlh = nlmsg_hdr(skb);
- len = nlmsg_len(nlh);
- if (len < (int)sizeof(struct cn_msg) ||
+ if (nlh->nlmsg_len < sizeof(struct cn_msg) ||
skb->len < nlh->nlmsg_len ||
- len > CONNECTOR_MAX_MSG_SIZE) {
+ nlh->nlmsg_len > CONNECTOR_MAX_MSG_SIZE) {
kfree_skb(skb);
return;
}