lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250731092953.2d8eea47@gandalf.local.home>
Date: Thu, 31 Jul 2025 09:29:53 -0400
From: Steven Rostedt <rostedt@...dmis.org>
To: Douglas Raillard <douglas.raillard@....com>
Cc: LKML <linux-kernel@...r.kernel.org>, Linux trace kernel
 <linux-trace-kernel@...r.kernel.org>, bpf@...r.kernel.org, Masami Hiramatsu
 <mhiramat@...nel.org>, Mathieu Desnoyers <mathieu.desnoyers@...icios.com>,
 Mark Rutland <mark.rutland@....com>, Peter Zijlstra <peterz@...radead.org>,
 Namhyung Kim <namhyung@...nel.org>, Takaya Saeki <takayas@...gle.com>, Tom
 Zanussi <zanussi@...nel.org>, Andrew Morton <akpm@...ux-foundation.org>,
 Thomas Gleixner <tglx@...utronix.de>, Ian Rogers <irogers@...gle.com>,
 aahringo@...hat.com
Subject: Re: [PATCH] tracing/probes: Allow use of BTF names to dereference
 pointers

On Thu, 31 Jul 2025 12:44:49 +0100
Douglas Raillard <douglas.raillard@....com> wrote:

> > The delimiter is '.' and the first item is the structure name. Then the
> > member of the structure to get the offset of. If that member is an
> > embedded structure, another '.MEMBER' may be added to get the offset of
> > its members with respect to the original value.
> > 
> >    "+kmem_cache.size($arg1)" is equivalent to:
> > 
> >    (*(struct kmem_cache *)$arg1).size
> > 
> > Anonymous structures are also handled:
> > 
> >    # echo 'e:xmit net.net_dev_xmit +net_device.name(+sk_buff.dev($skbaddr)):string' >> dynamic_events  
> 
> Not sure how hard that would be but the type of the expression could probably be inferred from
> BTF as well in some cases. Some cases may be ambiguous (like char* that could be either a buffer
> to display as hex or a null-terminated ASCII string) but BTF would still allow to restrict
> to something sensible (e.g. prevent u32 for a char*).

Hmm, should be possible, but would require passing that information back to
the caller of the BTF lookup function.



> > diff --git a/kernel/trace/trace_btf.c b/kernel/trace/trace_btf.c
> > index 5bbdbcbbde3c..b69404451410 100644
> > --- a/kernel/trace/trace_btf.c
> > +++ b/kernel/trace/trace_btf.c
> > @@ -120,3 +120,109 @@ const struct btf_member *btf_find_struct_member(struct btf *btf,
> >   	return member;
> >   }
> >   
> > +#define BITS_ROUNDDOWN_BYTES(bits) ((bits) >> 3)
> > +
> > +static int find_member(const char *ptr, struct btf *btf,
> > +		       const struct btf_type **type, int level)
> > +{
> > +	const struct btf_member *member;
> > +	const struct btf_type *t = *type;
> > +	int i;
> > +
> > +	/* Max of 3 depth of anonymous structures */
> > +	if (level > 3)
> > +		return -1;
> > +
> > +	for_each_member(i, t, member) {
> > +		const char *tname = btf_name_by_offset(btf, member->name_off);
> > +
> > +		if (strcmp(ptr, tname) == 0) {
> > +			*type = btf_type_by_id(btf, member->type);
> > +			return BITS_ROUNDDOWN_BYTES(member->offset);  
> 
> member->offset does not only contain the offset, and the offset may not be
> a multiple of 8:
> https://elixir.bootlin.com/linux/v6.16/source/include/uapi/linux/btf.h#L126
> 
>  From the BTF spec (https://docs.kernel.org/bpf/btf.html):
> 
> If the kind_flag is set, the btf_member.offset contains
> both member bitfield size and bit offset.
> The bitfield size and bit offset are calculated as below.:
> 
> #define BTF_MEMBER_BITFIELD_SIZE(val)   ((val) >> 24)
> #define BTF_MEMBER_BIT_OFFSET(val)      ((val) & 0xffffff)

So basically just need to change that to:

		if (strcmp(ptr, tname) == 0) {
			int offset = BTF_MEMBER_BIT_OFFSET(member->offset);
			*type = btf_type_by_id(btf, member->type);
			return BITS_ROUNDDOWN_BYTES(offset);

?

> 
> > +		}
> > +
> > +		/* Handle anonymous structures */
> > +		if (strlen(tname))
> > +			continue;
> > +
> > +		*type = btf_type_by_id(btf, member->type);
> > +		if (btf_type_is_struct(*type)) {
> > +			int offset = find_member(ptr, btf, type, level + 1);
> > +
> > +			if (offset < 0)
> > +				continue;
> > +
> > +			return offset + BITS_ROUNDDOWN_BYTES(member->offset);

And here too.

-- Steve

> > +		}
> > +	}
> > +
> > +	return -1;
> > +}
> > +

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ