aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@plumgrid.com>2015-10-08 01:23:21 -0400
committerDavid S. Miller <davem@davemloft.net>2015-10-12 22:13:35 -0400
commit1be7f75d1668d6296b80bf35dcf6762393530afc (patch)
tree319fe845ed6fc5f5f1b30f17983418d77196f313 /net/core
parent0fa28877b26641cca56b607ccec1fcbda7ae09c6 (diff)
bpf: enable non-root eBPF programs
In order to let unprivileged users load and execute eBPF programs teach verifier to prevent pointer leaks. Verifier will prevent - any arithmetic on pointers (except R10+Imm which is used to compute stack addresses) - comparison of pointers (except if (map_value_ptr == 0) ... ) - passing pointers to helper functions - indirectly passing pointers in stack to helper functions - returning pointer from bpf program - storing pointers into ctx or maps Spill/fill of pointers into stack is allowed, but mangling of pointers stored in the stack or reading them byte by byte is not. Within bpf programs the pointers do exist, since programs need to be able to access maps, pass skb pointer to LD_ABS insns, etc but programs cannot pass such pointer values to the outside or obfuscate them. Only allow BPF_PROG_TYPE_SOCKET_FILTER unprivileged programs, so that socket filters (tcpdump), af_packet (quic acceleration) and future kcm can use it. tracing and tc cls/act program types still require root permissions, since tracing actually needs to be able to see all kernel pointers and tc is for root only. For example, the following unprivileged socket filter program is allowed: int bpf_prog1(struct __sk_buff *skb) { u32 index = load_byte(skb, ETH_HLEN + offsetof(struct iphdr, protocol)); u64 *value = bpf_map_lookup_elem(&my_map, &index); if (value) *value += skb->len; return 0; } but the following program is not: int bpf_prog1(struct __sk_buff *skb) { u32 index = load_byte(skb, ETH_HLEN + offsetof(struct iphdr, protocol)); u64 *value = bpf_map_lookup_elem(&my_map, &index); if (value) *value += (u64) skb; return 0; } since it would leak the kernel address into the map. Unprivileged socket filter bpf programs have access to the following helper functions: - map lookup/update/delete (but they cannot store kernel pointers into them) - get_random (it's already exposed to unprivileged user space) - get_smp_processor_id - tail_call into another socket filter program - ktime_get_ns The feature is controlled by sysctl kernel.unprivileged_bpf_disabled. This toggle defaults to off (0), but can be set true (1). Once true, bpf programs and maps cannot be accessed from unprivileged process, and the toggle cannot be set back to false. Signed-off-by: Alexei Starovoitov <ast@plumgrid.com> Reviewed-by: Kees Cook <keescook@chromium.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/filter.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/net/core/filter.c b/net/core/filter.c
index 5f4cf1cffed3..0b00094932ab 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -1640,7 +1640,8 @@ sk_filter_func_proto(enum bpf_func_id func_id)
1640 case BPF_FUNC_ktime_get_ns: 1640 case BPF_FUNC_ktime_get_ns:
1641 return &bpf_ktime_get_ns_proto; 1641 return &bpf_ktime_get_ns_proto;
1642 case BPF_FUNC_trace_printk: 1642 case BPF_FUNC_trace_printk:
1643 return bpf_get_trace_printk_proto(); 1643 if (capable(CAP_SYS_ADMIN))
1644 return bpf_get_trace_printk_proto();
1644 default: 1645 default:
1645 return NULL; 1646 return NULL;
1646 } 1647 }