All of lore.kernel.org
 help / color / mirror / Atom feed
From: Beau Belgrave <beaub@linux.microsoft.com>
To: Masami Hiramatsu <mhiramat@kernel.org>
Cc: rostedt@goodmis.org, linux-trace-devel@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v8 11/12] user_events: Validate user payloads for size and null termination
Date: Mon, 3 Jan 2022 10:53:08 -0800	[thread overview]
Message-ID: <20220103185308.GA15522@kbox> (raw)
In-Reply-To: <20211223090822.a14244522fef64b4b4398fe0@kernel.org>

On Thu, Dec 23, 2021 at 09:08:22AM +0900, Masami Hiramatsu wrote:
> On Thu, 16 Dec 2021 09:35:10 -0800
> Beau Belgrave <beaub@linux.microsoft.com> wrote:
> 
> > Add validation to ensure data is at or greater than the min size for the
> > fields of the event. If a dynamic array is used and is a type of char,
> > ensure null termination of the array exists.
> 
> OK, looks good to me except a few nitpicks.
> 
> Reveiewed-by: Masami Hiramatsu <mhiramat@kernel.org>
> 
> I added some comments below.
> 
> > 
> > Signed-off-by: Beau Belgrave <beaub@linux.microsoft.com>
> > ---
> >  kernel/trace/trace_events_user.c | 147 +++++++++++++++++++++++++++----
> >  1 file changed, 132 insertions(+), 15 deletions(-)
> > 
> > diff --git a/kernel/trace/trace_events_user.c b/kernel/trace/trace_events_user.c
> > index fa3e26281fc3..58b8c9607c80 100644
> > --- a/kernel/trace/trace_events_user.c
> > +++ b/kernel/trace/trace_events_user.c
> > @@ -64,9 +64,11 @@ struct user_event {
> >  	struct dyn_event devent;
> >  	struct hlist_node node;
> >  	struct list_head fields;
> > +	struct list_head validators;
> >  	atomic_t refcnt;
> >  	int index;
> >  	int flags;
> > +	int min_size;
> >  };
> >  
> >  /*
> > @@ -81,8 +83,17 @@ struct user_event_refs {
> >  	struct user_event *events[];
> >  };
> >  
> > +#define VALIDATOR_ENSURE_NULL (1 << 0)
> > +#define VALIDATOR_REL (1 << 1)
> > +
> > +struct user_event_validator {
> > +	struct list_head link;
> > +	int offset;
> > +	int flags;
> > +};
> > +
> >  typedef void (*user_event_func_t) (struct user_event *user, struct iov_iter *i,
> > -				   void *tpdata);
> > +				   void *tpdata, bool *faulted);
> 
> Why don't you just return "int" value? ;-)
> 

There can be more than one callback attached per-probe, and in all cases
where a return value is needed is for a faulted (or would have faulted)
case. This allows less branches when data is being traced/logged as the
return value does not need to be checked (nor should it short circuit
other probes that are attached).

> >  
> >  static int user_event_parse(char *name, char *args, char *flags,
> >  			    struct user_event **newuser);
> > @@ -214,6 +225,17 @@ static int user_field_size(const char *type)
> >  	return -EINVAL;
> >  }
> >  

[..]

> > +static int user_event_validate(struct user_event *user, void *data, int len)
> > +{
> > +	struct list_head *head = &user->validators;
> > +	struct user_event_validator *validator;
> > +	void *pos, *end = data + len;
> > +	u32 loc, offset, size;
> > +
> > +	list_for_each_entry(validator, head, link) {
> > +		pos = data + validator->offset;
> > +
> > +		/* Already done min_size check, no bounds check here */
> > +		loc = *(u32 *)pos;
> > +		offset = loc & 0xffff;
> > +		size = loc >> 16;
> > +
> > +		if (likely(validator->flags & VALIDATOR_REL))
> > +			pos += offset + sizeof(loc);
> > +		else
> > +			pos = data + offset;
> > +
> > +		pos += size;
> > +
> > +		if (unlikely(pos > end))
> > +			return -EFAULT;
> > +
> > +		if (likely(validator->flags & VALIDATOR_ENSURE_NULL))
> > +			if (unlikely(*(char *)(pos - 1) != 0))
> 
> As we discussed in the previous version, isn't it '\0' ?
> (just a style comment)
> 

Sure, there are a few dangling around that I missed. I'll fix them.

> > +				return -EFAULT;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> >  /*
> >   * Writes the user supplied payload out to a trace file.
> >   */
> >  static void user_event_ftrace(struct user_event *user, struct iov_iter *i,
> > -			      void *tpdata)
> > +			      void *tpdata, bool *faulted)
> >  {
> >  	struct trace_event_file *file;
> >  	struct trace_entry *entry;
> >  	struct trace_event_buffer event_buffer;
> > +	size_t size = sizeof(*entry) + i->count;
> >  
> >  	file = (struct trace_event_file *)tpdata;
> >  
> > @@ -555,19 +648,25 @@ static void user_event_ftrace(struct user_event *user, struct iov_iter *i,
> >  		return;
> >  
> >  	/* Allocates and fills trace_entry, + 1 of this is data payload */
> > -	entry = trace_event_buffer_reserve(&event_buffer, file,
> > -					   sizeof(*entry) + i->count);
> > +	entry = trace_event_buffer_reserve(&event_buffer, file, size);
> >  
> >  	if (unlikely(!entry))
> >  		return;
> >  
> > -	if (unlikely(!copy_nofault(entry + 1, i->count, i))) {
> > -		__trace_event_discard_commit(event_buffer.buffer,
> > -					     event_buffer.event);
> > -		return;
> > -	}
> > +	if (unlikely(!copy_nofault(entry + 1, i->count, i)))
> > +		goto discard;
> 
> OK, this is a fault error.
> 
> > +
> > +	if (!list_empty(&user->validators) &&
> > +	    unlikely(user_event_validate(user, entry, size)))
> > +		goto discard;
> 
> But this maybe an invalid parameter error.
> 

Yes, but it has to be an invalid parameter that would have caused a
possible fault in a worse place. In my mind, I still treat it as a fault
case whether the user did it intentionally or not :)

Thanks,
-Beau

  reply	other threads:[~2022-01-03 18:53 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-16 17:34 [PATCH v8 00/12] user_events: Enable user processes to create and write to trace events Beau Belgrave
2021-12-16 17:35 ` [PATCH v8 01/12] user_events: Add minimal support for trace_event into ftrace Beau Belgrave
2021-12-21 15:16   ` Masami Hiramatsu
2022-01-03 18:22     ` Beau Belgrave
2021-12-16 17:35 ` [PATCH v8 02/12] user_events: Add print_fmt generation support for basic types Beau Belgrave
2021-12-22  0:30   ` Masami Hiramatsu
2022-01-03 18:56     ` Beau Belgrave
2021-12-16 17:35 ` [PATCH v8 03/12] user_events: Handle matching arguments from dyn_events Beau Belgrave
2021-12-22  6:19   ` Masami Hiramatsu
2021-12-16 17:35 ` [PATCH v8 04/12] user_events: Add basic perf and eBPF support Beau Belgrave
2021-12-22  7:55   ` Masami Hiramatsu
2021-12-16 17:35 ` [PATCH v8 05/12] user_events: Add self-test for ftrace integration Beau Belgrave
2021-12-16 17:35 ` [PATCH v8 06/12] user_events: Add self-test for dynamic_events integration Beau Belgrave
2021-12-16 17:35 ` [PATCH v8 07/12] user_events: Add self-test for perf_event integration Beau Belgrave
2021-12-16 17:35 ` [PATCH v8 08/12] user_events: Optimize writing events by only copying data once Beau Belgrave
2021-12-22 15:11   ` Masami Hiramatsu
2022-01-03 18:58     ` Beau Belgrave
2022-01-06 22:17   ` Steven Rostedt
2022-01-06 23:05     ` Beau Belgrave
2021-12-16 17:35 ` [PATCH v8 09/12] user_events: Add documentation file Beau Belgrave
2021-12-22 14:18   ` Masami Hiramatsu
2022-01-03 23:01     ` Beau Belgrave
2022-01-06 21:14       ` Steven Rostedt
2021-12-16 17:35 ` [PATCH v8 10/12] user_events: Add sample code for typical usage Beau Belgrave
2021-12-22 23:18   ` Masami Hiramatsu
2022-01-06 22:09     ` Steven Rostedt
2022-01-06 23:06       ` Beau Belgrave
2021-12-16 17:35 ` [PATCH v8 11/12] user_events: Validate user payloads for size and null termination Beau Belgrave
2021-12-23  0:08   ` Masami Hiramatsu
2022-01-03 18:53     ` Beau Belgrave [this message]
2022-01-06 23:32       ` Masami Hiramatsu
2022-01-07  1:01         ` Beau Belgrave
2021-12-16 17:35 ` [PATCH v8 12/12] user_events: Add self-test for validator boundaries Beau Belgrave
2022-04-18 20:43 ` [PATCH v8 00/12] user_events: Enable user processes to create and write to trace events Hagen Paul Pfeifer
2022-04-19  0:25   ` Beau Belgrave

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=20220103185308.GA15522@kbox \
    --to=beaub@linux.microsoft.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-trace-devel@vger.kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=rostedt@goodmis.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.