Commit cef0e9eb authored by Florian Westphal's avatar Florian Westphal Committed by Greg Kroah-Hartman

netfilter: ebtables: also count base chain policies

commit 3b48300d upstream.

ebtables doesn't include the base chain policies in the rule count,
so we need to add them manually when we call into the x_tables core
to allocate space for the comapt offset table.

This lead syzbot to trigger:
WARNING: CPU: 1 PID: 9012 at net/netfilter/x_tables.c:649
xt_compat_add_offset.cold+0x11/0x36 net/netfilter/x_tables.c:649

Reported-by: syzbot+276ddebab3382bbf72db@syzkaller.appspotmail.com
Fixes: 2035f3ff ("netfilter: ebtables: compat: un-break 32bit setsockopt when no rules are present")
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 07d92cae
...@@ -1779,20 +1779,28 @@ static int compat_calc_entry(const struct ebt_entry *e, ...@@ -1779,20 +1779,28 @@ static int compat_calc_entry(const struct ebt_entry *e,
return 0; return 0;
} }
static int ebt_compat_init_offsets(unsigned int number)
{
if (number > INT_MAX)
return -EINVAL;
/* also count the base chain policies */
number += NF_BR_NUMHOOKS;
return xt_compat_init_offsets(NFPROTO_BRIDGE, number);
}
static int compat_table_info(const struct ebt_table_info *info, static int compat_table_info(const struct ebt_table_info *info,
struct compat_ebt_replace *newinfo) struct compat_ebt_replace *newinfo)
{ {
unsigned int size = info->entries_size; unsigned int size = info->entries_size;
const void *entries = info->entries; const void *entries = info->entries;
int ret;
newinfo->entries_size = size; newinfo->entries_size = size;
if (info->nentries) { ret = ebt_compat_init_offsets(info->nentries);
int ret = xt_compat_init_offsets(NFPROTO_BRIDGE,
info->nentries);
if (ret) if (ret)
return ret; return ret;
}
return EBT_ENTRY_ITERATE(entries, size, compat_calc_entry, info, return EBT_ENTRY_ITERATE(entries, size, compat_calc_entry, info,
entries, newinfo); entries, newinfo);
...@@ -2241,11 +2249,9 @@ static int compat_do_replace(struct net *net, void __user *user, ...@@ -2241,11 +2249,9 @@ static int compat_do_replace(struct net *net, void __user *user,
xt_compat_lock(NFPROTO_BRIDGE); xt_compat_lock(NFPROTO_BRIDGE);
if (tmp.nentries) { ret = ebt_compat_init_offsets(tmp.nentries);
ret = xt_compat_init_offsets(NFPROTO_BRIDGE, tmp.nentries);
if (ret < 0) if (ret < 0)
goto out_unlock; goto out_unlock;
}
ret = compat_copy_entries(entries_tmp, tmp.entries_size, &state); ret = compat_copy_entries(entries_tmp, tmp.entries_size, &state);
if (ret < 0) if (ret < 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment