Skip to content

Commit

Permalink
tracing: add protection around open use of current_tracer
Browse files Browse the repository at this point in the history
Impact: fix to possible race conditions

There's some uses of current_tracer that is not protected by the
trace_types_lock. There is a small chance that a sysadmin changes
the tracer while the current_tracer is being referenced.

If the race is hit, it is unlikely to cause any harm since the
tracers are constant and are not freed. But some strang side
effects may occur.

Signed-off-by: Steven Rostedt <srostedt@redhat.com>
  • Loading branch information
Steven Rostedt committed Feb 27, 2009
1 parent 577b785 commit d8e83d2
Showing 1 changed file with 14 additions and 6 deletions.
20 changes: 14 additions & 6 deletions kernel/trace/trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -2024,12 +2024,12 @@ static ssize_t
tracing_trace_options_read(struct file *filp, char __user *ubuf,
size_t cnt, loff_t *ppos)
{
int i;
struct tracer_opt *trace_opts;
u32 tracer_flags;
int len = 0;
char *buf;
int r = 0;
int len = 0;
u32 tracer_flags = current_trace->flags->val;
struct tracer_opt *trace_opts = current_trace->flags->opts;
int i;


/* calculate max size */
Expand All @@ -2038,6 +2038,10 @@ tracing_trace_options_read(struct file *filp, char __user *ubuf,
len += 3; /* "no" and space */
}

mutex_lock(&trace_types_lock);
tracer_flags = current_trace->flags->val;
trace_opts = current_trace->flags->opts;

/*
* Increase the size with names of options specific
* of the current tracer.
Expand All @@ -2049,8 +2053,10 @@ tracing_trace_options_read(struct file *filp, char __user *ubuf,

/* +2 for \n and \0 */
buf = kmalloc(len + 2, GFP_KERNEL);
if (!buf)
if (!buf) {
mutex_unlock(&trace_types_lock);
return -ENOMEM;
}

for (i = 0; trace_options[i]; i++) {
if (trace_flags & (1 << i))
Expand All @@ -2067,14 +2073,14 @@ tracing_trace_options_read(struct file *filp, char __user *ubuf,
r += sprintf(buf + r, "no%s ",
trace_opts[i].name);
}
mutex_unlock(&trace_types_lock);

r += sprintf(buf + r, "\n");
WARN_ON(r >= len + 2);

r = simple_read_from_buffer(ubuf, cnt, ppos, buf, r);

kfree(buf);

return r;
}

Expand Down Expand Up @@ -2149,7 +2155,9 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf,

/* If no option could be set, test the specific tracer options */
if (!trace_options[i]) {
mutex_lock(&trace_types_lock);
ret = set_tracer_option(current_trace, cmp, neg);
mutex_unlock(&trace_types_lock);
if (ret)
return ret;
}
Expand Down

0 comments on commit d8e83d2

Please sign in to comment.