[PATCH] netfilter: fix out-of-bounds accesses in clusterip_tg_check()

86 views
Skip to first unread message

Dmitry Vyukov

unread,
Jan 30, 2018, 9:21:39 AM1/30/18
to pa...@netfilter.org, kad...@blackhole.kfki.hu, f...@strlen.de, da...@davemloft.net, kuz...@ms2.inr.ac.ru, yosh...@linux-ipv6.org, edum...@google.com, wil...@google.com, Dmitry Vyukov, netfilt...@vger.kernel.org, core...@netfilter.org, net...@vger.kernel.org, linux-...@vger.kernel.org, syzk...@googlegroups.com
Commit 136e92bbec0a 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.

Signed-off-by: Dmitry Vyukov <dvy...@google.com>
Fixes: 136e92bbec0a ("[NETFILTER] CLUSTERIP: use a bitmap to store node responsibility data")
Reported-by: syzbot <syzk...@googlegroups.com>
Cc: netfilt...@vger.kernel.org
Cc: core...@netfilter.org
Cc: net...@vger.kernel.org
Cc: linux-...@vger.kernel.org
Cc: syzk...@googlegroups.com
---
net/ipv4/netfilter/ipt_CLUSTERIP.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 69060e3abe85..1e4a7209a3d2 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -431,7 +431,7 @@ static int clusterip_tg_check(const struct xt_tgchk_param *par)
struct ipt_clusterip_tgt_info *cipinfo = par->targinfo;
const struct ipt_entry *e = par->entryinfo;
struct clusterip_config *config;
- int ret;
+ int ret, i;

if (par->nft_compat) {
pr_err("cannot use CLUSTERIP target from nftables compat\n");
@@ -450,8 +450,18 @@ static int clusterip_tg_check(const struct xt_tgchk_param *par)
pr_info("Please specify destination IP\n");
return -EINVAL;
}
-
- /* FIXME: further sanity checks */
+ if (cipinfo->num_local_nodes > ARRAY_SIZE(cipinfo->local_nodes)) {
+ 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);
if (!config) {
--
2.16.0.rc1.238.g530d649a79-goog

Pablo Neira Ayuso

unread,
Jan 31, 2018, 9:00:26 AM1/31/18
to Dmitry Vyukov, kad...@blackhole.kfki.hu, f...@strlen.de, da...@davemloft.net, kuz...@ms2.inr.ac.ru, yosh...@linux-ipv6.org, edum...@google.com, wil...@google.com, netfilt...@vger.kernel.org, core...@netfilter.org, net...@vger.kernel.org, linux-...@vger.kernel.org, syzk...@googlegroups.com
On Tue, Jan 30, 2018 at 03:21:34PM +0100, Dmitry Vyukov wrote:
> Commit 136e92bbec0a 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.

Applied, thanks Dmitry.
Reply all
Reply to author
Forward
0 new messages