Skip to content

Commit b9d62c1

Browse files
dvyukovbwhacks
authored andcommitted
netfilter: ipt_CLUSTERIP: fix out-of-bounds accesses in clusterip_tg_check()
commit 1a38956 upstream. Commit 136e92b 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: 136e92b ("[NETFILTER] CLUSTERIP: use a bitmap to store node responsibility data") Signed-off-by: Dmitry Vyukov <[email protected]> Reported-by: syzbot <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]> Signed-off-by: Ben Hutchings <[email protected]>
1 parent 8d6801a commit b9d62c1

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

net/ipv4/netfilter/ipt_CLUSTERIP.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ static int clusterip_tg_check(const struct xt_tgchk_param *par)
366366
struct ipt_clusterip_tgt_info *cipinfo = par->targinfo;
367367
const struct ipt_entry *e = par->entryinfo;
368368
struct clusterip_config *config;
369-
int ret;
369+
int ret, i;
370370

371371
if (cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP &&
372372
cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP_SPT &&
@@ -380,8 +380,18 @@ static int clusterip_tg_check(const struct xt_tgchk_param *par)
380380
pr_info("Please specify destination IP\n");
381381
return -EINVAL;
382382
}
383-
384-
/* FIXME: further sanity checks */
383+
if (cipinfo->num_local_nodes > ARRAY_SIZE(cipinfo->local_nodes)) {
384+
pr_info("bad num_local_nodes %u\n", cipinfo->num_local_nodes);
385+
return -EINVAL;
386+
}
387+
for (i = 0; i < cipinfo->num_local_nodes; i++) {
388+
if (cipinfo->local_nodes[i] - 1 >=
389+
sizeof(config->local_nodes) * 8) {
390+
pr_info("bad local_nodes[%d] %u\n",
391+
i, cipinfo->local_nodes[i]);
392+
return -EINVAL;
393+
}
394+
}
385395

386396
config = clusterip_config_find_get(par->net, e->ip.dst.s_addr, 1);
387397
if (!config) {

0 commit comments

Comments
 (0)