summaryrefslogtreecommitdiffstats
path: root/kernel/bpf
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@plumgrid.com>2015-06-12 22:39:12 -0400
committerDavid S. Miller <davem@davemloft.net>2015-06-15 18:53:50 -0400
commitffeedafbf0236f03aeb2e8db273b3e5ae5f5bc89 (patch)
treee00f1b0bba1c217afbcf4dda00ef950afdfcafbc /kernel/bpf
parentada6c1de9ecabcfc5619479bcd29a208f2e248a0 (diff)
bpf: introduce current->pid, tgid, uid, gid, comm accessors
eBPF programs attached to kprobes need to filter based on current->pid, uid and other fields, so introduce helper functions: u64 bpf_get_current_pid_tgid(void) Return: current->tgid << 32 | current->pid u64 bpf_get_current_uid_gid(void) Return: current_gid << 32 | current_uid bpf_get_current_comm(char *buf, int size_of_buf) stores current->comm into buf They can be used from the programs attached to TC as well to classify packets based on current task fields. Update tracex2 example to print histogram of write syscalls for each process instead of aggregated for all. Signed-off-by: Alexei Starovoitov <ast@plumgrid.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'kernel/bpf')
-rw-r--r--kernel/bpf/core.c3
-rw-r--r--kernel/bpf/helpers.c58
2 files changed, 61 insertions, 0 deletions
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 1e00aa3316dc..1fc45cc83076 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -730,6 +730,9 @@ const struct bpf_func_proto bpf_map_delete_elem_proto __weak;
730const struct bpf_func_proto bpf_get_prandom_u32_proto __weak; 730const struct bpf_func_proto bpf_get_prandom_u32_proto __weak;
731const struct bpf_func_proto bpf_get_smp_processor_id_proto __weak; 731const struct bpf_func_proto bpf_get_smp_processor_id_proto __weak;
732const struct bpf_func_proto bpf_ktime_get_ns_proto __weak; 732const struct bpf_func_proto bpf_ktime_get_ns_proto __weak;
733const struct bpf_func_proto bpf_get_current_pid_tgid_proto __weak;
734const struct bpf_func_proto bpf_get_current_uid_gid_proto __weak;
735const struct bpf_func_proto bpf_get_current_comm_proto __weak;
733 736
734/* Always built-in helper functions. */ 737/* Always built-in helper functions. */
735const struct bpf_func_proto bpf_tail_call_proto = { 738const struct bpf_func_proto bpf_tail_call_proto = {
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index 7ad5d8842d5b..1447ec09421e 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -14,6 +14,8 @@
14#include <linux/random.h> 14#include <linux/random.h>
15#include <linux/smp.h> 15#include <linux/smp.h>
16#include <linux/ktime.h> 16#include <linux/ktime.h>
17#include <linux/sched.h>
18#include <linux/uidgid.h>
17 19
18/* If kernel subsystem is allowing eBPF programs to call this function, 20/* If kernel subsystem is allowing eBPF programs to call this function,
19 * inside its own verifier_ops->get_func_proto() callback it should return 21 * inside its own verifier_ops->get_func_proto() callback it should return
@@ -124,3 +126,59 @@ const struct bpf_func_proto bpf_ktime_get_ns_proto = {
124 .gpl_only = true, 126 .gpl_only = true,
125 .ret_type = RET_INTEGER, 127 .ret_type = RET_INTEGER,
126}; 128};
129
130static u64 bpf_get_current_pid_tgid(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)
131{
132 struct task_struct *task = current;
133
134 if (!task)
135 return -EINVAL;
136
137 return (u64) task->tgid << 32 | task->pid;
138}
139
140const struct bpf_func_proto bpf_get_current_pid_tgid_proto = {
141 .func = bpf_get_current_pid_tgid,
142 .gpl_only = false,
143 .ret_type = RET_INTEGER,
144};
145
146static u64 bpf_get_current_uid_gid(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)
147{
148 struct task_struct *task = current;
149 kuid_t uid;
150 kgid_t gid;
151
152 if (!task)
153 return -EINVAL;
154
155 current_uid_gid(&uid, &gid);
156 return (u64) from_kgid(&init_user_ns, gid) << 32 |
157 from_kuid(&init_user_ns, uid);
158}
159
160const struct bpf_func_proto bpf_get_current_uid_gid_proto = {
161 .func = bpf_get_current_uid_gid,
162 .gpl_only = false,
163 .ret_type = RET_INTEGER,
164};
165
166static u64 bpf_get_current_comm(u64 r1, u64 size, u64 r3, u64 r4, u64 r5)
167{
168 struct task_struct *task = current;
169 char *buf = (char *) (long) r1;
170
171 if (!task)
172 return -EINVAL;
173
174 memcpy(buf, task->comm, min_t(size_t, size, sizeof(task->comm)));
175 return 0;
176}
177
178const struct bpf_func_proto bpf_get_current_comm_proto = {
179 .func = bpf_get_current_comm,
180 .gpl_only = false,
181 .ret_type = RET_INTEGER,
182 .arg1_type = ARG_PTR_TO_STACK,
183 .arg2_type = ARG_CONST_STACK_SIZE,
184};