diff options
author | Florian Westphal <fw@strlen.de> | 2018-02-19 01:24:15 +0100 |
---|---|---|
committer | Satyanarayana Dash <sadash@codeaurora.org> | 2018-10-12 21:48:13 +0530 |
commit | 0093c07aa5d329c493f89ab1fbbebb514dff0f6f (patch) | |
tree | 1ef498095f2e49a5840a70f5248d1e1ec86a8c4a | |
parent | 4c26040b8027318c39c672deec1586d8166252db (diff) |
netfilter: ebtables: CONFIG_COMPAT: don't trust userland offsetsLA.UM.6.8.r2-02500-SDM710.0
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>
Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Git-commit: b71812168571fa55e44cdd0254471331b9c4c4c6
Change-Id: Ic1b91b00521fb550f1774b916aa5b53c91940ed0
Signed-off-by: Dennis Cagle <dcagle@codeaurora.org>
Signed-off-by: Satyanarayana Dash <sadash@codeaurora.org>
-rw-r--r-- | net/bridge/netfilter/ebtables.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index f5c11bbe27db..5a89a4ac86ef 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -2031,7 +2031,9 @@ static int ebt_size_mwt(struct compat_ebt_entry_mwt *match32, if (match_kern) 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; } @@ -2087,6 +2089,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). */ + 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++) { struct compat_ebt_entry_mwt *match32; unsigned int size; |