After fixing the previous filter issue reported by Vince Weaver,
I could not come up with a situation where the operand counter (cnt) could go below zero, so I added a WARN_ON_ONCE(cnt < 0). Vince was able to trigger that warn on with his fuzzer test, but didn't have a filter input that caused it. Later, Sasha Levin was able to trigger that same warning, and was able to give me the filter string that triggered it. It was simply a single operation ">". I wrapped the filtering code in a userspace program such that I could single step through the logic. With a single operator the operand counter can legitimately go below zero, and should be reported to the user as an error, but should not produce a kernel warning. The WARN_ON_ONCE(cnt < 0) should be just a "if (cnt < 0) break;" and the code following it will produce the error message for the user. While debugging this, I found that there was another bug that let the pointer to the filter string go beyond the filter string. This too was fixed. Finally, there was a typo in a stub function that only gets compiled if trace events is disabled but tracing is enabled (I'm not even sure that's possible). -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJVjWh2AAoJEEjnJuOKh9ldOn0IANHPW82++0O87U1pEe3hHnKv gSTKiNPVNC3GBt9DHnawA0EuyPfPa+Wj5X2xgrstWA+KRADZErZzdWpzbh/iHosJ 0kaUFqFcaKBheOSqhHfz3WQshD16pb1lQYbV7vbdzMjpcIpYT3VcuKQq3zQVb5Pr njPmgZXK+I9ITYQ8E+DysnTg0+Mo+l/2P/tqnBoIkAVmuZitfJS5okTtVw1GNzyR 7VRMGBE3G0GxB++57T/xILXjFc9sSGQH5lZgLHQhEh36YgWuDvc0R2FfxDKROmeq b/xw68uCO1Hv8oEng6r/UceVtUoaXhf+JamSJqxztBTsjsqR/iXCV78Jac1vnPY= =cmr8 -----END PGP SIGNATURE----- Merge tag 'trace-fixes-4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace Pull tracing fixes from Steven Rostedt: "This isn't my 4.2 pull request (yet). I found a few more bugs that I would have sent to fix 4.1, but since 4.1 is already out, I'm sending this before sending my 4.2 request (which is ready to go). After fixing the previous filter issue reported by Vince Weaver, I could not come up with a situation where the operand counter (cnt) could go below zero, so I added a WARN_ON_ONCE(cnt < 0). Vince was able to trigger that warn on with his fuzzer test, but didn't have a filter input that caused it. Later, Sasha Levin was able to trigger that same warning, and was able to give me the filter string that triggered it. It was simply a single operation ">". I wrapped the filtering code in a userspace program such that I could single step through the logic. With a single operator the operand counter can legitimately go below zero, and should be reported to the user as an error, but should not produce a kernel warning. The WARN_ON_ONCE(cnt < 0) should be just a "if (cnt < 0) break;" and the code following it will produce the error message for the user. While debugging this, I found that there was another bug that let the pointer to the filter string go beyond the filter string. This too was fixed. Finally, there was a typo in a stub function that only gets compiled if trace events is disabled but tracing is enabled (I'm not even sure that's possible)" * tag 'trace-fixes-4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: tracing: Fix typo from "static inlin" to "static inline" tracing/filter: Do not allow infix to exceed end of string tracing/filter: Do not WARN on operand count going below zero
This commit is contained in:
Коммит
fcbc1777ce
|
@ -1312,7 +1312,7 @@ void trace_event_init(void);
|
|||
void trace_event_enum_update(struct trace_enum_map **map, int len);
|
||||
#else
|
||||
static inline void __init trace_event_init(void) { }
|
||||
static inlin void trace_event_enum_update(struct trace_enum_map **map, int len) { }
|
||||
static inline void trace_event_enum_update(struct trace_enum_map **map, int len) { }
|
||||
#endif
|
||||
|
||||
extern struct trace_iterator *tracepoint_print_iter;
|
||||
|
|
|
@ -1056,6 +1056,9 @@ static void parse_init(struct filter_parse_state *ps,
|
|||
|
||||
static char infix_next(struct filter_parse_state *ps)
|
||||
{
|
||||
if (!ps->infix.cnt)
|
||||
return 0;
|
||||
|
||||
ps->infix.cnt--;
|
||||
|
||||
return ps->infix.string[ps->infix.tail++];
|
||||
|
@ -1071,6 +1074,9 @@ static char infix_peek(struct filter_parse_state *ps)
|
|||
|
||||
static void infix_advance(struct filter_parse_state *ps)
|
||||
{
|
||||
if (!ps->infix.cnt)
|
||||
return;
|
||||
|
||||
ps->infix.cnt--;
|
||||
ps->infix.tail++;
|
||||
}
|
||||
|
@ -1385,7 +1391,9 @@ static int check_preds(struct filter_parse_state *ps)
|
|||
if (elt->op != OP_NOT)
|
||||
cnt--;
|
||||
n_normal_preds++;
|
||||
WARN_ON_ONCE(cnt < 0);
|
||||
/* all ops should have operands */
|
||||
if (cnt < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (cnt != 1 || !n_normal_preds || n_logical_preds >= n_normal_preds) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче