Skip to content

Commit 0efe6b6

Browse files
ahunter6acmel
authored andcommitted
perf tools: Validate config term maximum value
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>
1 parent 09ff607 commit 0efe6b6

File tree

1 file changed

+29
-1
lines changed

1 file changed

+29
-1
lines changed

tools/perf/util/pmu.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,18 @@ static void pmu_format_value(unsigned long *format, __u64 value, __u64 *v,
589589
}
590590
}
591591

592+
static __u64 pmu_format_max_value(const unsigned long *format)
593+
{
594+
int w;
595+
596+
w = bitmap_weight(format, PERF_PMU_FORMAT_BITS);
597+
if (!w)
598+
return 0;
599+
if (w < 64)
600+
return (1ULL << w) - 1;
601+
return -1;
602+
}
603+
592604
/*
593605
* Term is a string term, and might be a param-term. Try to look up it's value
594606
* in the remaining terms.
@@ -662,7 +674,7 @@ static int pmu_config_term(struct list_head *formats,
662674
{
663675
struct perf_pmu_format *format;
664676
__u64 *vp;
665-
__u64 val;
677+
__u64 val, max_val;
666678

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

743+
max_val = pmu_format_max_value(format->bits);
744+
if (val > max_val) {
745+
if (err) {
746+
err->idx = term->err_val;
747+
if (asprintf(&err->str,
748+
"value too big for format, maximum is %llu",
749+
(unsigned long long)max_val) < 0)
750+
err->str = strdup("value too big for format");
751+
return -EINVAL;
752+
}
753+
/*
754+
* Assume we don't care if !err, in which case the value will be
755+
* silently truncated.
756+
*/
757+
}
758+
731759
pmu_format_value(format->bits, val, vp, zero);
732760
return 0;
733761
}

0 commit comments

Comments
 (0)