From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f179.google.com (mail-pl1-f179.google.com [209.85.214.179]) (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 1B13234251B for ; Mon, 3 Aug 2026 11:25:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.179 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785756347; cv=none; b=fzTEoJImcPiZr+Js43Vst14GQNESG0VikXG7ppSipxv+eCXBv/y2fCeU/poxEtlkYf/1nTnWVZ9EoaqUyptT42Tnqi2hH6NzoEBaPxnaclOapeJJxZFfRx8fRZAIoHZGlQljLI0p4pB3ZYdN56DwK4EisUuOk4vD8mmyZzK41xU= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785756347; c=relaxed/simple; bh=DX2T1t5+wkhjkNMPP9O3hcoBYmJLEcLYhP/ce7kvHxc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ZnqY4UDmMtw2WXXdYN7GRr3CpRTBw1NviHVkxCULFeN2yTs9CkIQX8hCeuPINE+FcQeiFq5FQgR3njHmM57LsdS42+YsRgI1jGsOQCTT1TiKRf1cHcQLkxYeVfWNroh5lZHgQRaxRcKqZMtUWktmWMb6O6PXUHa/HF1/a+DU4LE= 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=RJawwLb6; arc=none smtp.client-ip=209.85.214.179 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="RJawwLb6" Received: by mail-pl1-f179.google.com with SMTP id d9443c01a7336-2caced6038eso31715825ad.0 for ; Mon, 03 Aug 2026 04:25:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785756345; x=1786361145; 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=GA10tWMw7G+suJhvgrYzC8iyWhRvHbTnt0EFzl+EgR0=; b=RJawwLb6e7YTLm/aOWEsMKc9Yezb68C2KZkYyU4VNPmXvptH4+G5bhkyWWGO02BLTU OGRmr+F4v6OqjGcGeW3NEBr1Tzod3NKGftCLPtVEfJFGLZcvKF/EsHnuNdIyLaKvOrP5 cSzQRij2GOnlXs5lOeN3rrm952UQaU6XhgczM4AYkmshbyEJKnWFGdIRX7W0rsZTk3a4 iHUtrJKBi8IG/IEnFkz5+uNtQL9D8lBRYQeEEopnVzqcOh1pqohdzRUU48NUr7q5Fpqj ob2tCFQwMBYylqVYbXKikatSoeRg4Uspzh+A+G2qFMZvegZzz0lDLGxDzzdmtX45a1QC ciCQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785756345; x=1786361145; 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=GA10tWMw7G+suJhvgrYzC8iyWhRvHbTnt0EFzl+EgR0=; b=CdS3LxgwBIEEK58XOi5cHbhWz/n1vtVa5F2eK1ydzSCifsa0T+2F6LMl4w3MhnxrDo AdblOLOthjY0kcbdTRx3o6QnfFfbxPicZmyCONaNS2vDSKJ6TwmJYn8lr5/5Q4Zji1J8 0kol4fLqX8k+769jP3SMkErsH4ad9zbtw3lopeLOwAvpajxGd8ANtO/xsCUlilsTpwQQ a4F4X9TIs5C/iEZFT8HzY8vPzDMo5i2oUIBcKISqQ/7J5U7maoKSR1Y69BQl05FFif+w r8R9BNEhaz6c+ldu7FYY7MX+NrE4L5uhpqVUr6y1nwDoi2HdVE0qt7obZcsGjzBZ2gaw JE9w== X-Forwarded-Encrypted: i=1; AHgh+RqlFh7FinGsOqKQKvDtOzmDQeTGwxVNU7QvArsaT6nZg5cfxUkROHcbqz8GwmmE85drE+j9TxjYZXKmdS0=@vger.kernel.org X-Gm-Message-State: AOJu0Yy+ktxPEUEbSgr9YiOMKOfvsFKGfFjYwmASamKjgc5adtT/38LX suGcynG5gqkIVGyQRXw3NhHsr5OXrXpYtrAdrZDEh1dAoV+I1IhS5tom X-Gm-Gg: AR+sD11UJQhOhuK4Q78XeTbT25Wi6bVcyw/+ZzQt+iPgk8zcpZ9OWfty+1HgL/wo/ZV OpYcLW2bTkczF2v+4Cik/mmgSpAMGxH+BWPtuxQJvzvqOFvuNKQOXSzM1BWUInZsDuODtaX2vjU paeL+8fHOlhwyoFkPGm5GIR4Op4nwIa9OustpPd7BvoUwpO3VS0FreViHAmPWsqS6EPgs04EuDH ZT8usMgXfHu3u+nT6SNdbnggTMKPtBERM3nFevy20b8j6/doQ0dpZsQTd4shY0UAnLmbSe8+F1s WNf6ooih8CVjUeTYdRvbRd92JwZTM29liZk7P3yr6KyyDhcHQcdycjAsM+MdmjCDgxM1kfmKfC9 kMWrfqxumk/hmk9Mo2LOhajlWGZS26rjTAq2ma7a6OWCQfowCKZ+wtko7jmMGfsQ2BTYy5MQ6N4 kmXENlrW7UXhbFM5Uxaab/RkT1948gPv6EERiPdwb//XbLE4YIGxyATzjFxK7+acA0G6xfN3iIw +VewSOQewJS0HhgaA== X-Received: by 2002:a17:903:1786:b0:2cf:70d2:da7c with SMTP id d9443c01a7336-2d047d7921fmr108519205ad.12.1785756345462; Mon, 03 Aug 2026 04:25:45 -0700 (PDT) Received: from patterson.cs.ubc.ca (patterson.cs.ubc.ca. [198.162.52.65]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2d04ae5a91asm36190685ad.21.2026.08.03.04.25.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Aug 2026 04:25:45 -0700 (PDT) From: Ning Ding To: bpf@vger.kernel.org Cc: memxor@gmail.com, greg@kroah.com, Ning Ding , sashiko-bot@kernel.org, Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Eduard Zingerman , Martin KaFai Lau , Song Liu , Yonghong Song , Jiri Olsa , Emil Tsalapatis , Shuah Khan , Viktor Malik , Justin Suess , Kaitao Cheng , Leon Hwang , Yiyang Chen , linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH bpf v3 4/4] selftests/bpf: Test untrusted allocated-object pointers Date: Mon, 3 Aug 2026 04:22:11 -0700 Message-ID: <20260803112218.3361213-5-dingning04@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260803112218.3361213-1-dingning04@gmail.com> References: <20260803112218.3361213-1-dingning04@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 The verifier previously allowed pointers used after RCU protection ended to reach bpf_refcount_acquire() and, for one object layout, a direct write. If the object was freed and reused, these operations could access stale memory. Add tests that keep BPF_PROBE_MEM reads accepted but reject reference acquisition and direct writes after RCU protection ends. Cover both tested object layouts. Reported-by: sashiko-bot@kernel.org Link: https://lore.kernel.org/r/20260726021304.97ED91F000E9@smtp.kernel.org Assisted-by: Codex:gpt-5 Signed-off-by: Ning Ding --- .../selftests/bpf/progs/refcounted_kptr.c | 100 ++++++++++++++++++ .../bpf/progs/refcounted_kptr_fail.c | 27 +++++ 2 files changed, 127 insertions(+) diff --git a/tools/testing/selftests/bpf/progs/refcounted_kptr.c b/tools/testing/selftests/bpf/progs/refcounted_kptr.c index fd35093285c0d..b70be8b52ff80 100644 --- a/tools/testing/selftests/bpf/progs/refcounted_kptr.c +++ b/tools/testing/selftests/bpf/progs/refcounted_kptr.c @@ -893,6 +893,106 @@ long refcount_acquire_rcu_map_kptr_null_checked(void *ctx) return 0; } +SEC("?tc") +__success +long map_kptr_read_after_rcu_unlock(void *ctx) +{ + struct map_value_refcount_only *mapval; + struct node_refcount_only *n; + int idx = 0; + + mapval = bpf_map_lookup_elem(&stashed_refcount_only, &idx); + if (!mapval) + return 0; + + bpf_rcu_read_lock(); + n = mapval->node; + if (!n) { + bpf_rcu_read_unlock(); + return 0; + } + bpf_rcu_read_unlock(); + + return n->key; +} + +SEC("?tc") +__failure __msg("is neither owning or non-owning ref") +long refcount_acquire_graph_after_rcu_unlock(void *ctx) +{ + struct map_value *mapval; + struct node_data *n, *m; + int idx = 0; + + mapval = bpf_map_lookup_elem(&stashed_nodes, &idx); + if (!mapval) + return 0; + + bpf_rcu_read_lock(); + n = mapval->node; + if (!n) { + bpf_rcu_read_unlock(); + return 0; + } + bpf_rcu_read_unlock(); + + m = bpf_refcount_acquire(n); + if (m) + bpf_obj_drop(m); + + return 0; +} + +SEC("?tc") +__failure __msg("only read is supported") +long graph_map_kptr_write_after_rcu_unlock(void *ctx) +{ + struct map_value *mapval; + struct node_data *n; + int idx = 0; + + mapval = bpf_map_lookup_elem(&stashed_nodes, &idx); + if (!mapval) + return 1; + + bpf_rcu_read_lock(); + n = mapval->node; + if (!n) { + bpf_rcu_read_unlock(); + return 2; + } + bpf_rcu_read_unlock(); + + n->key = 1; + return 0; +} + +SEC("?tc") +__success +long graph_map_kptr_read_after_spin_unlock(void *ctx) +{ + struct map_value *mapval; + struct node_data *n; + int idx = 0; + + mapval = bpf_map_lookup_elem(&stashed_nodes, &idx); + if (!mapval) + return 0; + + bpf_rcu_read_lock(); + n = mapval->node; + if (!n) { + bpf_rcu_read_unlock(); + return 0; + } + bpf_rcu_read_unlock(); + + bpf_spin_lock(&lock); + bpf_spin_unlock(&lock); + + return n->key; +} + static long __stash_map_empty_xchg(struct node_data *n, int idx) { struct map_value *mapval = bpf_map_lookup_elem(&stashed_nodes, &idx); diff --git a/tools/testing/selftests/bpf/progs/refcounted_kptr_fail.c b/tools/testing/selftests/bpf/progs/refcounted_kptr_fail.c index acd3e81a39168..3408f68ad444d 100644 --- a/tools/testing/selftests/bpf/progs/refcounted_kptr_fail.c +++ b/tools/testing/selftests/bpf/progs/refcounted_kptr_fail.c @@ -127,6 +127,33 @@ long refcount_acquire_rcu_map_kptr_unchecked_drop(void *ctx) return 0; } +SEC("?tc") +__failure __msg("is neither owning or non-owning ref") +long refcount_acquire_after_rcu_unlock(void *ctx) +{ + struct map_value_refcount_only *mapval; + struct node_refcount_only *n, *m; + int idx = 0; + + mapval = bpf_map_lookup_elem(&stashed_refcount_only, &idx); + if (!mapval) + return 1; + + bpf_rcu_read_lock(); + n = mapval->node; + if (!n) { + bpf_rcu_read_unlock(); + return 2; + } + bpf_rcu_read_unlock(); + + m = bpf_refcount_acquire(n); + if (m) + bpf_obj_drop(m); + + return 0; +} + SEC("?tc") __failure __msg("Unreleased reference id=3 alloc_insn={{[0-9]+}}") long rbtree_refcounted_node_ref_escapes_owning_input(void *ctx) -- 2.43.0