From: Jiri Olsa <olsajiri@gmail.com>
To: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Cc: Jiri Olsa <olsajiri@gmail.com>,
Juri Lelli <juri.lelli@redhat.com>, bpf <bpf@vger.kernel.org>,
LKML <linux-kernel@vger.kernel.org>,
Artem Savkov <asavkov@redhat.com>
Subject: Re: NULL pointer deref when running BPF monitor program (6.11.0-rc1)
Date: Thu, 8 Aug 2024 12:46:08 +0200 [thread overview]
Message-ID: <ZrSh8AuV21AKHfNg@krava> (raw)
In-Reply-To: <CAADnVQ+NpPtFOrvD0o2F8npCpZwPrLf4dX8h8Rt96uwM+crQcQ@mail.gmail.com>
On Tue, Aug 06, 2024 at 11:44:52AM -0700, Alexei Starovoitov wrote:
> On Tue, Aug 6, 2024 at 6:24 AM Jiri Olsa <olsajiri@gmail.com> wrote:
> >
> > > Jiri,
> > >
> > > the verifier removes the check because it assumes that pointers
> > > passed by the kernel into tracepoint are valid and trusted.
> > > In this case:
> > > trace_sched_pi_setprio(p, pi_task);
> > >
> > > pi_task can be NULL.
> > >
> > > We cannot make all tracepoint pointers to be PTR_TRUSTED | PTR_MAYBE_NULL
> > > by default, since it will break a bunch of progs.
> > > Instead we can annotate this tracepoint arg as __nullable and
> > > teach the verifier to recognize such special arguments of tracepoints.
> >
> > ok, so you mean to be able to mark it in event header like:
> >
> > TRACE_EVENT(sched_pi_setprio,
> > TP_PROTO(struct task_struct *tsk, struct task_struct *pi_task __nullable),
> >
> > I guess we could make pahole to emit DECL_TAG for that argument,
> > but I'm not sure how to propagate that __nullable info to pahole
> >
> > while wondering about that, I tried the direct fix below ;-)
>
> We don't need to rush such a hack below.
> No need to add decl_tag and change pahole either.
> The arg name is already vmlinux BTF:
> [51371] FUNC_PROTO '(anon)' ret_type_id=0 vlen=3
> '__data' type_id=61
> 'tsk' type_id=77
> 'pi_task' type_id=77
> [51372] FUNC '__bpf_trace_sched_pi_setprio' type_id=51371 linkage=static
>
> just need to rename "pi_task" to "pi_task__nullable"
> and teach the verifier.
the problem is that btf_trace_<xxx> is typedef
typedef void (*btf_trace_##call)(void *__data, proto);
and dwarf does not store argument names for subroutine type entry,
so it's not in BTF's TYPEDEF either
it's the btf_trace_##call typedef ID that verifier has to work with,
I wonder we could somehow associate that ID with __bpf_trace_##call
subroutine entry which has the argument names
we could store __bpf_trace_##call's BTF_ID in __bpf_raw_tp_map record,
but we'd need to do the lookup based on the tracepoint name when loading
the program .. ATM we do the lookup __bpf_raw_tp_map record only when
doing attach, so we would need to move it to program load time
or we could 'fix' the argument names in pahole, but that'd probably
mean extra setup and hash lookup, so also not great
jirka
>
>
> > jirka
> >
> >
> > ---
> > diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
> > index 95426d5b634e..1a20bbdead64 100644
> > --- a/kernel/bpf/btf.c
> > +++ b/kernel/bpf/btf.c
> > @@ -6377,6 +6377,25 @@ int btf_ctx_arg_offset(const struct btf *btf, const struct btf_type *func_proto,
> > return off;
> > }
> >
> > +static bool is_tracing_prog_raw_tp(const struct bpf_prog *prog, const char *name)
> > +{
> > + struct btf *btf = prog->aux->attach_btf;
> > + const struct btf_type *t;
> > + const char *tname;
> > +
> > + if (prog->expected_attach_type != BPF_TRACE_RAW_TP)
> > + return false;
> > +
> > + t = btf_type_by_id(btf, prog->aux->attach_btf_id);
> > + if (!t)
> > + return false;
> > +
> > + tname = btf_name_by_offset(btf, t->name_off);
> > + if (!tname)
> > + return false;
> > + return !strcmp(tname, name);
> > +}
> > +
> > bool btf_ctx_access(int off, int size, enum bpf_access_type type,
> > const struct bpf_prog *prog,
> > struct bpf_insn_access_aux *info)
> > @@ -6544,6 +6563,10 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type,
> > }
> > }
> >
> > + /* Second argument of sched_pi_setprio tracepoint can be null */
> > + if (is_tracing_prog_raw_tp(prog, "btf_trace_sched_pi_setprio") && arg == 1)
> > + info->reg_type |= PTR_MAYBE_NULL;
> > +
> > info->btf = btf;
> > info->btf_id = t->type;
> > t = btf_type_by_id(btf, t->type);
next prev parent reply other threads:[~2024-08-08 10:46 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-05 9:20 NULL pointer deref when running BPF monitor program (6.11.0-rc1) Juri Lelli
2024-08-05 16:49 ` Jiri Olsa
2024-08-05 17:00 ` Alexei Starovoitov
2024-08-06 7:08 ` Juri Lelli
2024-08-06 13:17 ` Jiri Olsa
2024-08-06 13:24 ` Jiri Olsa
2024-08-06 18:44 ` Alexei Starovoitov
2024-08-08 10:46 ` Jiri Olsa [this message]
2024-08-08 15:43 ` Alexei Starovoitov
2024-08-15 11:48 ` Jiri Olsa
2024-08-15 12:37 ` Alexei Starovoitov
2024-08-16 14:10 ` Steven Rostedt
2024-08-16 18:59 ` Jiri Olsa
2024-08-16 19:30 ` Steven Rostedt
2024-08-19 11:47 ` Jiri Olsa
2024-08-19 14:05 ` Jiri Olsa
2024-08-19 15:37 ` Steven Rostedt
2024-08-20 10:17 ` Jiri Olsa
2024-08-20 15:05 ` Steven Rostedt
2024-10-02 16:30 ` Jiri Olsa
2024-10-09 20:41 ` Jiri Olsa
2024-10-10 0:33 ` Josh Poimboeuf
2024-10-10 0:56 ` Steven Rostedt
2024-10-10 0:57 ` Steven Rostedt
2024-10-10 3:17 ` Josh Poimboeuf
2024-10-10 9:00 ` Jiri Olsa
2024-10-10 13:49 ` Steven Rostedt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZrSh8AuV21AKHfNg@krava \
--to=olsajiri@gmail.com \
--cc=alexei.starovoitov@gmail.com \
--cc=asavkov@redhat.com \
--cc=bpf@vger.kernel.org \
--cc=juri.lelli@redhat.com \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox