From patchwork Sat Nov 18 03:46:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrii Nakryiko X-Patchwork-Id: 13459859 X-Patchwork-Delegate: bpf@iogearbox.net Authentication-Results: smtp.subspace.kernel.org; dkim=none Received: from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com [67.231.145.42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 31D76D72 for ; Fri, 17 Nov 2023 19:47:03 -0800 (PST) Received: from pps.filterd (m0044012.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 3AI2rE6d003777 for ; Fri, 17 Nov 2023 19:47:03 -0800 Received: from mail.thefacebook.com ([163.114.132.120]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3uemvd856w-9 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Fri, 17 Nov 2023 19:47:02 -0800 Received: from twshared44805.48.prn1.facebook.com (2620:10d:c085:208::11) by mail.thefacebook.com (2620:10d:c085:21d::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.34; Fri, 17 Nov 2023 19:46:57 -0800 Received: by devbig019.vll3.facebook.com (Postfix, from userid 137359) id 5F0DA3BB30014; Fri, 17 Nov 2023 19:46:51 -0800 (PST) From: Andrii Nakryiko To: , , , CC: , , Eduard Zingerman , Stanislav Fomichev Subject: [PATCH v3 bpf-next 8/8] bpf: emit frameno for PTR_TO_STACK regs if it differs from current one Date: Fri, 17 Nov 2023 19:46:23 -0800 Message-ID: <20231118034623.3320920-9-andrii@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231118034623.3320920-1-andrii@kernel.org> References: <20231118034623.3320920-1-andrii@kernel.org> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-GUID: YHBHjOOZLnlZX8TZXuGhh_qAvzDavZQE X-Proofpoint-ORIG-GUID: YHBHjOOZLnlZX8TZXuGhh_qAvzDavZQE X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.987,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-11-18_01,2023-11-17_01,2023-05-22_02 X-Patchwork-Delegate: bpf@iogearbox.net It's possible to pass a pointer to parent's stack to child subprogs. In such case verifier state output is ambiguous not showing whether register container a pointer to "current" stack, belonging to current subprog (frame), or it's actually a pointer to one of parent frames. So emit this information if frame number differs between the state which register is part of. E.g., if current state is in frame 2 and it has a register pointing to stack in grand parent state (frame #0), we'll see something like 'R1=fp[0]-16', while "local stack pointer" will be just 'R2=fp-16'. Acked-by: Eduard Zingerman Acked-by: Stanislav Fomichev Signed-off-by: Andrii Nakryiko --- kernel/bpf/log.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/kernel/bpf/log.c b/kernel/bpf/log.c index 87105aa482ed..3505f3e5ae96 100644 --- a/kernel/bpf/log.c +++ b/kernel/bpf/log.c @@ -615,7 +615,9 @@ static bool type_is_map_ptr(enum bpf_reg_type t) { } } -static void print_reg_state(struct bpf_verifier_env *env, const struct bpf_reg_state *reg) +static void print_reg_state(struct bpf_verifier_env *env, + const struct bpf_func_state *state, + const struct bpf_reg_state *reg) { enum bpf_reg_type t; const char *sep = ""; @@ -623,10 +625,8 @@ static void print_reg_state(struct bpf_verifier_env *env, const struct bpf_reg_s t = reg->type; if (t == SCALAR_VALUE && reg->precise) verbose(env, "P"); - if ((t == SCALAR_VALUE || t == PTR_TO_STACK) && - tnum_is_const(reg->var_off)) { + if (t == SCALAR_VALUE && tnum_is_const(reg->var_off)) { /* reg->off should be 0 for SCALAR_VALUE */ - verbose(env, "%s", t == SCALAR_VALUE ? "" : reg_type_str(env, t)); verbose_snum(env, reg->var_off.value + reg->off); return; } @@ -637,6 +637,14 @@ static void print_reg_state(struct bpf_verifier_env *env, const struct bpf_reg_s #define verbose_a(fmt, ...) ({ verbose(env, "%s" fmt, sep, ##__VA_ARGS__); sep = ","; }) verbose(env, "%s", reg_type_str(env, t)); + if (t == PTR_TO_STACK) { + if (state->frameno != reg->frameno) + verbose(env, "[%d]", reg->frameno); + if (tnum_is_const(reg->var_off)) { + verbose_snum(env, reg->var_off.value + reg->off); + return; + } + } if (base_type(t) == PTR_TO_BTF_ID) verbose(env, "%s", btf_type_name(reg->btf, reg->btf_id)); verbose(env, "("); @@ -698,7 +706,7 @@ void print_verifier_state(struct bpf_verifier_env *env, const struct bpf_func_st verbose(env, " R%d", i); print_liveness(env, reg->live); verbose(env, "="); - print_reg_state(env, reg); + print_reg_state(env, state, reg); } for (i = 0; i < state->allocated_stack / BPF_REG_SIZE; i++) { char types_buf[BPF_REG_SIZE + 1]; @@ -731,7 +739,7 @@ void print_verifier_state(struct bpf_verifier_env *env, const struct bpf_func_st verbose(env, " fp%d", (-i - 1) * BPF_REG_SIZE); print_liveness(env, reg->live); verbose(env, "=%s", types_buf); - print_reg_state(env, reg); + print_reg_state(env, state, reg); break; case STACK_DYNPTR: /* skip to main dynptr slot */