From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 38D81C433FE for ; Thu, 7 Apr 2022 22:31:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232063AbiDGWdw (ORCPT ); Thu, 7 Apr 2022 18:33:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48326 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232094AbiDGWdo (ORCPT ); Thu, 7 Apr 2022 18:33:44 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2657B82332 for ; Thu, 7 Apr 2022 15:31:32 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id x10-20020a5b028a000000b0063f0cc26f1bso662185ybl.16 for ; Thu, 07 Apr 2022 15:31:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=zmR1o2tbqO1PCy5LYhOTyAaO3QgHPcHpKMd6y/ugnfU=; b=JITxNyBjXwlvw1dwqwCXqXs7ZWoLkqtfUZ0RTIDcqyr+RuZXH78QT9afl+NJPec0QP vmp6jPXWuue2ypLHx9+v3pudlKs0ecP438aAOoLwiCIpCaYl1Y0gddaGSGpB4m3PcWPc b237uVEtT6oW3Yz6dd6y1TvTwA0QegQ4wjttrQ8X8IW3U2E4YqciJRml/g0zvFa/54dy PUm1iKoRlVOMMXUuCZL3BluYiDt71fUCDmHza1rYHPSIFQ2nMuItyPz32VSeRcre05yq 4gWlkPRJGbfTNxq6NO+WR/gp/o6qc4ebAs96LRVnKTnBNsFVCLQF1xsuUihldP2qMJaM o62A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=zmR1o2tbqO1PCy5LYhOTyAaO3QgHPcHpKMd6y/ugnfU=; b=MnUAhzaChVXrxPdcb3IK0FxNUCnLHsTKJEJKGB/bZEH+i7pEHRls3jQoX7DkfhGQMt nl/UWV79tix4Xo+0q5pHcJDCieun3IQE6V97retYhT3x+knAMzgSYwtsryMAjyDUTH/L Y9iKqaV66qUWivddGebyeCTJ3NRN91ylwhwSQijfsUWGIa3gRkkQ0kG8anuU4kzPToBM Ozqylnc7SDTcs9zsu+1sP/mFzK4h29v/eq9nHY9FNQ9xQuIR3kWpc4O5rBQRl/wo43ks gzkZ23YDZSieZp+YW3BZGjWtUmE8n5o1Sp7pR95IjOkRAjnZpeq6EvjeGR+wFZFPxmU/ oc+Q== X-Gm-Message-State: AOAM530It7t6zRGBWYTZcUK5IWhYEXooULY10Xmv+D+APWGKIqa6ssZV UDvKlqRL/en2p5QFPe/g9fDj8tU33to1MslEZ6szmwAijLUKmDhn7BcboGFt5rp5EI6r8iC0821 JQOwmiV5Ihtz5bZEBnhQY/QjczUS9ueEe97ZZ7I0FD6tSOiDeC+G4qw== X-Google-Smtp-Source: ABdhPJwKo+iErGY7B4rVb3xP1RowmegMAvIknx/F9bhsooruBGkVEWWaSSiTh+WxUfLJ8SAh2FLO0Jo= X-Received: from sdf2.svl.corp.google.com ([2620:15c:2c4:201:9e25:5910:c207:e29a]) (user=sdf job=sendgmr) by 2002:a25:7e85:0:b0:63d:b3e4:884 with SMTP id z127-20020a257e85000000b0063db3e40884mr12033257ybc.311.1649370691838; Thu, 07 Apr 2022 15:31:31 -0700 (PDT) Date: Thu, 7 Apr 2022 15:31:12 -0700 In-Reply-To: <20220407223112.1204582-1-sdf@google.com> Message-Id: <20220407223112.1204582-8-sdf@google.com> Mime-Version: 1.0 References: <20220407223112.1204582-1-sdf@google.com> X-Mailer: git-send-email 2.35.1.1178.g4f1659d476-goog Subject: [PATCH bpf-next v3 7/7] selftests/bpf: verify lsm_cgroup struct sock access From: Stanislav Fomichev To: netdev@vger.kernel.org, bpf@vger.kernel.org Cc: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, Stanislav Fomichev Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org sk_priority & sk_mark are writable, the rest is readonly. Add new ldx_offset fixups to lookup the offset of struct field. Allow using test.kfunc regardless of prog_type. One interesting thing here is that the verifier doesn't really force me to add NULL checks anywhere :-/ Signed-off-by: Stanislav Fomichev --- tools/testing/selftests/bpf/test_verifier.c | 54 ++++++++++++++++++- .../selftests/bpf/verifier/lsm_cgroup.c | 34 ++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/bpf/verifier/lsm_cgroup.c diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c index a2cd236c32eb..d6bc55c54aaa 100644 --- a/tools/testing/selftests/bpf/test_verifier.c +++ b/tools/testing/selftests/bpf/test_verifier.c @@ -75,6 +75,12 @@ struct kfunc_btf_id_pair { int insn_idx; }; +struct ldx_offset { + const char *strct; + const char *field; + int insn_idx; +}; + struct bpf_test { const char *descr; struct bpf_insn insns[MAX_INSNS]; @@ -102,6 +108,7 @@ struct bpf_test { int fixup_map_ringbuf[MAX_FIXUPS]; int fixup_map_timer[MAX_FIXUPS]; struct kfunc_btf_id_pair fixup_kfunc_btf_id[MAX_FIXUPS]; + struct ldx_offset fixup_ldx[MAX_FIXUPS]; /* Expected verifier log output for result REJECT or VERBOSE_ACCEPT. * Can be a tab-separated sequence of expected strings. An empty string * means no log verification. @@ -755,6 +762,7 @@ static void do_test_fixup(struct bpf_test *test, enum bpf_prog_type prog_type, int *fixup_map_ringbuf = test->fixup_map_ringbuf; int *fixup_map_timer = test->fixup_map_timer; struct kfunc_btf_id_pair *fixup_kfunc_btf_id = test->fixup_kfunc_btf_id; + struct ldx_offset *fixup_ldx = test->fixup_ldx; if (test->fill_helper) { test->fill_insns = calloc(MAX_TEST_INSNS, sizeof(struct bpf_insn)); @@ -967,6 +975,50 @@ static void do_test_fixup(struct bpf_test *test, enum bpf_prog_type prog_type, fixup_kfunc_btf_id++; } while (fixup_kfunc_btf_id->kfunc); } + + if (fixup_ldx->strct) { + const struct btf_member *memb; + const struct btf_type *tp; + const char *name; + struct btf *btf; + int btf_id; + int off; + int i; + + btf = btf__load_vmlinux_btf(); + + do { + off = -1; + if (!btf) + goto next_ldx; + + btf_id = btf__find_by_name_kind(btf, + fixup_ldx->strct, + BTF_KIND_STRUCT); + if (btf_id < 0) + goto next_ldx; + + tp = btf__type_by_id(btf, btf_id); + memb = btf_members(tp); + + for (i = 0; i < btf_vlen(tp); i++) { + name = btf__name_by_offset(btf, + memb->name_off); + if (strcmp(fixup_ldx->field, name) == 0) { + off = memb->offset / 8; + break; + } + memb++; + } + +next_ldx: + prog[fixup_ldx->insn_idx].off = off; + fixup_ldx++; + + } while (fixup_ldx->strct); + + btf__free(btf); + } } struct libcap { @@ -1131,7 +1183,7 @@ static void do_test_single(struct bpf_test *test, bool unpriv, opts.log_level = 4; opts.prog_flags = pflags; - if (prog_type == BPF_PROG_TYPE_TRACING && test->kfunc) { + if (test->kfunc) { int attach_btf_id; attach_btf_id = libbpf_find_vmlinux_btf_id(test->kfunc, diff --git a/tools/testing/selftests/bpf/verifier/lsm_cgroup.c b/tools/testing/selftests/bpf/verifier/lsm_cgroup.c new file mode 100644 index 000000000000..af0efe783511 --- /dev/null +++ b/tools/testing/selftests/bpf/verifier/lsm_cgroup.c @@ -0,0 +1,34 @@ +#define SK_WRITABLE_FIELD(tp, field, size, res) \ +{ \ + .descr = field, \ + .insns = { \ + /* r1 = *(u64 *)(r1 + 0) */ \ + BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0), \ + /* r1 = *(u64 *)(r1 + offsetof(struct socket, sk)) */ \ + BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0), \ + /* r2 = *(u64 *)(r1 + offsetof(struct sock, )) */ \ + BPF_LDX_MEM(size, BPF_REG_2, BPF_REG_1, 0), \ + /* *(u64 *)(r1 + offsetof(struct sock, )) = r2 */ \ + BPF_STX_MEM(size, BPF_REG_1, BPF_REG_2, 0), \ + BPF_MOV64_IMM(BPF_REG_0, 1), \ + BPF_EXIT_INSN(), \ + }, \ + .result = res, \ + .errstr = res ? "no write support to 'struct sock' at off" : "", \ + .prog_type = BPF_PROG_TYPE_LSM, \ + .expected_attach_type = BPF_LSM_CGROUP, \ + .kfunc = "socket_post_create", \ + .fixup_ldx = { \ + { "socket", "sk", 1 }, \ + { tp, field, 2 }, \ + { tp, field, 3 }, \ + }, \ +} + +SK_WRITABLE_FIELD("sock_common", "skc_family", BPF_H, REJECT), +SK_WRITABLE_FIELD("sock", "sk_sndtimeo", BPF_DW, REJECT), +SK_WRITABLE_FIELD("sock", "sk_priority", BPF_W, ACCEPT), +SK_WRITABLE_FIELD("sock", "sk_mark", BPF_W, ACCEPT), +SK_WRITABLE_FIELD("sock", "sk_pacing_rate", BPF_DW, REJECT), + +#undef SK_WRITABLE_FIELD -- 2.35.1.1178.g4f1659d476-goog