From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pj1-f41.google.com (mail-pj1-f41.google.com [209.85.216.41]) (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 08B12432E7C for ; Thu, 13 Aug 2026 21:16:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.41 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786655816; cv=none; b=hZCdT9HEcGUDUYXvXqXPO6PLKNyETmKKJflb2T5JXTAN2506MFlWm2iWoa3HHRCsf3CWTAdLbsDkTDiFPKKUJ/ucKmvO1XT03GJtn3f3Q2nY7P7RUCHeAEVKWf2FYZaxVg6j2L8ukBL5tAIfxbFGuxy5vGf+g5DmbqH7vraazNc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786655816; c=relaxed/simple; bh=7l0xVe2LyVfkGorEBGaNMxELLWKDVGFFXB1DJ5Ano04=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=O7EFfqSxLxZLukg2McgsJ+wmAf+r2uJjnDBPJVBMK/Q5uxMNKJMpgBH/PfDdbpBIUs9kGvHTSD4o3crH0Z82Jb5rjachOBSCAcF3zv2U0oUDpcrko7+n6LmwvyYRe7sSOANEtd7CUxvIzeGiI5Cne68snAM/lld2h905NTgP0sU= 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=lZ0Gfbs+; arc=none smtp.client-ip=209.85.216.41 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="lZ0Gfbs+" Received: by mail-pj1-f41.google.com with SMTP id 98e67ed59e1d1-38dc4553f62so444040a91.0 for ; Thu, 13 Aug 2026 14:16:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786655807; x=1787260607; 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=b35On+LZmzrHtmSn5bQB+gzqg4iokp+EtUtdHB8ERVI=; b=lZ0Gfbs+VyMopqbFHQm6349hOuQtkCC3yGUpMrcJORx0SpfLTDjA88A6XL55pOlpMs ZY+vfHEVHhDc/rS6C5KM4BOp1MCfTTc8VdeyTti8yVwi+O9PP4StUDcLYtxcOJL5tdR1 PmWZZzOFF+Vu5Weq/xsiyXw7aG11oeQGhHL1rGsltaRi2I+vVxbes+YRgsh9PQgfRD6T Lg3bsyqOPZJtTxgu5QF/qtbqzaJxPfGzN+yN6gvbyHBkGo6xdsY+43IN0rLo8P5QoPu0 dPC9bNO2MCrtKBFEI6BbpOOO0AnZgVBpXPHRDmR9Cn3Oud1ckOVHfc8qMkoGaWwUg3oE 0EFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786655807; x=1787260607; 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=b35On+LZmzrHtmSn5bQB+gzqg4iokp+EtUtdHB8ERVI=; b=mFa07HVtr2nTwjuXchBLuyQNn+It3xSlFidpeJEs25vGVVLIsl5tQH2UIgwDr4EQbs jGs1km4BHHbqkfRGTWawJoR2Txc6EKOG8yXyBSukA1Si+wWLTKb/Rr2ww6uJwzjfHUjK mAtZm9ZyvALs4xeCFJhwI+mFDxFltiJDAMTipy/d5XqOYyGreoi3PbfNBuP1vkoIhexa i82I6UofIkd6WdJajnSDFwcpKB+jz0UiSPFlYWjP1GbmIoF5e6OedQFJdI3EiN44f1Ah N8v70CemciXHJkFjRRCOv7Xzkuh3X701UfxjT49oDYvtIES+DTfMqGBphuu+fv8QHjNH Jj9g== X-Forwarded-Encrypted: i=1; AHgh+RrdlKAKT32OcaiMaPhtthhvOvr1Ue1FAd/Z5fGVadrh1RkZehKVPkq8flP2Ub1LXppP0ESqkYGgO3i98SU=@vger.kernel.org X-Gm-Message-State: AOJu0Yy8oOn0Ls5vgK4RmuhomorB2jnWstQmX70iO6fhlhzzGq2OQyQ9 iQOSvxC4eEsvuIYe6JlPfcSP7041Fu/6nRZt9lJC6yJ1nYYCMh80+NO4 X-Gm-Gg: AR+sD10cKq40jxoUY8Wtw6izg7oXjDUl7n/89TpwlkjmXm6uqj4qcalY3lzPdRYvl4o cfdQFn8pY/OTRjO3QdoiAstslTFPw5gxldw3VOQSgRUwdxkTt0SY7M0sVTyMA8mt3SHpN4gu6Wx D0+bLT93LSA/Yh6XyNOnEpJrWVIl4j124K1EiYQET646Y+Q+IR5adto8Yhxg3dNJeuP74Of0pK+ UI99v+Zvt86fbMvZG4b0Y3bsbqf7dQE73RVQ2WFvrn+ImGdEqNKr8inYuC/NrmC6FefLpMVxu0k k2MqqzMmzmnFzAyO9htmbck4JUAZYb1X8qr2IVSRJWVtHqNPhFtU23LpVx8Bz+n2CXsrukc3jv5 mOnYsfMCeU0+O/2ubEUaShUzJuPsSwDGLvkS25FU1gd8Kg+Mj3i38PQFIk89fF38HaeKofuqpoh yWjvwjGVS0ZBmFy8cDsK4m7CRb/NnVcJGIlbf7eK5vblueCt4loJ0kY1O3c/GwHHkmRqFNXdYtF mkqg2u+ECAuXRw2 X-Received: by 2002:a17:90b:5807:b0:37f:ed7e:7e42 with SMTP id 98e67ed59e1d1-3933b958ad5mr945995a91.14.1786655806903; Thu, 13 Aug 2026 14:16:46 -0700 (PDT) Received: from patterson.cs.ubc.ca (patterson.cs.ubc.ca. [198.162.52.65]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-3933a03e288sm853985a91.17.2026.08.13.14.16.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Aug 2026 14:16:46 -0700 (PDT) From: Ning Ding To: bpf@vger.kernel.org Cc: memxor@gmail.com, greg@kroah.com, dingning04@gmail.com, sashiko-bot@kernel.org, Andrii Nakryiko , Eduard Zingerman , Ihor Solodrai , Alexei Starovoitov , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , Jiri Olsa , Emil Tsalapatis , Shuah Khan , Kaitao Cheng , Viktor Malik , Justin Suess , Leon Hwang , Yiyang Chen , linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH bpf-next v4 4/4] selftests/bpf: Test untrusted allocated-object pointers Date: Thu, 13 Aug 2026 14:15:26 -0700 Message-ID: <20260813211533.290256-5-dingning04@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260813211533.290256-1-dingning04@gmail.com> References: <20260813211533.290256-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 fd35093285c0..383c5b1b7111 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("?syscall") +__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("?syscall") +__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("?syscall") +__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("?syscall") +__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 acd3e81a3916..0cc4cbd0c81b 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("?syscall") +__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