em_text_change() copies the user-supplied tcf_em_text struct from netlink and passes conf->algo straight to textsearch_prepare(), which forwards it to lookup_ts_algo() (strcmp) and request_module() (vsnprintf %s). But the algo[16] field is never validated to be NULL-terminated, so a fully populated array reads past it into the adjacent from_offset/to_offset/pattern_len fields and the trailing pattern bytes during the string operations. This type of pattern is properly checked in the string_mt_check() for xt_string netfilter matching function, but for some reason was not added here, so fix this up by doing the same exact thing. Cc: Jamal Hadi Salim Cc: Jiri Pirko Cc: "David S. Miller" Cc: Eric Dumazet Cc: Jakub Kicinski Cc: Paolo Abeni Cc: Simon Horman Fixes: d675c989ed2d ("[PKT_SCHED]: Packet classification based on textsearch (ematch)") Cc: stable Assisted-by: gregkh_clanker_t1000 Signed-off-by: Greg Kroah-Hartman --- Note, my tools flagged this, so I fixed this up the same way that string_mt_check() did, but if there is some other way that this should be resolved, or I got this totally wrong that this isn't an issue, please let me know, thanks! net/sched/em_text.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/sched/em_text.c b/net/sched/em_text.c index 343f1aebeec2..24a8aa21971d 100644 --- a/net/sched/em_text.c +++ b/net/sched/em_text.c @@ -58,6 +58,9 @@ static int em_text_change(struct net *net, void *data, int len, if (len < sizeof(*conf) || len < (sizeof(*conf) + conf->pattern_len)) return -EINVAL; + if (conf->algo[sizeof(conf->algo) - 1] != '\0') + return -EINVAL; + if (conf->from_layer > conf->to_layer) return -EINVAL; -- 2.53.0