Re: [PATCH 1/3] [BUGFIX] tracing: Fix double free of event_trigger_data

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 24 Jul 2018 19:13:31 -0400
Steven Rostedt <rostedt@xxxxxxxxxxx> wrote:

> On Tue, 24 Jul 2018 17:30:08 -0400
> Steven Rostedt <rostedt@xxxxxxxxxxx> wrote:
> 
> > I don't see where ->reg() would return anything but 1 on success. Maybe
> > I'm missing something. I'll look some more, but I'm thinking of changing
> > ->reg() to return zero on all success, and negative on all errors and  
> > just check those results.
> 
> Yeah, I'm going to make these changes. That is, all struct
> event_command .reg functions will return negative on error, and
> zero or positive on everything else. All the checks are going to be
> only for the negative value.
> 
> But for the bug fix itself, I believe this should do it. Masami, what
> do you think?

Hm, as far as I can see, when register_trigger() returns >= 0, it already
calls ->init the trigger_data. This means its refcount++, and in that
case, below patch will miss to free the trigger_data.
How about below for tentative fix?

	if (!ret) {
		ret = -ENOENT;
		/* We have to forcibly free the trigger_data */
		goto out_free;
	} else if (ret > 0)
		ret = 0;

Thank you,

> 
> -- Steve
> 
> diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c
> index d18249683682..8771a27ca60f 100644
> --- a/kernel/trace/trace_events_trigger.c
> +++ b/kernel/trace/trace_events_trigger.c
> @@ -679,6 +679,8 @@ event_trigger_callback(struct event_command *cmd_ops,
>  		goto out_free;
>  
>   out_reg:
> +	/* Up the trigger_data count to make sure reg doesn't free it on failure */
> +	event_trigger_init(trigger_ops, trigger_data);
>  	ret = cmd_ops->reg(glob, trigger_ops, trigger_data, file);
>  	/*
>  	 * The above returns on success the # of functions enabled,
> @@ -687,10 +689,11 @@ event_trigger_callback(struct event_command *cmd_ops,
>  	 */
>  	if (!ret) {
>  		ret = -ENOENT;
> -		goto out_free;
> -	} else if (ret < 0)
> -		goto out_free;
> -	ret = 0;
> +	} else if (ret > 0)
> +		ret = 0;
> +
> +	/* Down the counter of trigger_data or free it if not used anymore */
> +	event_trigger_free(trigger_ops, trigger_data);
>   out:
>  	return ret;
>  


-- 
Masami Hiramatsu <mhiramat@xxxxxxxxxx>



[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux