From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752853AbcGMKhK (ORCPT ); Wed, 13 Jul 2016 06:37:10 -0400 Received: from mail-oi0-f42.google.com ([209.85.218.42]:35392 "EHLO mail-oi0-f42.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750854AbcGMKhD (ORCPT ); Wed, 13 Jul 2016 06:37:03 -0400 MIME-Version: 1.0 From: Sargun Dhillon Date: Wed, 13 Jul 2016 03:36:11 -0700 Message-ID: Subject: [PATCH 1/1] tracing, bpf: Implement function bpf_probe_write To: linux-kernel@vger.kernel.org Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Provides BPF programs, attached to kprobes a safe way to write to memory referenced by probes. This is done by making probe_kernel_write accessible to bpf functions via the bpf_probe_write helper. Signed-off-by: Sargun Dhillon --- include/uapi/linux/bpf.h | 3 +++ kernel/trace/bpf_trace.c | 20 ++++++++++++++++++++ samples/bpf/bpf_helpers.h | 2 ++ 3 files changed, 25 insertions(+) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 406459b..355b565 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -313,6 +313,9 @@ enum bpf_func_id { */ BPF_FUNC_skb_get_tunnel_opt, BPF_FUNC_skb_set_tunnel_opt, + + BPF_FUNC_probe_write, /* int bpf_probe_write(void *dst, void *src, int size) */ + __BPF_FUNC_MAX_ID, }; diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 26f603d..dc745d1 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -81,6 +81,24 @@ static const struct bpf_func_proto bpf_probe_read_proto = { .arg3_type = ARG_ANYTHING, }; +static u64 bpf_probe_write(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) +{ + void *dst = (void *) (long) r1; + void *unsafe_ptr = (void *) (long) r2; + int size = (int) r3; + + return probe_kernel_write(dst, unsafe_ptr, size); +} + +static const struct bpf_func_proto bpf_probe_write_proto = { + .func = bpf_probe_write, + .gpl_only = true, + .ret_type = RET_INTEGER, + .arg1_type = ARG_ANYTHING, + .arg2_type = ARG_PTR_TO_RAW_STACK, + .arg3_type = ARG_CONST_STACK_SIZE, +}; + /* * limited trace_printk() * only %d %u %x %ld %lu %lx %lld %llu %llx %p %s conversion specifiers allowed @@ -319,6 +337,8 @@ static const struct bpf_func_proto *tracing_func_proto(enum bpf_func_id func_id) return &bpf_map_delete_elem_proto; case BPF_FUNC_probe_read: return &bpf_probe_read_proto; + case BPF_FUNC_probe_write: + return &bpf_probe_write_proto; case BPF_FUNC_ktime_get_ns: return &bpf_ktime_get_ns_proto; case BPF_FUNC_tail_call: diff --git a/samples/bpf/bpf_helpers.h b/samples/bpf/bpf_helpers.h index 7904a2a..07b90ac 100644 --- a/samples/bpf/bpf_helpers.h +++ b/samples/bpf/bpf_helpers.h @@ -17,6 +17,8 @@ static int (*bpf_map_delete_elem)(void *map, void *key) = (void *) BPF_FUNC_map_delete_elem; static int (*bpf_probe_read)(void *dst, int size, void *unsafe_ptr) = (void *) BPF_FUNC_probe_read; +static int (*bpf_probe_write)(void *dst, void *unsafe_ptr, int size) = + (void *) BPF_FUNC_probe_write; static unsigned long long (*bpf_ktime_get_ns)(void) = (void *) BPF_FUNC_ktime_get_ns; static int (*bpf_trace_printk)(const char *fmt, int fmt_size, ...) = -- 2.7.4