linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Steven Rostedt <rostedt@goodmis.org>
To: Sean Christopherson <seanjc@google.com>
Cc: linux-kernel@vger.kernel.org, Ingo Molnar <mingo@kernel.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Masami Hiramatsu <mhiramat@kernel.org>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Jacob Wen <jian.w.wen@oracle.com>,
	Paolo Bonzini <pbonzini@redhat.com>
Subject: Re: [PATCH 2/2] tracing: Add a verifier to check string pointers for trace events
Date: Fri, 4 Jun 2021 22:28:30 -0400	[thread overview]
Message-ID: <20210604222830.2505d67a@rorschach.local.home> (raw)
In-Reply-To: <YLrRUmwjjaozIt4K@google.com>

On Sat, 5 Jun 2021 01:20:18 +0000
Sean Christopherson <seanjc@google.com> wrote:

> +Paolo
> 
> On Fri, Feb 26, 2021, Steven Rostedt wrote:
> > diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
> > index f5e8e39d6f57..ff08c04de6cb 100644
> > --- a/kernel/trace/trace.c
> > +++ b/kernel/trace/trace.c
> > @@ -3551,6 +3551,154 @@ static char *trace_iter_expand_format(struct trace_iterator *iter)
> >  	return tmp;
> >  }
> >  
> > +/* Returns true if the string is safe to dereference from an event */
> > +static bool trace_safe_str(struct trace_iterator *iter, const char *str)
> > +{
> > +	unsigned long addr = (unsigned long)str;
> > +	struct trace_event *trace_event;
> > +	struct trace_event_call *event;
> > +
> > +	/* OK if part of the event data */
> > +	if ((addr >= (unsigned long)iter->ent) &&
> > +	    (addr < (unsigned long)iter->ent + iter->ent_size))
> > +		return true;
> > +
> > +	/* OK if part of the temp seq buffer */
> > +	if ((addr >= (unsigned long)iter->tmp_seq.buffer) &&
> > +	    (addr < (unsigned long)iter->tmp_seq.buffer + PAGE_SIZE))
> > +		return true;
> > +
> > +	/* Core rodata can not be freed */
> > +	if (is_kernel_rodata(addr))
> > +		return true;
> > +
> > +	/*
> > +	 * Now this could be a module event, referencing core module
> > +	 * data, which is OK.
> > +	 */  
> 
> Question on this: is it safe for a module to provide a string from its core data
> when invoking a tracepoint that is defined and exported by a different module or
> by the kernel proper?	

If it is in kernel proper, then it will be fine because all core read
only memory is fine to print. If it is not read only, then it can
change from the time it was recorded to the time it was printed which
is also considered unsafe.

Now I haven't thought about a module writing a string that is static
and read only from another module that the first module is dependent
on. That's new.

Now, are you talking about a built-in tracepoint referencing a module
string? If so, what happens if the trace happens, the module is
unloaded, and then the trace is read. That string is now unsafe. And
yes, that event will still exist in the buffer after the module is
unloaded. (Note, if a module events were enabled, unloading it will
clear the buffer, but if you only enabled the event that references the
module string and not events within the module, unloading the module
will *not* clear the buffer)

Same if there's not a dependency between modules. If one module
references a string from another module. If it is possible for the
other module to be unloaded between the time the event is recorded, but
the tracepoint module is not released, reading the string will be
stale, and that too is unsafe.

> 
> If that behavior is safe, then this will generate false positives on those use

I need to see the exact use case here, because it may very well not be
safe, thus not a false positive, and indeed a bug in the trace event.

> cases.  And AFAICT, it's not possible to fully fix the issue, at least not
> without plumbing in more crud.  E.g. if the tracepoint is built into the kernel,
> event->mod will be NULL and so even a hack-a-fix like walking source_list isn't
> an option (I used source_list to verify the address is indeed in the invoking
> module).
> 
> E.g. in KVM, all tracepoints are defined and exported by the common 'kvm' module
> (which can also be built-in), and used by 'kvm' and the vendor modules,
> 'kvm_intel' and 'kvm_amd'.  One tracepoint in particular takes a hardcoded string
> and does a direct fast assign to and from a 'const char *'.  This triggers the
> WARN and displays [UNSAFE-MEMORY] because the string is in 'kvm_intel', not the
> tracepoint owner.

What happens if you enable the trace, remove kvm_intel, then read the
trace? Sounds to me that string will no longer exist and you are then
referencing some undefined data. Which is *exactly* what this is trying
to prevent.

> 
> The bug is easy to workaround in KVM by converting to the __string() machinery,
> but I suspect there will be grumpy users on the horizon when a false positive
> breaks a tracepoint in a different module at the worst possible time.

What you described to me does not sound like a false positive, and
converting to __string() is not a workaround but an actual fix, and
would also need to be backported to stable.

-- Steve

> 
> > +	if (!iter->ent)
> > +		return false;
> > +
> > +	trace_event = ftrace_find_event(iter->ent->type);
> > +	if (!trace_event)
> > +		return false;
> > +
> > +	event = container_of(trace_event, struct trace_event_call, event);
> > +	if (!event->mod)
> > +		return false;
> > +
> > +	/* Would rather have rodata, but this will suffice */
> > +	if (within_module_core(addr, event->mod))
> > +		return true;
> > +
> > +	return false;
> > +}  


  reply	other threads:[~2021-06-05  2:28 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-26 18:59 [PATCH 0/2] tracing: Detect unsafe dereferencing of pointers from trace events Steven Rostedt
2021-02-26 18:59 ` [PATCH 1/2] tracing: Add check of trace event print fmts for dereferencing pointers Steven Rostedt
2021-02-27 14:16   ` [tracing] 5c71984c21: WARNING:at_kernel/trace/trace_events.c:#test_event_printk kernel test robot
2021-02-26 18:59 ` [PATCH 2/2] tracing: Add a verifier to check string pointers for trace events Steven Rostedt
2021-06-05  1:20   ` Sean Christopherson
2021-06-05  2:28     ` Steven Rostedt [this message]
2021-06-05  2:45       ` Steven Rostedt
2021-06-07 16:02         ` Sean Christopherson
2021-06-07 17:24           ` Steven Rostedt
2021-02-26 22:21 ` [PATCH 0/2] tracing: Detect unsafe dereferencing of pointers from " Linus Torvalds
2021-02-26 23:33   ` Steven Rostedt
2021-02-27  4:04     ` Joe Perches
2021-02-27 19:18   ` Steven Rostedt
2021-02-28  0:08     ` Steven Rostedt
2021-03-01  5:27       ` Pawel Laszczak
2021-03-02  8:23         ` Peter Chen
2021-03-02 14:56           ` Steven Rostedt
2021-03-03  1:21             ` Peter Chen
2021-03-03  1:54               ` Steven Rostedt
2021-03-07  4:01             ` Peter Chen
2021-03-07 21:14               ` 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=20210604222830.2505d67a@rorschach.local.home \
    --to=rostedt@goodmis.org \
    --cc=akpm@linux-foundation.org \
    --cc=jian.w.wen@oracle.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=mingo@kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=seanjc@google.com \
    --cc=torvalds@linux-foundation.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;
as well as URLs for NNTP newsgroup(s).