Skip to content

Commit

Permalink
perf tools: Validate config term maximum value
Browse files Browse the repository at this point in the history
Currently the value of a PMU config term is silently truncated if it is
too big. This is an impediment to validating the value for other
criteria later on i.e.  the user provides an invalid value that gets
truncated to a valid one.

The maximum value validation is only done for the parser where the error
is passed back to the user. In other cases the silent truncation
continues so as not to affect tools that perhaps rely on it.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/1437150840-31811-16-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
  • Loading branch information
Adrian Hunter authored and Arnaldo Carvalho de Melo committed Aug 6, 2015
1 parent 09ff607 commit 0efe6b6
Showing 1 changed file with 29 additions and 1 deletion.
30 changes: 29 additions & 1 deletion tools/perf/util/pmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,18 @@ static void pmu_format_value(unsigned long *format, __u64 value, __u64 *v,
}
}

static __u64 pmu_format_max_value(const unsigned long *format)
{
int w;

w = bitmap_weight(format, PERF_PMU_FORMAT_BITS);
if (!w)
return 0;
if (w < 64)
return (1ULL << w) - 1;
return -1;
}

/*
* Term is a string term, and might be a param-term. Try to look up it's value
* in the remaining terms.
Expand Down Expand Up @@ -662,7 +674,7 @@ static int pmu_config_term(struct list_head *formats,
{
struct perf_pmu_format *format;
__u64 *vp;
__u64 val;
__u64 val, max_val;

/*
* If this is a parameter we've already used for parameterized-eval,
Expand Down Expand Up @@ -728,6 +740,22 @@ static int pmu_config_term(struct list_head *formats,
} else
return -EINVAL;

max_val = pmu_format_max_value(format->bits);
if (val > max_val) {
if (err) {
err->idx = term->err_val;
if (asprintf(&err->str,
"value too big for format, maximum is %llu",
(unsigned long long)max_val) < 0)
err->str = strdup("value too big for format");
return -EINVAL;
}
/*
* Assume we don't care if !err, in which case the value will be
* silently truncated.
*/
}

pmu_format_value(format->bits, val, vp, zero);
return 0;
}
Expand Down

0 comments on commit 0efe6b6

Please sign in to comment.