From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pf1-f171.google.com (mail-pf1-f171.google.com [209.85.210.171]) (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 BD1422D662F for ; Tue, 28 Jul 2026 03:38:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.171 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785209935; cv=none; b=rrl2YHE/B8xvxdgdhbyPpLSOFFWc7UqoBA7XEpdrr80VI9rKHR4jCn5altucotrFonKXwP8St+QeLNndefBw6ajv1aIJny+7jkAfzccGtKRKsdnY2zRGeL9E0snYHDlgJjKBjlrmgXVUTrZoXeDN0ZkmTJZOsnGsGShn9iAR60E= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785209935; c=relaxed/simple; bh=rZjYNl3+MPB+91xxVJNulZvx9ICIzCZfQoEYPHyNCEQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=W+FkxQoP88njRfbkVgevORpj6iCJuDZZEkVY/TzM3jbw8Yihiw4EZr0W0FwwOD5+ZT/7juig0J1dcD5XKz9ij0dqz7NP7gSiwULpHtN8tihfNYCZ6s9SbmWmhZp7Sobgthy1OHynboUua/4R+2kEYaiLDRp8jbNmX74J8wiL7UE= 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=MVTpRJws; arc=none smtp.client-ip=209.85.210.171 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="MVTpRJws" Received: by mail-pf1-f171.google.com with SMTP id d2e1a72fcca58-848593533cbso2438280b3a.3 for ; Mon, 27 Jul 2026 20:38:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785209933; x=1785814733; 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=q8rlllOW1RK3ni0UfDzUVjg1yaTTz9iURLbN/ICv9wY=; b=MVTpRJwsBIBf8bL//bMNDDFRrETpq2j5uJVpbekoiXHUezVLCjVr1G4JERzPQ1fsAZ bO4hjdnDHdpEJL7tQuC4pX4HgOWdfRVZWbTVTAoCIg5LpletYSI5Pemo3VKWOmmWEpW2 523hwHwyAbRvxNfojE9uVetu3uxH83IjjLwlcU/wZ6W0mgv2AluY99B2kJWoKx6XI71y cJZ0sKUb0v5E6PtWSJ1ErN6nniF64cO0cLJT2r/p+qN89NHjxLNHrAkYDMEelU4m88oK +NZjzzezMY4eHK5a8yatpBntS1DNCJ3W4HWoanK2Kr0/UAVGl4/CLUHO6UQNZKo05PLJ KsbQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785209933; x=1785814733; 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=q8rlllOW1RK3ni0UfDzUVjg1yaTTz9iURLbN/ICv9wY=; b=bOEfw5a2rXDWyiiMt6xj45xohJSD0hZKdAzqBxmOsOxrE22aipk4KsrLnpiJJFzW25 mSLIxZ2v/4KAVSUxXEg4ASg2xTBvm6y5B3HYut+dPWB1RiWaDz/1V6IfGlKxwtfv1zSi whdYSvfffYgZNh4kjrteooVxdOpJJ5O5ceGpm4gqb1dJPpXsGoKhSTjPEH/jM2gNUm8i b0oKISAtjN94vj9pD2TiYKZBv3ZU0T6oY2Q8vo4C1tDJiZZ3Mfb4bd9W90ObasxBvyj3 SodA3E+h87BYd3oRS9pyv52PYNGqMKJVnDH580f8ZRGZdR89o1P4HleLkJ7cJU2LBtgL WVwQ== X-Forwarded-Encrypted: i=1; AHgh+Rq8jif3HTXmmqzQod40Mmb075PExmfOWomCogJ3jcSVZEaxTTlh3Bu6cw0Uua+f5zJfmaePbY1By76z3wbSnqw=@vger.kernel.org X-Gm-Message-State: AOJu0YzHOGBG/I2Gk8lxVyf3u1G1uY+hp1xrjdvYn8Cydyqvs7wFGZMG EZobP8Fv4ukv1NmgaRN5ReClqsori0e7uiB51WiS6WReFj13CQULHZ9B X-Gm-Gg: AR+sD12zRzP6maAzYkpc6/lDKM0hdZgBG6+cOfTE5CXhD6yoB59LtJsuQEbHJHDhOl9 RXbc8Jpfs5Xvvjs5kiPchvGjPxtRlN0fdo3WNIi7fajbLd0UJl/H07kjhOfHGCaHSGZU8NGIw+d tfIc4j0djsnDCOhxkwy75hY8j+MYDHjZCGzariuxoXOI9NWHhbXQEroBtTCR6Rgb5Q366kf3sg4 bjv6UL9BYW7uLGNkvlkoO9DRTLCWm2axCu04PkscKLsJ0/5FQj5S9vKMWTG2AWEwxfzV7APuUH/ 1/iKjWZSGXgP1NEiaejEao/6csYxfL0G0+Ui9Bijh4yRrYwGcs1KqzQtS55/vth9QSArDIEFbbZ lylYV5Ikh+qyC9mjMje4w/ySNRUqfRMYBhGnXx56mOBFs9iUsJpA9HuOywzYrs++teLN2ZLe+aX yiEbD/XzQtX8/csVjNtl+hpysJsRA3mA== X-Received: by 2002:a05:6a00:84f:b0:847:8d54:f4f9 with SMTP id d2e1a72fcca58-84e93358f09mr584000b3a.51.1785209932964; Mon, 27 Jul 2026 20:38:52 -0700 (PDT) Received: from patterson.cs.ubc.ca (patterson.cs.ubc.ca. [198.162.52.65]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-84e5325856dsm3753865b3a.9.2026.07.27.20.38.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Jul 2026 20:38:52 -0700 (PDT) From: Ning Ding To: bpf@vger.kernel.org Cc: ast@kernel.org, daniel@iogearbox.net, john.fastabend@gmail.com, andrii@kernel.org, eddyz87@gmail.com, memxor@gmail.com, martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev, jolsa@kernel.org, emil@etsalapatis.com, shuah@kernel.org, danieltimlee@gmail.com, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Ning Ding Subject: [PATCH bpf] bpf: Reject writes through untrusted allocated pointers Date: Mon, 27 Jul 2026 20:38:37 -0700 Message-ID: <20260728033837.1466123-1-dingning04@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260726021304.97ED91F000E9@smtp.kernel.org> References: <20260726021304.97ED91F000E9@smtp.kernel.org> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit A kptr loaded under an RCU read lock has MEM_ALLOC set. After bpf_rcu_read_unlock(), the verifier marks it PTR_UNTRUSTED, but check_ptr_to_btf_access() still allows writes because type_is_ptr_alloc_obj() ignores that flag. Reject writes through MEM_ALLOC pointers that are PTR_UNTRUSTED. Reads remain allowed and are converted to probe-memory accesses. Also skip the owning-reference check for these pointers, since they no longer have a live reference after leaving the RCU critical section. Add verifier tests for the rejected write and permitted read cases. Fixes: 503e4def5414 ("bpf: Replace open code with for allocated object check") Closes: https://lore.kernel.org/all/20260726021304.97ED91F000E9@smtp.kernel.org/ Assisted-by: Codex:gpt-5.6-sol Signed-off-by: Ning Ding --- kernel/bpf/verifier.c | 6 +- .../bpf/progs/local_kptr_stash_fail.c | 58 +++++++++++++++++++ 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 7aa47342dc65..24c151ad2e62 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -5804,13 +5804,15 @@ static int check_ptr_to_btf_access(struct bpf_verifier_env *env, * program allocated objects (which always have id > 0), * but not for untrusted PTR_TO_BTF_ID | MEM_ALLOC. */ - if (atype != BPF_READ && !type_is_ptr_alloc_obj(reg->type)) { + if (atype != BPF_READ && + (!type_is_ptr_alloc_obj(reg->type) || reg->type & PTR_UNTRUSTED)) { verbose(env, "only read is supported\n"); return -EACCES; } if (type_is_alloc(reg->type) && !type_is_non_owning_ref(reg->type) && - !(reg->type & MEM_RCU) && !reg_is_referenced(env, reg)) { + !(reg->type & (MEM_RCU | PTR_UNTRUSTED)) && + !reg_is_referenced(env, reg)) { verifier_bug(env, "allocated object must have a referenced id"); return -EFAULT; } diff --git a/tools/testing/selftests/bpf/progs/local_kptr_stash_fail.c b/tools/testing/selftests/bpf/progs/local_kptr_stash_fail.c index fcf7a7567da2..d7b8cd6458bb 100644 --- a/tools/testing/selftests/bpf/progs/local_kptr_stash_fail.c +++ b/tools/testing/selftests/bpf/progs/local_kptr_stash_fail.c @@ -8,14 +8,22 @@ #include "../bpf_experimental.h" #include "bpf_misc.h" +extern void bpf_rcu_read_lock(void) __ksym; +extern void bpf_rcu_read_unlock(void) __ksym; + struct node_data { long key; long data; struct bpf_rb_node node; }; +struct plain_data { + long key; +}; + struct map_value { struct node_data __kptr *node; + struct plain_data __kptr *plain; }; struct node_data2 { @@ -31,6 +39,7 @@ struct node_data2 { * [35] TYPE_TAG 'kptr_ref' type_id=34 */ struct node_data *just_here_because_btf_bug; +struct plain_data *just_here_because_btf_bug2; struct { __uint(type, BPF_MAP_TYPE_ARRAY); @@ -82,4 +91,53 @@ long drop_rb_node_off(void *ctx) return 0; } +SEC("?tc") +__failure __msg("only read is supported") +long write_untrusted_alloc_obj(void *ctx) +{ + struct map_value *mapval; + struct node_data *res; + int idx = 0; + + mapval = bpf_map_lookup_elem(&some_nodes, &idx); + if (!mapval) + return 1; + + bpf_rcu_read_lock(); + res = mapval->node; + if (!res) { + bpf_rcu_read_unlock(); + return 2; + } + barrier_var(res); + bpf_rcu_read_unlock(); + + res->key = 42; + return 0; +} + +SEC("?tc") +__success +long read_untrusted_alloc_obj(void *ctx) +{ + struct map_value *mapval; + struct plain_data *res; + int idx = 0; + + mapval = bpf_map_lookup_elem(&some_nodes, &idx); + if (!mapval) + return 1; + + bpf_rcu_read_lock(); + res = mapval->plain; + if (!res) { + bpf_rcu_read_unlock(); + return 2; + } + barrier_var(res); + bpf_rcu_read_unlock(); + + return res->key; +} + char _license[] SEC("license") = "GPL"; -- 2.43.0