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 BC9B5403B0A for ; Tue, 14 Jul 2026 09:39:10 +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=1784021952; cv=none; b=G3Bdu9KO7NGhQtDBZdv9ijiT3cv4g2/UkO4Gj7AqixdPjwhqFLAayWVKhBbmmEDoutOdRpzHMGiMi/BYASddq7IW6fmpDZ5P7Bc0xodXI0VX1pm1s1H16osZl2wSkdM/kMUckKaltWqroNgbJHcbZuga8Qe7Yp91LQ2S8E4zVE8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784021952; c=relaxed/simple; bh=mfnEbSScsujRwoxasSxyWdhvlmzfSWWEe+mMVO63fwg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Tu5lIysYxW3ChiLTxCO2RZQ0KkhcoA+thVx/yJaFt3t6k5jVmdWCgfDrq+cgl7rdFkzttpvxvzBAQzWJCA1/1JT4CYCokosAwN7LJIPQAHvJ4xeu2fzTEW0D22uWM+8iAwVwJKRDyiNNYy/xMYgnNnH+owWxY48dfUabUG7UF2w= 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=Ajw33idr; 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="Ajw33idr" Received: by mail-qt1-f181.google.com with SMTP id d75a77b69052e-51c149c5722so6337601cf.0 for ; Tue, 14 Jul 2026 02:39:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1784021950; x=1784626750; 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=wL+dQXVVG1jrwdjXyQWY9fUn4W24MWcB/WCkDuLFzik=; b=Ajw33idrKx2wBknLRObepsEF2PyiQ5p/GpEFEudsDvoqMAiujy5gWefUB/St074/X5 9rF0RzZy2qCl3dlktddBqoI0e0kSXOPtrEVLuaNQef+p48ZMm+Xm3MFN+bnzsZcrbUXu EQFPC2uE5kotDPwJOmjPM3ieuaHpW198N9d4YM+59/JgRBVtShihMyMq033aMDBAX/0a pFobB7xmEetSo2Eb6iUkfLMkXyzF4tSCejdJXhEWGqvVGpLhXcqwZstXvhIJcIRelAK8 9kdVdYq0aa/QQNX1Bw2fI+rcTbnf/WenW30eRlQcqgPJWvhDeTS2cniXfepkKsj4U8EY G0+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784021950; x=1784626750; 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=wL+dQXVVG1jrwdjXyQWY9fUn4W24MWcB/WCkDuLFzik=; b=cliGnb9CjNK1Lc0oSXG/MuDGtoqFVQ5tpUYt5COJ4dqT3etsMpByEDSysgZeMRuN4t svq614y+YQNx3Sd16414PixBmCyu+aHZn73l0tAfkI5jdUKFjnIDj81ko8KwIiz0xHY3 wKyLW98p30ep8xCZlE7Pmzl7n5FLWqsMGR6Tw9cogAKyzRKca7adxTj9WJlKS6/X4xam eXh3j3ze9DFdcHgJhz3bWNk17KQNVUvB+z+4v+Qq5ueyqQOkPuhKVM4B5bqhO+45fIf6 khAuZElENI8Hkhja7O0sDYUk5KxWqQUjmDAYxgm1sLkhIZQ2icgnU5JbKPpiQ99PsDkl Z+HA== X-Forwarded-Encrypted: i=1; AHgh+RqjS5qsMvlhekXvd4nLSK+g1eE+9P4d4KEx5uj0OXB5JNqbUa3nHMiZPlw9E/mSWvBllGRrRg0be8/xrmM=@vger.kernel.org X-Gm-Message-State: AOJu0YzrfeSoI28dzQkgSIm2cKmkIfgQyngf/Pdu55KuCdddiM8g9cl1 +FTy+Jq9Ml4hAmLjCZ+XnhZfzFG578bALZkuP7IbrssNbhM3GMq+y97W X-Gm-Gg: AfdE7cmrFUh4bt8G+hu1maF4Us5W/4Kpel9f1iRqOWEiZ5DFaPcpqos5l2oMxavm9Cf g9+lDoRuVoVgOt7Luat2U3pRyTZub0R4UC7BIdrDS28eCtf0lSEYwfGmnAYlZikec6U2Ni7BSDe rfkH1Q3I98Kjg2HGAp8gKWkmhdR19xqaq9G5dnh6fKkgeSkinYORQU5BTAOXxj81lLUPOTylrHr ml8nnGVwwQXSWCXoWdeRia1tGV3D5/j8EWk1TdwlcnsvMm7Ghch2TPuvliZDvA0j+733/NoXBiW JQxKA061kDPFktVHX2y0BAMjDlI1dlVhEa52akntxzE7x2zAmiYf87OxQCaneecfIFmH+FUWQCm /67/sw0Fn/mND3jufht4jzOZlBo6bmq7CFIzM1g2wHsXdBqKxLAmFSgjPy/ZjhFYSW2eW4Op9QG p3Mbrl28tzdV62KJK5nzccL8dgA1f2Q+wcOQBddYj7Tf19LpmzOfSjdhyRy7iS7/IYfGt20PXH X-Received: by 2002:a05:622a:1e07:b0:51c:4f35:81b8 with SMTP id d75a77b69052e-51cbf73e524mr120889981cf.7.1784021949680; Tue, 14 Jul 2026 02:39:09 -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.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Jul 2026 02:39:09 -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 1/2] bpf: Reject negative const offsets for buffer pointers Date: Tue, 14 Jul 2026 02:38:45 -0700 Message-ID: <20260714093846.18159-2-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 The verifier rejects variable offsets for PTR_TO_TP_BUFFER and PTR_TO_BUF accesses, but it currently accepts a constant negative offset produced by pointer arithmetic. Commit 022ac0750883 ("bpf: use reg->var_off instead of reg->off for pointers") moved constant pointer offsets from reg->off to reg->var_off. However, __check_buffer_access() continued to check only the instruction offset. An access with reg->var_off equal to -8 and an instruction offset of zero therefore passes verification. For writable raw tracepoints, the access end is also calculated from the unsigned reg->var_off.value. An eight-byte access starting at -8 wraps the calculated end to zero, allowing the program to load and attach without increasing max_tp_access. After ensuring that reg->var_off is constant, calculate the effective access start using signed arithmetic and reject it when it is negative. Use the validated start to calculate the access end for both PTR_TO_TP_BUFFER and PTR_TO_BUF. Fixes: 022ac0750883 ("bpf: use reg->var_off instead of reg->off for pointers") Acked-by: Shung-Hsi Yu Cc: stable@vger.kernel.org # 5.2.0 Signed-off-by: Sun Jian --- kernel/bpf/verifier.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 6515d4d3c003..9f1333676365 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -5326,14 +5326,11 @@ static int check_max_stack_depth(struct bpf_verifier_env *env) static int __check_buffer_access(struct bpf_verifier_env *env, const char *buf_info, const struct bpf_reg_state *reg, - argno_t argno, int off, int size) + argno_t argno, int off, int size, + u32 *access_end) { - if (off < 0) { - verbose(env, - "%s invalid %s buffer access: off=%d, size=%d\n", - reg_arg_name(env, argno), buf_info, off, size); - return -EACCES; - } + s64 start; + if (!tnum_is_const(reg->var_off)) { char tn_buf[48]; @@ -5344,6 +5341,15 @@ static int __check_buffer_access(struct bpf_verifier_env *env, return -EACCES; } + start = (s64)reg->var_off.value + off; + if (start < 0) { + verbose(env, + "%s invalid negative %s buffer offset: off=%d, var_off=%lld\n", + reg_arg_name(env, argno), buf_info, off, (s64)reg->var_off.value); + return -EACCES; + } + + *access_end = start + size; return 0; } @@ -5351,14 +5357,14 @@ static int check_tp_buffer_access(struct bpf_verifier_env *env, const struct bpf_reg_state *reg, argno_t argno, int off, int size) { + u32 access_end; int err; - err = __check_buffer_access(env, "tracepoint", reg, argno, off, size); + err = __check_buffer_access(env, "tracepoint", reg, argno, off, size, &access_end); if (err) return err; - env->prog->aux->max_tp_access = max(reg->var_off.value + off + size, - env->prog->aux->max_tp_access); + env->prog->aux->max_tp_access = max(access_end, env->prog->aux->max_tp_access); return 0; } @@ -5370,13 +5376,14 @@ static int check_buffer_access(struct bpf_verifier_env *env, u32 *max_access) { const char *buf_info = type_is_rdonly_mem(reg->type) ? "rdonly" : "rdwr"; + u32 access_end; int err; - err = __check_buffer_access(env, buf_info, reg, argno, off, size); + err = __check_buffer_access(env, buf_info, reg, argno, off, size, &access_end); if (err) return err; - *max_access = max(reg->var_off.value + off + size, *max_access); + *max_access = max(access_end, *max_access); return 0; } -- 2.43.0