Commit 1eda32ca authored by Dmitry Vyukov's avatar Dmitry Vyukov Committed by Greg Kroah-Hartman

netfilter: ipt_CLUSTERIP: fix out-of-bounds accesses in clusterip_tg_check()

commit 1a38956c upstream.

Commit 136e92bb switched local_nodes from an array to a bitmask
but did not add proper bounds checks. As the result
clusterip_config_init_nodelist() can both over-read
ipt_clusterip_tgt_info.local_nodes and over-write
clusterip_config.local_nodes.

Add bounds checks for both.

Fixes: 136e92bb ("[NETFILTER] CLUSTERIP: use a bitmap to store node responsibility data")
Signed-off-by: default avatarDmitry Vyukov <dvyukov@google.com>
Reported-by: default avatarsyzbot <syzkaller@googlegroups.com>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 4556b01a
...@@ -365,7 +365,7 @@ static int clusterip_tg_check(const struct xt_tgchk_param *par) ...@@ -365,7 +365,7 @@ static int clusterip_tg_check(const struct xt_tgchk_param *par)
struct ipt_clusterip_tgt_info *cipinfo = par->targinfo; struct ipt_clusterip_tgt_info *cipinfo = par->targinfo;
const struct ipt_entry *e = par->entryinfo; const struct ipt_entry *e = par->entryinfo;
struct clusterip_config *config; struct clusterip_config *config;
int ret; int ret, i;
if (par->nft_compat) { if (par->nft_compat) {
pr_err("cannot use CLUSTERIP target from nftables compat\n"); pr_err("cannot use CLUSTERIP target from nftables compat\n");
...@@ -384,8 +384,18 @@ static int clusterip_tg_check(const struct xt_tgchk_param *par) ...@@ -384,8 +384,18 @@ static int clusterip_tg_check(const struct xt_tgchk_param *par)
pr_info("Please specify destination IP\n"); pr_info("Please specify destination IP\n");
return -EINVAL; return -EINVAL;
} }
if (cipinfo->num_local_nodes > ARRAY_SIZE(cipinfo->local_nodes)) {
/* FIXME: further sanity checks */ pr_info("bad num_local_nodes %u\n", cipinfo->num_local_nodes);
return -EINVAL;
}
for (i = 0; i < cipinfo->num_local_nodes; i++) {
if (cipinfo->local_nodes[i] - 1 >=
sizeof(config->local_nodes) * 8) {
pr_info("bad local_nodes[%d] %u\n",
i, cipinfo->local_nodes[i]);
return -EINVAL;
}
}
config = clusterip_config_find_get(par->net, e->ip.dst.s_addr, 1); config = clusterip_config_find_get(par->net, e->ip.dst.s_addr, 1);
if (!config) { if (!config) {
......
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