From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from out-181.mta0.migadu.com (out-181.mta0.migadu.com [91.218.175.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 43A6237F740 for ; Wed, 14 Jan 2026 08:49:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.181 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768380546; cv=none; b=ru9CqWMyl95lwIl0TRhWHnj9jiAK+qgoAmEfjzbTjlblvrq8yxhpxFzoKN2WvY14McIQ5RE2mI4vyh04i40i5t+WX9ZOmEueFwPPX7uvSj9keQ+zN1a7zvPyaFFogrJ17GHG8h0LIJ6wR/Yf1kgtnH4cmVST9g9AySMYfWhtiSQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768380546; c=relaxed/simple; bh=m7WlSDjsJR23TNHdC8y0tLHb4b6D1xumCWxXi1BM0Eo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=n77aJlh+y9Ut+beAJwbA+RAsVCoEERbUkYtrFaJGK7i4rkVm8ubnvKLbpoZd4EelwNvDSrC5LPZieNE9Zp0ToSFr8n4XERfg3uyW11TNnxLkuaNRa7zmuRuGXHegW5LQ0evSWOx0O/GQm1+9RU/7RrvQYVbke0WYe/MR+ybIQRs= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=R7jHi1BQ; arc=none smtp.client-ip=91.218.175.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="R7jHi1BQ" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1768380530; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=xFOvYS/MwLIoa2ddKtSerXnnDZ6P+P0QxZA10mD8sGk=; b=R7jHi1BQHrpYXKbkhrJYyhW/15yWOtqM8To4dfUn4yXQHUs64cj6n7K4oLF+s+q/e/b2zQ MMwFcGvtGx6VckfAj0b1UI+Klr5FEB5HNg1sG1un4yovX71Aqyh9uF+H5gkLyh36c/3nfa AfW3oYFB22Sk3Brat2A11k7mAGushXI= From: Menglong Dong To: Andrii Nakryiko Cc: Andrii Nakryiko , bpf@vger.kernel.org, netdev@vger.kernel.org, ast@fb.com, daniel@iogearbox.net, kernel-team@fb.com Subject: Re: [PATCH bpf-next 3/9] libbpf: improve relocation ambiguity detection Date: Wed, 14 Jan 2026 16:48:39 +0800 Message-ID: <4682258.8F6SAcFxjW@7940hx> In-Reply-To: References: <20200818223921.2911963-1-andriin@fb.com> <2249675.irdbgypaU6@7940hx> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" X-Migadu-Flow: FLOW_OUT On 2026/1/14 07:26 Andrii Nakryiko write: > On Mon, Jan 12, 2026 at 11:36=E2=80=AFPM Menglong Dong wrote: > > > > On 2020/8/19 06:39 Andrii Nakryiko write: > > > Split the instruction patching logic into relocation value calculatio= n and > > > application of relocation to instruction. Using this, evaluate reloca= tion > > > against each matching candidate and validate that all candidates agre= e on > > > relocated value. If not, report ambiguity and fail load. > > > > > > This logic is necessary to avoid dangerous (however unlikely) acciden= tal match > > > against two incompatible candidate types. Without this change, libbpf= will > > > pick a random type as *the* candidate and apply potentially invalid > > > relocation. > > > > > > Signed-off-by: Andrii Nakryiko > > > --- > > > tools/lib/bpf/libbpf.c | 170 ++++++++++++++++++++++++++++++---------= =2D- > > > 1 file changed, 124 insertions(+), 46 deletions(-) > > > > > > diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c > > > index 2047e4ed0076..1ba458140f50 100644 > > > --- a/tools/lib/bpf/libbpf.c > > [......] > > > @@ -5005,16 +5063,31 @@ static int bpf_core_reloc_field(struct bpf_pr= ogram *prog, > > > if (err =3D=3D 0) > > > continue; > > > > > > + err =3D bpf_core_calc_relo(prog, relo, relo_idx, &local= _spec, &cand_spec, &cand_res); > > > + if (err) > > > + return err; > > > + > > > if (j =3D=3D 0) { > > > + targ_res =3D cand_res; > > > targ_spec =3D cand_spec; > > > } else if (cand_spec.bit_offset !=3D targ_spec.bit_offs= et) { > > > - /* if there are many candidates, they should all > > > - * resolve to the same bit offset > > > + /* if there are many field relo candidates, they > > > + * should all resolve to the same bit offset > > > */ > > > - pr_warn("prog '%s': relo #%d: offset ambiguity:= %u !=3D %u\n", > > > + pr_warn("prog '%s': relo #%d: field offset ambi= guity: %u !=3D %u\n", > > > prog_name, relo_idx, cand_spec.bit_offs= et, > > > targ_spec.bit_offset); > > > return -EINVAL; > > > + } else if (cand_res.poison !=3D targ_res.poison || cand= _res.new_val !=3D targ_res.new_val) { > > > + /* all candidates should result in the same rel= ocation > > > + * decision and value, otherwise it's dangerous= to > > > + * proceed due to ambiguity > > > + */ > > > + pr_warn("prog '%s': relo #%d: relocation decisi= on ambiguity: %s %u !=3D %s %u\n", > > > + prog_name, relo_idx, > > > + cand_res.poison ? "failure" : "success"= , cand_res.new_val, > > > + targ_res.poison ? "failure" : "success"= , targ_res.new_val); > > > + return -EINVAL; > > > } > > > > Hi, Andrii. This approach is not friend to bpf_core_cast() if the struct > > is not used in the vmlinux, but the kernel modules. > > > > Take "struct nft_chain" for example. Following code will fail: > > struct nft_chain *chain =3D bpf_core_cast(ptr, struct nft_chain). > > > > The bpf_core_cast() will record a BPF_CORE_TYPE_ID_TARGET relocation > > for "struct nft_chain". The libbpf will find multi btf type of nft_chain > > in the modules nf_tables, nft_reject, etc, and it will fail the verific= ation > > due to the "new_val", which is btf type id, not the same, even if all > > the "struct nft_chain" are exactly the same in different kernel modules. > > > > I think this is a common case. So how about we check the consistence of > > struct nft_chain in all the candidate list, and use the first one if al= l of > > them have exactly the same definition? >=20 > BTF type ID for some type in some kernel is not meaningful without > also capturing module's BTF ID or FD, so we'd be just capturing some > relatively random and meaningless type ID. >=20 > I'm actually not sure bpf_core_cast() can work with BTF types defined > in module's BTF. Can you please check what we do if we have > non-ambiguous BTF type defined only in module's BTF? You are right. I got the following error when I use bpf_core_cast() for the struct that in kernel module: Unknown type ID 142301 passed to kfunc bpf_rdonly_cast It seems that I didn't realize the kernel side. The module's BTF ID or FD for the struct is unknown for the kernel, and it will only lookup it in the btf that the kfunc belongs to. >=20 > > > > We can check all the members in the struct iteratively, and make > > sure they are all the same. > > >=20 > It's not even clear what "same" would mean here, btw. None of the > issues you bring up are easy to solve :) Yeah, thing is much more complex than I thought. I think I'd better use bpf_probe_kernel_read() for such case ;) Thanks! Menglong Dong >=20 > > Thanks! > > Menglong Dong > > > > > > > > cand_ids->data[j++] =3D cand_spec.spec[0].type_id; > > > @@ -5042,13 +5115,18 @@ static int bpf_core_reloc_field(struct bpf_pr= ogram *prog, > > > * verifier. If it was an error, then verifier will complain an= d point > > > * to a specific instruction number in its log. > > > */ > > > - if (j =3D=3D 0) > > > + if (j =3D=3D 0) { > > > pr_debug("prog '%s': relo #%d: no matching targets foun= d\n", > > > prog_name, relo_idx); > > > > > > - /* bpf_core_reloc_insn should know how to handle missing targ_s= pec */ > > > - err =3D bpf_core_reloc_insn(prog, relo, relo_idx, &local_spec, > > > - j ? &targ_spec : NULL); > > > + /* calculate single target relo result explicitly */ > > > + err =3D bpf_core_calc_relo(prog, relo, relo_idx, &local= _spec, NULL, &targ_res); > > > + if (err) > > > + return err; > > > + } > > > + > > > + /* bpf_core_patch_insn() should know how to handle missing targ= _spec */ > > > + err =3D bpf_core_patch_insn(prog, relo, relo_idx, &targ_res); > > > if (err) { > > > pr_warn("prog '%s': relo #%d: failed to patch insn at o= ffset %d: %d\n", > > > prog_name, relo_idx, relo->insn_off, err); > > > -- > > > 2.24.1 > > > > > > > > > > > > > >