From patchwork Sun May 24 16:50:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Fastabend X-Patchwork-Id: 218613 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.6 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9645FC433DF for ; Sun, 24 May 2020 16:51:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6EC222073B for ; Sun, 24 May 2020 16:51:12 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="uWRILoHS" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387682AbgEXQvL (ORCPT ); Sun, 24 May 2020 12:51:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41694 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728375AbgEXQvL (ORCPT ); Sun, 24 May 2020 12:51:11 -0400 Received: from mail-pj1-x1044.google.com (mail-pj1-x1044.google.com [IPv6:2607:f8b0:4864:20::1044]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1C5E7C061A0E; Sun, 24 May 2020 09:51:10 -0700 (PDT) Received: by mail-pj1-x1044.google.com with SMTP id s69so7563296pjb.4; Sun, 24 May 2020 09:51:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:from:to:cc:date:message-id:in-reply-to:references :user-agent:mime-version:content-transfer-encoding; bh=6SKBe6xQJXBNFACnU6xjW3B0HnZH7Fada6vWqTlhWS4=; b=uWRILoHSTUjptzPYr/bMScb2eycrw1HplGZOhrl4v/0v8VjolR1vo8lVdTFj/9ga2G VnQmrmdM2p2AN9A0P8WseshA9KzeYfnmkQOqa3EOS28snhRshtGV/GcDqnkSIVMB5lK4 APss7NVTOi+mbWSU+VtLPHhl1Kc7XDN3/eMYhHgLvnJp2fjhcSynB/3RwKDtL46I0pRu +a+O6P4O2z9e2Xx2JFXrwXDW0lFtIfO0ZbhXGaDKZ4iHKJG4uI87KK9S1jHR6dEt5nvS bzIsjR4TW7A4JMXdCnkz0OKjaHTSiAigGVj3X/fzhtOBvv1MucG9WusyNukVwAV7T+QN 2SXA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:date:message-id:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=6SKBe6xQJXBNFACnU6xjW3B0HnZH7Fada6vWqTlhWS4=; b=Mp+1BUnF/kq/S0p0k5kslXUuWOtAdCizS61rpvoqF0ZmuX6idjfwGdkjGOPZ6NV2z0 QPLZnw2qMq332b45lfCvdwAo3m3Lov1pNEOqbEQrhoup1Mt7Lq2XfcM02Nqi69a9IKBf YGNdcZtffHUP1MFO9Er2WJp753WjtwXTLnX/WxsYbJZ1R2MLhfvxaESoxmqjtT8hQGY5 +L08ZT8XqfRfZvy+IR4EIFNZoEG/ZviPP58mC0PvPKxkF5bufPJLScgvPl/H78FnYShq 58zpx2I2ExbKBJ38CuZFrWwAgDnO72VWzbNB/Hn9uGpDNtK7ojPlvFgLnk0gBEvjUtUf xJqA== X-Gm-Message-State: AOAM533E/cxXVdslx7JbT7ymRXnudHNhAWlcg4JdvpFDASEagZG2vbWU yuFFa3Qth0/t1ioNp0HNzxM= X-Google-Smtp-Source: ABdhPJxb9NsIphjiXioSr3YjOz/11c2E54lvrwvOSZHJS6UKTMkYYPKi/AZGR5d2RV2kMa8ZgVOuqw== X-Received: by 2002:a17:902:fe06:: with SMTP id g6mr23666938plj.118.1590339069680; Sun, 24 May 2020 09:51:09 -0700 (PDT) Received: from [127.0.1.1] ([184.63.162.180]) by smtp.gmail.com with ESMTPSA id p190sm11275070pfp.207.2020.05.24.09.51.01 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sun, 24 May 2020 09:51:09 -0700 (PDT) Subject: [bpf-next PATCH v5 2/5] bpf: extend bpf_base_func_proto helpers with probe_* and *current_task* From: John Fastabend To: yhs@fb.com, andrii.nakryiko@gmail.com, ast@kernel.org, daniel@iogearbox.net Cc: netdev@vger.kernel.org, bpf@vger.kernel.org, john.fastabend@gmail.com Date: Sun, 24 May 2020 09:50:55 -0700 Message-ID: <159033905529.12355.4368381069655254932.stgit@john-Precision-5820-Tower> In-Reply-To: <159033879471.12355.1236562159278890735.stgit@john-Precision-5820-Tower> References: <159033879471.12355.1236562159278890735.stgit@john-Precision-5820-Tower> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Often it is useful when applying policy to know something about the task. If the administrator has CAP_SYS_ADMIN rights then they can use kprobe + networking hook and link the two programs together to accomplish this. However, this is a bit clunky and also means we have to call both the network program and kprobe program when we could just use a single program and avoid passing metadata through sk_msg/skb->cb, socket, maps, etc. To accomplish this add probe_* helpers to bpf_base_func_proto programs guarded by a perfmon_capable() check. New supported helpers are the following, BPF_FUNC_get_current_task BPF_FUNC_current_task_under_cgroup BPF_FUNC_probe_read_user BPF_FUNC_probe_read_kernel BPF_FUNC_probe_read_user_str BPF_FUNC_probe_read_kernel_str Signed-off-by: John Fastabend Acked-by: Yonghong Song --- kernel/bpf/helpers.c | 24 ++++++++++++++++++++++++ kernel/trace/bpf_trace.c | 10 +++++----- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index 886949f..bb4fb63 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -601,6 +601,12 @@ const struct bpf_func_proto bpf_event_output_data_proto = { .arg5_type = ARG_CONST_SIZE_OR_ZERO, }; +const struct bpf_func_proto bpf_get_current_task_proto __weak; +const struct bpf_func_proto bpf_probe_read_user_proto __weak; +const struct bpf_func_proto bpf_probe_read_user_str_proto __weak; +const struct bpf_func_proto bpf_probe_read_kernel_proto __weak; +const struct bpf_func_proto bpf_probe_read_kernel_str_proto __weak; + const struct bpf_func_proto * bpf_base_func_proto(enum bpf_func_id func_id) { @@ -648,6 +654,24 @@ bpf_base_func_proto(enum bpf_func_id func_id) case BPF_FUNC_jiffies64: return &bpf_jiffies64_proto; default: + break; + } + + if (!perfmon_capable()) + return NULL; + + switch (func_id) { + case BPF_FUNC_get_current_task: + return &bpf_get_current_task_proto; + case BPF_FUNC_probe_read_user: + return &bpf_probe_read_user_proto; + case BPF_FUNC_probe_read_kernel: + return &bpf_probe_read_kernel_proto; + case BPF_FUNC_probe_read_user_str: + return &bpf_probe_read_user_str_proto; + case BPF_FUNC_probe_read_kernel_str: + return &bpf_probe_read_kernel_str_proto; + default: return NULL; } } diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 9531f54..187cd69 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -147,7 +147,7 @@ BPF_CALL_3(bpf_probe_read_user, void *, dst, u32, size, return ret; } -static const struct bpf_func_proto bpf_probe_read_user_proto = { +const struct bpf_func_proto bpf_probe_read_user_proto = { .func = bpf_probe_read_user, .gpl_only = true, .ret_type = RET_INTEGER, @@ -167,7 +167,7 @@ BPF_CALL_3(bpf_probe_read_user_str, void *, dst, u32, size, return ret; } -static const struct bpf_func_proto bpf_probe_read_user_str_proto = { +const struct bpf_func_proto bpf_probe_read_user_str_proto = { .func = bpf_probe_read_user_str, .gpl_only = true, .ret_type = RET_INTEGER, @@ -198,7 +198,7 @@ BPF_CALL_3(bpf_probe_read_kernel, void *, dst, u32, size, return bpf_probe_read_kernel_common(dst, size, unsafe_ptr, false); } -static const struct bpf_func_proto bpf_probe_read_kernel_proto = { +const struct bpf_func_proto bpf_probe_read_kernel_proto = { .func = bpf_probe_read_kernel, .gpl_only = true, .ret_type = RET_INTEGER, @@ -253,7 +253,7 @@ BPF_CALL_3(bpf_probe_read_kernel_str, void *, dst, u32, size, return bpf_probe_read_kernel_str_common(dst, size, unsafe_ptr, false); } -static const struct bpf_func_proto bpf_probe_read_kernel_str_proto = { +const struct bpf_func_proto bpf_probe_read_kernel_str_proto = { .func = bpf_probe_read_kernel_str, .gpl_only = true, .ret_type = RET_INTEGER, @@ -907,7 +907,7 @@ BPF_CALL_0(bpf_get_current_task) return (long) current; } -static const struct bpf_func_proto bpf_get_current_task_proto = { +const struct bpf_func_proto bpf_get_current_task_proto = { .func = bpf_get_current_task, .gpl_only = true, .ret_type = RET_INTEGER, From patchwork Sun May 24 16:51:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Fastabend X-Patchwork-Id: 218612 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.6 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3524AC433DF for ; Sun, 24 May 2020 16:51:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0ECC22073B for ; Sun, 24 May 2020 16:51:52 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="vVlkubaD" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387784AbgEXQvv (ORCPT ); Sun, 24 May 2020 12:51:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41802 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387726AbgEXQvv (ORCPT ); Sun, 24 May 2020 12:51:51 -0400 Received: from mail-pf1-x443.google.com (mail-pf1-x443.google.com [IPv6:2607:f8b0:4864:20::443]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 31C5FC061A0E; Sun, 24 May 2020 09:51:51 -0700 (PDT) Received: by mail-pf1-x443.google.com with SMTP id z64so3325557pfb.1; Sun, 24 May 2020 09:51:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:from:to:cc:date:message-id:in-reply-to:references :user-agent:mime-version:content-transfer-encoding; bh=P1MJ05uFAxDfNHMQqVnK1prcFqS5udLDYsJyc1jGlFg=; b=vVlkubaD3lePujFNIPeSe5q1u1In6QoLx1X5AMofE5Cgn3VlyGktPR9LOHVb3qahwQ RhrbPuJsY5qQjiborwMYWLWU2v4/WuXw6SjMc1yQQFNh+LV0nIEB1bRTB1+tjqNCMjYK 1yHjlQXj4+/5msrn0ctyMs37CVhSIlHJbuY7VbRIMlwvoaV3JX3+5jkN32s1AjfP03f1 B7bWTeSBpXD+LytEmcuGZAiAl2zy/vSronmk/L1qu5JXOKAJ0sQdCVkTtkYKdCMr3fh+ LpvdQ975Ph6yW9D2EJuk3mNcsnNABq41YHSTn8ZJev0UO3fyYbzMKAYfIIw/RrMZGQT6 ghVw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:date:message-id:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=P1MJ05uFAxDfNHMQqVnK1prcFqS5udLDYsJyc1jGlFg=; b=l5AweIgMxGsw9vBJULtHPRMRapGwI3LlLoQbFoioPYGtycO4rYBLKfRnKZdOFXsaBG HTbHqABkEta+sBUXvvIwW6TKIJq+XM7zuIzoxCJVFPvs/l6pfBCKUnQQxoK/7R8T002l eCi3F9KUoYSflH1Ws1CEsFCbA/xEY8wykP4sB/xWSBiIyUcrbgqqh40VyL3ufJlgJR2F AJDELrA2mp7JQ+hq+ku2TBhNNA7qQP8qRPsPZIb4hG2FDIktfY3IjZgrqOdNIJicF7Z4 cSioXky5Z8Y6LqqZJqSauFrTGsrpZVuvSiAhoQDKEF9t9Z0eITCDCXBR2T4rd5X1wyUM fjgA== X-Gm-Message-State: AOAM5311beux7lc4AesG6gKB1QAQVnEiy1omZ30Rt3IvIlUFgOdZ0pUQ MZyGwGSqFGnH0x90Nxcu1Wk= X-Google-Smtp-Source: ABdhPJyJ3n/qmbE1lmwe5QSBAwRG3ksaEMA0M+az/TuMIeiWzgNO3NmU167keHrdNrtKSdSMUsvKIw== X-Received: by 2002:a62:ed02:: with SMTP id u2mr13717713pfh.60.1590339110757; Sun, 24 May 2020 09:51:50 -0700 (PDT) Received: from [127.0.1.1] ([184.63.162.180]) by smtp.gmail.com with ESMTPSA id l23sm10261865pgc.55.2020.05.24.09.51.42 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sun, 24 May 2020 09:51:50 -0700 (PDT) Subject: [bpf-next PATCH v5 4/5] bpf, selftests: add sk_msg helpers load and attach test From: John Fastabend To: yhs@fb.com, andrii.nakryiko@gmail.com, ast@kernel.org, daniel@iogearbox.net Cc: netdev@vger.kernel.org, bpf@vger.kernel.org, john.fastabend@gmail.com Date: Sun, 24 May 2020 09:51:36 -0700 Message-ID: <159033909665.12355.6166415847337547879.stgit@john-Precision-5820-Tower> In-Reply-To: <159033879471.12355.1236562159278890735.stgit@john-Precision-5820-Tower> References: <159033879471.12355.1236562159278890735.stgit@john-Precision-5820-Tower> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The test itself is not particularly useful but it encodes a common pattern we have. Namely do a sk storage lookup then depending on data here decide if we need to do more work or alternatively allow packet to PASS. Then if we need to do more work consult task_struct for more information about the running task. Finally based on this additional information drop or pass the data. In this case the suspicious check is not so realisitic but it encodes the general pattern and uses the helpers so we test the workflow. This is a load test to ensure verifier correctly handles this case. Signed-off-by: John Fastabend --- .../selftests/bpf/prog_tests/sockmap_basic.c | 35 +++++++++++++++ .../selftests/bpf/progs/test_skmsg_load_helpers.c | 47 ++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 tools/testing/selftests/bpf/progs/test_skmsg_load_helpers.c diff --git a/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c b/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c index aa43e0b..96e7b7f 100644 --- a/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c +++ b/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c @@ -1,7 +1,9 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (c) 2020 Cloudflare +#include #include "test_progs.h" +#include "test_skmsg_load_helpers.skel.h" #define TCP_REPAIR 19 /* TCP sock is under repair right now */ @@ -70,10 +72,43 @@ static void test_sockmap_create_update_free(enum bpf_map_type map_type) close(s); } +static void test_skmsg_helpers(enum bpf_map_type map_type) +{ + struct test_skmsg_load_helpers *skel; + int err, map, verdict; + + skel = test_skmsg_load_helpers__open_and_load(); + if (CHECK_FAIL(!skel)) { + perror("test_skmsg_load_helpers__open_and_load"); + return; + } + + verdict = bpf_program__fd(skel->progs.prog_msg_verdict); + map = bpf_map__fd(skel->maps.sock_map); + + err = bpf_prog_attach(verdict, map, BPF_SK_MSG_VERDICT, 0); + if (CHECK_FAIL(err)) { + perror("bpf_prog_attach"); + goto out; + } + + err = bpf_prog_detach2(verdict, map, BPF_SK_MSG_VERDICT); + if (CHECK_FAIL(err)) { + perror("bpf_prog_detach2"); + goto out; + } +out: + test_skmsg_load_helpers__destroy(skel); +} + void test_sockmap_basic(void) { if (test__start_subtest("sockmap create_update_free")) test_sockmap_create_update_free(BPF_MAP_TYPE_SOCKMAP); if (test__start_subtest("sockhash create_update_free")) test_sockmap_create_update_free(BPF_MAP_TYPE_SOCKHASH); + if (test__start_subtest("sockmap sk_msg load helpers")) + test_skmsg_helpers(BPF_MAP_TYPE_SOCKMAP); + if (test__start_subtest("sockhash sk_msg load helpers")) + test_skmsg_helpers(BPF_MAP_TYPE_SOCKHASH); } diff --git a/tools/testing/selftests/bpf/progs/test_skmsg_load_helpers.c b/tools/testing/selftests/bpf/progs/test_skmsg_load_helpers.c new file mode 100644 index 0000000..45e8fc7 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_skmsg_load_helpers.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2020 Isovalent, Inc. +#include "vmlinux.h" +#include + +struct { + __uint(type, BPF_MAP_TYPE_SOCKMAP); + __uint(max_entries, 2); + __type(key, __u32); + __type(value, __u64); +} sock_map SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_SOCKHASH); + __uint(max_entries, 2); + __type(key, __u32); + __type(value, __u64); +} sock_hash SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_SK_STORAGE); + __uint(map_flags, BPF_F_NO_PREALLOC); + __type(key, __u32); + __type(value, __u64); +} socket_storage SEC(".maps"); + +SEC("sk_msg") +int prog_msg_verdict(struct sk_msg_md *msg) +{ + struct task_struct *task = (struct task_struct *)bpf_get_current_task(); + int verdict = SK_PASS; + __u32 pid, tpid; + __u64 *sk_stg; + + pid = bpf_get_current_pid_tgid() >> 32; + sk_stg = bpf_sk_storage_get(&socket_storage, msg->sk, 0, BPF_SK_STORAGE_GET_F_CREATE); + if (!sk_stg) + return SK_DROP; + *sk_stg = pid; + bpf_probe_read_kernel(&tpid , sizeof(tpid), &task->tgid); + if (pid != tpid) + verdict = SK_DROP; + bpf_sk_storage_delete(&socket_storage, (void *)msg->sk); + return verdict; +} + +char _license[] SEC("license") = "GPL";