netfilter: ebtables: CONFIG_COMPAT: don't trust userland offsets

We need to make sure the offsets are not out of range of the
total size.
Also check that they are in ascending order.

The WARN_ON triggered by syzkaller (it sets panic_on_warn) is
changed to also bail out, no point in continuing parsing.

Briefly tested with simple ruleset of
-A INPUT --limit 1/s' --log
plus jump to custom chains using 32bit ebtables binary.

Reported-by: <syzbot+845a53d13171abf8bf29@syzkaller.appspotmail.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
Florian Westphal 2018-02-19 01:24:15 +01:00 committed by Pablo Neira Ayuso
parent fc6a5d0601
commit b718121685

View File

@ -2060,7 +2060,9 @@ static int ebt_size_mwt(struct compat_ebt_entry_mwt *match32,
if (match_kern) if (match_kern)
match_kern->match_size = ret; match_kern->match_size = ret;
WARN_ON(type == EBT_COMPAT_TARGET && size_left); if (WARN_ON(type == EBT_COMPAT_TARGET && size_left))
return -EINVAL;
match32 = (struct compat_ebt_entry_mwt *) buf; match32 = (struct compat_ebt_entry_mwt *) buf;
} }
@ -2116,6 +2118,15 @@ static int size_entry_mwt(struct ebt_entry *entry, const unsigned char *base,
* *
* offsets are relative to beginning of struct ebt_entry (i.e., 0). * offsets are relative to beginning of struct ebt_entry (i.e., 0).
*/ */
for (i = 0; i < 4 ; ++i) {
if (offsets[i] >= *total)
return -EINVAL;
if (i == 0)
continue;
if (offsets[i-1] > offsets[i])
return -EINVAL;
}
for (i = 0, j = 1 ; j < 4 ; j++, i++) { for (i = 0, j = 1 ; j < 4 ; j++, i++) {
struct compat_ebt_entry_mwt *match32; struct compat_ebt_entry_mwt *match32;
unsigned int size; unsigned int size;