From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=74.125.82.54 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1792569674; b=dJln/4A+Iv+1RAGZ9JmOSLWE1pMhNRVeYQl9qfXkUPluStCeT13o6UqXH1c+qFtRUnhn W04wD/9TjT+vLFpEuCv3qWNxCQwEjjn9ijiMwVE7KnZQT/NMrUbuD08Xu5+LjDA8T3FIy JmEQzSvEpUWq8j/hJDiVnfoyBS5W2YO5UyE400wCV8p3L+q3k9B8LAUsNvphvB8KIdj28 6iczOTl6jwJee6vSvuAMbKeOgCWylcYqPuLuYalef+8TloIXryrbf1tqzU2QN9IPXmXCC ZJULxUXGGa/Ug1wY+RPXjXTD0C1XvzWrXzdIoWbRvRx7blvRCynWj1t7bZsjFZ1fvkw== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1792569674; h=DMARC-Filter:Received:DKIM-Signature:X-Google-DKIM-Signature: X-Gm-Message-State:X-Gm-Gg:X-Received:Received:From:To:Cc:Subject: Date:Message-ID:X-Mailer:MIME-Version:Content-Transfer-Encoding; bh=PiI4cMavYXtb8vt/MajCrhWPebqVcKLkNr8147+y6WU=; b=BKvbZXtYa5vPJWZmZIww1Lumhfu4l75pwJpQr+SXQCry/pZpRf+3p3qkYLg4Of/iXSZV b6WmHwmPT0IWdBkLc++XDq14q6/RhgOJM814VmK0cTJYIB817SUO+JESWb3g0/Dd4wm4z 7qdg/soViP/DBgZPUBRUohxBi5nG8c98sFQmUegGWcyQpNDr9msdilqG5y6FxMVZvl1gi Z3vQfbjUE5I0Ckp0yw7KK/4psqK+G8PlMuB9wb8KiudFADcHlYmrUHbct6jA0e/N2wmIt vAkHCXkUFFckmirntoOj4+lZ7QMzdgAyuUo20U2h7UbMU+cEf8F13BWouK19e/9/98Q== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=beu0BXXQ; arc=none smtp.remote-ip=74.125.82.54 Received: from mail-dl1-f54.google.com (mail-dl1-f54.google.com [74.125.82.54]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 40C4A606A320 for ; Wed, 21 Oct 2026 08:01:14 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org 40C4A606A320 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, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=beu0BXXQ Received: by mail-dl1-f54.google.com with SMTP id a92af1059eb24-15943c9c005so542361c88.1 for ; Wed, 21 Oct 2026 01:01:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1792569673; x=1793174473; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=PiI4cMavYXtb8vt/MajCrhWPebqVcKLkNr8147+y6WU=; b=beu0BXXQNA4InNFt82BaFOJL7zjfNzYGRue65Lszr5n1WGFG30rIq1M+HQKabuKkU7 WSGmDMMMCbDASNd576d4BDkYI/1wp6mgI/GmHyILQKHOSInIEZ1qkcYS0t9hULGA+kn4 jJoOCAhS6O9mMs8W39ak8jOyiwaM8xvuuz/XFO4h/fHkykK3R3oP0lnsMN7QbzJJ+7Nt pZ1Ebg3bWHyPBJcfET7k48n8OnHw4wWjxUjiJKiA2d9nOVooBcUAkN6zawPdFd79CJYE 1LCplnCxiXImwEi+W866dU/4WYnve+jSyw5TAMWa3ZSZGLM1vXr6YUZm0Hcdr9dR9PpO XT5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1792569673; x=1793174473; h=content-transfer-encoding:mime-version: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=PiI4cMavYXtb8vt/MajCrhWPebqVcKLkNr8147+y6WU=; b=Ujj/TsQMzZ/JPJkURo2RcZs6K53/+IwAGu10y/GK41BmYg71OFE8KbxZdtz4pPhrSE 4UusTT62exYoAaPan3xMSwVWQHPMLc4Q36OOUUOqCFvgQdweGguT+WZLgKDaILmNv2LZ ok2OCtIMyJeoN8TmG3VnBbj7fkxLsaFzxzwYdBTscO50g7JwIbA97lhnKLUskGOxC8EF F2DZp36BeKetcytGQPiftPm3Hj2LytnmooiLz9Wk0rPP0fcLhI9wN3nuRb2wjmorYqsu GSowG3XOcs2HhfdRRokzwKAtd94ZLWsUcvDhcvLddrk/QnQgMFUPuCh41vvyZocYT93V 9h8A== X-Gm-Message-State: AFq9FYIIngiayg9RGxbsWlq0vKbgDP/l3VclQdW/MzhJ4IWyOIQMGFv5 khCAQJaunGNErgrjH+C8o9gFXdfTNuFSSre2b1GMA1aX7BUWbS9irkps X-Gm-Gg: AYBFou2LOLtoNO7DY5WnASCJdznE655QRX6Hy0iMA0pajqrAAJcsoVoYymsPrV6lAAk YXEccP+0akMJbWO6CmtAFbPmSJlcjrZilsy5F7ydFZdqAXuCu8O5d5jKM+TUXEoRQ7RUaR/Sb/x OlQQrrTUVFPofqzTKDhICW8n07HKQJAJAhLFjGuOQ2P0VRdabKGcYNuKns2dTG6hh+CNfma4ndt WAlFQc/cum7uP/ywM9WFGA0Lm4Au7a8VeDOVhY3G2C9mIRbNOuMN6XiK9dr25IUPaMTthHsIFtx D3avqFagLiwIgM3QTAEyvPOGqkQ60KHCTqV4hJ+j5TvXWDF9nLCFFNktxiEYVC9k6IY/u8P324J 36kg5CPOfCfCh2dTScBqLvjjwjhCb1goqzKumOSM57TEnA+WP7By0K29rQgHZYy693FRx50Bo5y r9m1JYtm6j/y6ClhgrM8prFg+ory0QXCh+eOn9kbLAtcC8Ci9Q5usM30GKQQvi+1mw+3q35Hy2r MtCE/YXjKwRLuca1OKH2UR6SKiOUMWYhfI2DZa+3DlIyqM5u3k2tKpMnRVoXqjLo28tON0F+Wl1 yFVW7qfV1zu8x9VEwVGp3NMl0xrV X-Received: by 2002:a05:7022:e1d:b0:141:4c37:a212 with SMTP id a92af1059eb24-190a051dd9amr2581121c88.2.1792569672784; Wed, 21 Oct 2026 01:01:12 -0700 (PDT) Received: from Terra.tail0ac356.ts.net ([198.176.50.208]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-367416a1fb9sm4470610eec.20.2026.10.21.01.01.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 Oct 2026 01:01:11 -0700 (PDT) From: Weiming Shi To: Alexei Starovoitov , Daniel Borkmann , John Fastabend , Andrii Nakryiko , Martin KaFai Lau , Eduard Zingerman , Kumar Kartikeya Dwivedi , Song Liu , Yonghong Song , Jiri Olsa , Shuah Khan Cc: bpf@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, co+eada64ce90ecebce@bugs.sh, Xiang Mei , Weiming Shi , Alexei Starovoitov Subject: [PATCH bpf v2 1/2] bpf: Validate stack arg reads against caller state Date: Wed, 21 Oct 2026 01:00:59 -0700 Message-ID: <20261021080100.2663618-1-bestswngs@gmail.com> X-Mailer: git-send-email 2.56.0 X-Mailing-List: bpf@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit check_stack_arg_read() bounds a stack argument index with the callee's BTF-derived argument count, then uses the index in the caller's stack_arg_regs[] array. The array's actual logical length is recorded in caller->out_stack_arg_cnt, so the bound and indexed object can diverge. A crafted BPF_PROG_LOAD can use an argument mismatch to mark a static subprogram's BTF information unreliable. Later calls return from btf_check_subprog_call() before check_outgoing_stack_args(), while check_func_call() continues the static call on -EINVAL. The callee can then read a slot that the caller never allocated or initialized. The earlier commit 4286f5deee14 ("bpf: Validate outgoing stack args when btf_prepare_func_args fails") closed this hole for the first call, but not for later calls after the subprogram has been marked unreliable. Callbacks have a related problem. The verifier can make incoming stack arguments readable from outgoing slots at the helper call site. However, helpers and kfuncs invoke callbacks through an ABI that passes at most five arguments, so the runtime callback receives no stack arguments. Async callback verification can also reach check_stack_arg_read() without a caller frame. On x86-64, KASAN reports the direct-call out-of-bounds copy as: BUG: KASAN: slab-out-of-bounds in check_load_mem+0xb51/0xc60 Read of size 80 at addr ffff8881009af550 by task poc/131 Call Trace: check_stack_arg_read at kernel/bpf/verifier.c:4234 (inlined by) check_load_mem at kernel/bpf/verifier.c:6645 do_check_common at kernel/bpf/verifier.c:19568 bpf_check at kernel/bpf/verifier.c:21318 bpf_prog_load at kernel/bpf/syscall.c:3134 Reject callback subprograms with incoming stack arguments before their state is pushed. For direct calls, retrieve the slot with bpf_get_spilled_stack_arg(), which validates the index against the caller's out_stack_arg_cnt and rejects uninitialized slots before copying the register state. Fixes: 0f6bd5e7a804 ("bpf: Support stack arguments for bpf functions") Reported-by: Suggested-by: Alexei Starovoitov Assisted-by: LLM Signed-off-by: Weiming Shi --- Changes in v2: - Reject callback subprograms that declare stack arguments. - Drop the curframe-zero check because only async callbacks can reach that state, and callbacks with stack arguments are now rejected earlier. - Explain that commit 4286f5deee14 closed the hole for the first call only. kernel/bpf/verifier.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 72a3f5998dd27f..f461e9e5d19da5 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -4228,7 +4228,12 @@ static int check_stack_arg_read(struct bpf_verifier_env *env, struct bpf_func_st } caller = vstate->frame[vstate->curframe - 1]; - arg = &caller->stack_arg_regs[spi]; + arg = bpf_get_spilled_stack_arg(spi, caller); + if (!arg) { + verbose(env, "invalid read from uninitialized stack arg off %d\n", off); + return -EACCES; + } + cur = vstate->frame[vstate->curframe]; bpf_diag_mod_begin(env, &cur->regs[dst_regno], arg, BPF_DIAG_MOD_WRITE); cur->regs[dst_regno] = *arg; @@ -9839,6 +9844,10 @@ static int push_callback_call(struct bpf_verifier_env *env, struct bpf_insn *ins err = btf_check_subprog_call(env, subprog, caller->regs); if (err == -EFAULT) return err; + if (bpf_in_stack_arg_cnt(&env->subprog_info[subprog])) { + verbose(env, "callback subprog cannot have stack args\n"); + return -EINVAL; + } /* set_callee_state is used for direct subprog calls, but we are * interested in validating only BPF helpers that can call subprogs as -- 2.56.0