From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-qt1-f181.google.com (mail-qt1-f181.google.com [209.85.160.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C2EEF403B0A for ; Tue, 14 Jul 2026 09:39:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.181 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784021958; cv=none; b=BS4U6/CJrlDeNBYIlaiuWuxC5UhXUCuB1ZqODeZdDQFHuL2A/j22vt9azDdxAlGyVq8mobvD2/BkWYAqFZXh9iFp77Io4p7F6llg2eg8IoXkEK7o48pv1Zy+qWmqVvhTo9DjYBHQi/7C8cxZMi7VIcD4iCTBKb7Z6zashENKkjE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784021958; c=relaxed/simple; bh=r/JDpp9Iimh8FTBDGcm0LfUXUFcOqUVFUp0bIL15etE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IVPrMAl2D5lm3PxbdzA3T1fvf1NVpzaBrHTqhIOmyO4SVK5RIr7k9IisiXAcplt2EvCFNsaeJXvXIxSZBeu8BhalBfvxmQp8KxMDPunXrcF2ei8g1ldBRrD3FMYIAEAKzAtND69JauF1EVCX/upHvebTL4rCDIO2Ztv1Fj3r8G0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=EkUAr68F; arc=none smtp.client-ip=209.85.160.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="EkUAr68F" Received: by mail-qt1-f181.google.com with SMTP id d75a77b69052e-51bfb91795eso34882811cf.1 for ; Tue, 14 Jul 2026 02:39:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1784021956; x=1784626756; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=TRUF16K+9RX9W6LVqQ9Os239vrltLvcFobxQ5E3uYfY=; b=EkUAr68FD1Tpn54nA37AJN98Lw+fsieXK66U1a1jV4R5z8HwcMQQtmCqyBbA3ttpcO pI8m6y4rAlCavm1/XFZEpoatat+7J4TxEBTthsAG5dIUO/Q6z9+eto5EHS5pppKhVBgT Qf6oUJNhws9ewmKT4NC7OO61llYMIFrNjQCpAApRW28kPATYHxuHigUcD6PrjJ1jMI46 krfZJwzyHXZ/Pc+Rt1JD4RJsb1A7AF2sP7XUL208K9vAhdVSEvRO8XLXBTlIGtuzkig3 Y8ezaHmKNizCrrMbRYI1pqeZ4ONZgOOg09ANjOXd+Uu6YL5TGuBWimSqUQjDmw2F9yEr rTWw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784021956; x=1784626756; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=TRUF16K+9RX9W6LVqQ9Os239vrltLvcFobxQ5E3uYfY=; b=liHfOpWL5YJSTwFMXNreWYF76F05UL5fNzJp1ccI8EUCSuvJgbgSTHf161FVQer4a9 3SI3ISZqaj4pO7UDnZoymhuyAnCU9gwM5VmDSB1bbR1PaeBK40r3+rFFBzWq/qenQ1r0 T0mZkKWjIzLoc8fsFmozuzsTuboLgEzbxJFAGOYsjHneYhS4YEuz4pAEyaiWqt7RmJcP lt5Bb1dbtxxWRqLcSvHjX0pz5DowjwBurmIibkE6LNioHkri/OCVe5gUAV3K6XOeKzk5 2EqliIl4panxyxNaMkNfs23ddhbVIAUeGvIXHYArfnD3MkK8hniov9LKwOwhI0HR6GQO mYjw== X-Forwarded-Encrypted: i=1; AHgh+RrhKafyvzGyFOBOHxsJU6mHsoq+YcYKvZ+uEIO4oYK9vTlLpCiezX3xG87xoEPFyvB4yglYdFssjt+qpnY=@vger.kernel.org X-Gm-Message-State: AOJu0YydHOEDrEv1Av3uhm59nN/9/fsgHG2GNR2SOxap1artzzMo8Jdb zpUcDlTqnJXkAeCGybtYuSxdP+rCGegWdIGFHhbrXErt+J5kkZ5CWuqM X-Gm-Gg: AfdE7cmSu3wKULruD7ONGLuiKAkaOcF+W6+6FixB29Oxhc/7yfWYEaS7UNGsxZPNqm2 Xtl46ZXi2rVP70FTekzmXXzWwQ2NQvWzWwwtSLiyBI+1LqqyO2oUk/jbaMLBwG8bXsTtI68xlRc K/lKJE5+jKxhQ5jenL0FNA4w5cIEvrFl7old+5gA5LtURiFt0AFPTXHPGLutfg9EYhbuD033SsR Ntr1RvCwBpHcl7qcRQx42J7VE4ur2SVJcK9FDLWVjzT8kCnVOoxCaR0qrRbnP02ISY8IAImRirz tBVH6xdh71AVkr6csLEWnum1k3pnPnJtnsBoVAFMmQgM8mg/U2Uo9xQFt3iOwSZ80tGLMoMz/+E P6qBJDJWZn/SlBU3BZVBXECgh53XM/jDzdSB56KCmhQnyp9yVhjkF3ItwhzBYN++H6p0aPOIflu fIuX2vs9hV+7aX9gKIG7nYWsRZAR2xwkZ35WIN46KJ4ZpeXRA5BUwkI0rVSaKkRJaqbAKnj/Hw X-Received: by 2002:ac8:5fc9:0:b0:51b:9878:8242 with SMTP id d75a77b69052e-51e42364121mr10307501cf.6.1784021955639; Tue, 14 Jul 2026 02:39:15 -0700 (PDT) Received: from localhost.localdomain ([202.8.105.115]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-51caacf2a75sm111460511cf.13.2026.07.14.02.39.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Jul 2026 02:39:15 -0700 (PDT) From: Sun Jian To: bpf@vger.kernel.org Cc: Alexei Starovoitov , Andrii Nakryiko , Daniel Borkmann , Eduard Zingerman , Emil Tsalapatis , Jiri Olsa , John Fastabend , Kumar Kartikeya Dwivedi , Martin KaFai Lau , Shuah Khan , Song Liu , Yonghong Song , Shung-Hsi Yu , Matt Mullins , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Sun Jian , stable@vger.kernel.org Subject: [PATCH bpf v5 2/2] selftests/bpf: Cover negative buffer pointer offsets Date: Tue, 14 Jul 2026 02:38:46 -0700 Message-ID: <20260714093846.18159-3-sun.jian.kdev@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260714093846.18159-1-sun.jian.kdev@gmail.com> References: <20260714093846.18159-1-sun.jian.kdev@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Add verifier coverage for constant negative offsets on PTR_TO_TP_BUFFER and PTR_TO_BUF pointers. Both programs adjust the buffer pointer by -8 and access it at offset zero, so the negative effective start must be rejected at load time. Switch the raw tracepoint writable attach checks from nbd_send_request to bpf_testmod_test_writable_bare_tp, avoiding a dependency on the NBD tracepoint. Keep the existing past-end case and add a case with a negative var_off compensated by a positive instruction offset. The effective start remains non-negative, so the program loads, but its access end exceeds the writable context size and bpf_raw_tracepoint_open() must return -EINVAL. Reported-by: Shung-Hsi Yu Link: https://lore.kernel.org/bpf/alRtilWhKw4zzMkI@u94a Cc: stable@vger.kernel.org # 5.2.0 Signed-off-by: Sun Jian --- .../raw_tp_writable_reject_bad_access.c | 57 +++++++++++++++++++ .../raw_tp_writable_reject_nbd_invalid.c | 43 -------------- .../selftests/bpf/prog_tests/verifier.c | 2 + .../selftests/bpf/progs/verifier_ptr_to_buf.c | 27 +++++++++ .../bpf/progs/verifier_raw_tp_writable.c | 16 ++++++ 5 files changed, 102 insertions(+), 43 deletions(-) create mode 100644 tools/testing/selftests/bpf/prog_tests/raw_tp_writable_reject_bad_access.c delete mode 100644 tools/testing/selftests/bpf/prog_tests/raw_tp_writable_reject_nbd_invalid.c create mode 100644 tools/testing/selftests/bpf/progs/verifier_ptr_to_buf.c diff --git a/tools/testing/selftests/bpf/prog_tests/raw_tp_writable_reject_bad_access.c b/tools/testing/selftests/bpf/prog_tests/raw_tp_writable_reject_bad_access.c new file mode 100644 index 000000000000..b8538fc4fc3f --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/raw_tp_writable_reject_bad_access.c @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include "test_kmods/bpf_testmod.h" +#include "bpf_util.h" + +static void check_attach_reject(const struct bpf_insn *program, size_t prog_len) +{ + LIBBPF_OPTS(bpf_prog_load_opts, opts); + char error[4096]; + int bpf_fd, tp_fd; + + opts.log_level = 2; + opts.log_buf = error; + opts.log_size = sizeof(error); + + bpf_fd = bpf_prog_load(BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE, NULL, "GPL v2", + program, prog_len, &opts); + if (!ASSERT_GE(bpf_fd, 0, "prog_load")) + return; + + tp_fd = bpf_raw_tracepoint_open("bpf_testmod_test_writable_bare_tp", bpf_fd); + ASSERT_EQ(tp_fd, -EINVAL, "bpf_raw_tracepoint_open"); + if (tp_fd >= 0) + close(tp_fd); + + close(bpf_fd); +} + +void test_raw_tp_writable_reject_bad_access(void) +{ + const struct bpf_insn program[] = { + /* r6 is our tp buffer */ + BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0), + /* one byte beyond the end of the writable context */ + BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_6, + sizeof(struct bpf_testmod_test_writable_ctx)), + BPF_EXIT_INSN(), + }; + + const struct bpf_insn negative_var_off_program[] = { + BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0), + /* make var_off negative, but keep the effective access offset non-negative */ + BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8), + /* one byte beyond the end of the writable context */ + BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_6, + sizeof(struct bpf_testmod_test_writable_ctx) + 8), + BPF_EXIT_INSN(), + }; + + if (test__start_subtest("past_end")) + check_attach_reject(program, ARRAY_SIZE(program)); + + if (test__start_subtest("negative_var_off_past_end")) + check_attach_reject(negative_var_off_program, + ARRAY_SIZE(negative_var_off_program)); +} diff --git a/tools/testing/selftests/bpf/prog_tests/raw_tp_writable_reject_nbd_invalid.c b/tools/testing/selftests/bpf/prog_tests/raw_tp_writable_reject_nbd_invalid.c deleted file mode 100644 index 216b0dfac0fe..000000000000 --- a/tools/testing/selftests/bpf/prog_tests/raw_tp_writable_reject_nbd_invalid.c +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -#include -#include -#include "bpf_util.h" - -void test_raw_tp_writable_reject_nbd_invalid(void) -{ - __u32 duration = 0; - char error[4096]; - int bpf_fd = -1, tp_fd = -1; - - const struct bpf_insn program[] = { - /* r6 is our tp buffer */ - BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0), - /* one byte beyond the end of the nbd_request struct */ - BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_6, - sizeof(struct nbd_request)), - BPF_EXIT_INSN(), - }; - - LIBBPF_OPTS(bpf_prog_load_opts, opts, - .log_level = 2, - .log_buf = error, - .log_size = sizeof(error), - ); - - bpf_fd = bpf_prog_load(BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE, NULL, "GPL v2", - program, ARRAY_SIZE(program), - &opts); - if (CHECK(bpf_fd < 0, "bpf_raw_tracepoint_writable load", - "failed: %d errno %d\n", bpf_fd, errno)) - return; - - tp_fd = bpf_raw_tracepoint_open("nbd_send_request", bpf_fd); - if (CHECK(tp_fd >= 0, "bpf_raw_tracepoint_writable open", - "erroneously succeeded\n")) - goto out_bpffd; - - close(tp_fd); -out_bpffd: - close(bpf_fd); -} diff --git a/tools/testing/selftests/bpf/prog_tests/verifier.c b/tools/testing/selftests/bpf/prog_tests/verifier.c index 8a3d69e2453c..be97f6887f0e 100644 --- a/tools/testing/selftests/bpf/prog_tests/verifier.c +++ b/tools/testing/selftests/bpf/prog_tests/verifier.c @@ -78,6 +78,7 @@ #include "verifier_precision.skel.h" #include "verifier_prevent_map_lookup.skel.h" #include "verifier_private_stack.skel.h" +#include "verifier_ptr_to_buf.skel.h" #include "verifier_raw_stack.skel.h" #include "verifier_raw_tp_writable.skel.h" #include "verifier_reg_equal.skel.h" @@ -230,6 +231,7 @@ void test_verifier_or_jmp32_k(void) { RUN(verifier_or_jmp32_k); } void test_verifier_precision(void) { RUN(verifier_precision); } void test_verifier_prevent_map_lookup(void) { RUN(verifier_prevent_map_lookup); } void test_verifier_private_stack(void) { RUN(verifier_private_stack); } +void test_verifier_ptr_to_buf(void) { RUN(verifier_ptr_to_buf); } void test_verifier_raw_stack(void) { RUN(verifier_raw_stack); } void test_verifier_raw_tp_writable(void) { RUN(verifier_raw_tp_writable); } void test_verifier_reg_equal(void) { RUN(verifier_reg_equal); } diff --git a/tools/testing/selftests/bpf/progs/verifier_ptr_to_buf.c b/tools/testing/selftests/bpf/progs/verifier_ptr_to_buf.c new file mode 100644 index 000000000000..12cf24db46a0 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/verifier_ptr_to_buf.c @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include "bpf_misc.h" + +SEC("iter/bpf_map_elem") +__description("PTR_TO_BUF: reject negative const offset") +__failure +__msg("invalid negative rdwr buffer offset") +__naked void ptr_to_buf_reject_negative_const_offset(void) +{ + asm volatile ("r0 = 0; \ + r2 = *(u64 *)(r1 + %[value_off]); \ + if r2 == 0 goto l0_%=; \ + r2 += -8; \ + r0 = *(u64 *)(r2 + 0); \ +l0_%=: \ + exit; \ + " + : + : __imm_const(value_off, + offsetof(struct bpf_iter__bpf_map_elem, value)) + : __clobber_all); +} + +char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/progs/verifier_raw_tp_writable.c b/tools/testing/selftests/bpf/progs/verifier_raw_tp_writable.c index 14a0172e2141..4055a6443bc2 100644 --- a/tools/testing/selftests/bpf/progs/verifier_raw_tp_writable.c +++ b/tools/testing/selftests/bpf/progs/verifier_raw_tp_writable.c @@ -47,4 +47,20 @@ l0_%=: /* shift the buffer pointer to a variable location */\ : __clobber_all); } +SEC("raw_tracepoint.w") +__description("raw_tracepoint_writable: reject negative const offset") +__failure +__msg("invalid negative tracepoint buffer offset") +__naked void tracepoint_writable_reject_negative_const_offset(void) +{ + asm volatile (" \ + r6 = *(u64 *)(r1 + 0); \ + r6 += -8; \ + r0 = *(u64 *)(r6 + 0); \ + exit; \ +" : + : + : __clobber_all); +} + char _license[] SEC("license") = "GPL"; -- 2.43.0