Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp5034215ybl; Tue, 14 Jan 2020 02:20:48 -0800 (PST) X-Google-Smtp-Source: APXvYqxi0VRJZiWSmFm5AU7sSjYeKqf1FcIr+EhDWDID6/6vKPWHoMzxMz6uiICq7+qtO68mWXvw X-Received: by 2002:aca:51c9:: with SMTP id f192mr16697618oib.10.1578997248302; Tue, 14 Jan 2020 02:20:48 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1578997248; cv=none; d=google.com; s=arc-20160816; b=HNs+ZmU22JiPsSeX9gIC80xOUE2sQA9WkkgCfEggIwkbA4YAuuZYHc13+23/yQh2BI iX6u+/13mGCOwsowXLDBS/qS/SUbBVLlv4xM/1xJ/GhSCNVe6qgjQ1mLSvCeBMW3Z7Qm KQVHmKw5adzDMRUxdX5kNUXoiu1/i13Lgof1KX8F760WfNzIqj7Ct8RmgMoiLLqg7o6x gWO6c49NT5tQlwABOxzFCPMsuy7hNZWYNN2e9etS8en4h2V6MaFHOMZkhgKRnMWzLmCL hrP2kpBhv0tTpOkLF/kPwLc/8je5fCuRVLCtrPkQtNIvTNdC4E2HKtT/0OdtNa165zCa VQ8A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=XPlQVIDwRqrRLzpLODH3LuJoScRnd17pjwpQvcgqVdY=; b=rs9oskaTOYWAGDV409y7WAfFtLhAkNtNtCniAWAiBqadnV03qEWkjmCJKWp9kw2yUB 70N9F4n5WOzmjSlni3SiOaVDA4nBdUseRYfxECS2cGcJtIPC2qTrIIlpO3tQwpYXsbZn BGXZz5oxATC7vv7ZOt/1NzDyDHKywG3Jxf+Fm+W7yNUUAYHaZFUy1iVSDxPjZD0KR2Hj Q2eluABcvNK2GeLUivVaeo+muvfFvZN2cfCzIgKgSB90dw6SLXaOs8136KOUxNCSVBB1 nFKVo165iW5TGuR5v/5rZPQS0hW1BHO1wLkOLxT4gGe99YuyUcbwoCj0hQJKN0QIUTG3 L/jA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=HsraGOna; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s129si7239309oig.177.2020.01.14.02.20.37; Tue, 14 Jan 2020 02:20:48 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=HsraGOna; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730716AbgANKTT (ORCPT + 99 others); Tue, 14 Jan 2020 05:19:19 -0500 Received: from mail.kernel.org ([198.145.29.99]:35360 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729950AbgANKGV (ORCPT ); Tue, 14 Jan 2020 05:06:21 -0500 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id E26A724676; Tue, 14 Jan 2020 10:06:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1578996380; bh=GSiPrkVh8W0BgVy8K+GW2cCWlYwb4Zxjg1e2YFJ5fdQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HsraGOnax31+6y/iL9Mo8mjLdRxH0yJrXlZ0OB6sMC065fcbSqwHfYVaIHDX0+mto H/Li0+gqhgvg68MKqHHBnywFq9p23ebiq54PueXhEXVbngiQWEACKI5CH0ZKs/9Fhe iKoXZ38MGomZIHfoHGg4FXQwBBOsicBgkg5dWp+4= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, syzbot+d7358a458d8a81aee898@syzkaller.appspotmail.com, Florian Westphal , Cong Wang , Pablo Neira Ayuso Subject: [PATCH 5.4 76/78] netfilter: arp_tables: init netns pointer in xt_tgchk_param struct Date: Tue, 14 Jan 2020 11:01:50 +0100 Message-Id: <20200114094403.522011249@linuxfoundation.org> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200114094352.428808181@linuxfoundation.org> References: <20200114094352.428808181@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Florian Westphal commit 1b789577f655060d98d20ed0c6f9fbd469d6ba63 upstream. We get crash when the targets checkentry function tries to make use of the network namespace pointer for arptables. When the net pointer got added back in 2010, only ip/ip6/ebtables were changed to initialize it, so arptables has this set to NULL. This isn't a problem for normal arptables because no existing arptables target has a checkentry function that makes use of par->net. However, direct users of the setsockopt interface can provide any target they want as long as its registered for ARP or UNPSEC protocols. syzkaller managed to send a semi-valid arptables rule for RATEEST target which is enough to trigger NULL deref: kasan: GPF could be caused by NULL-ptr deref or user memory access general protection fault: 0000 [#1] PREEMPT SMP KASAN RIP: xt_rateest_tg_checkentry+0x11d/0xb40 net/netfilter/xt_RATEEST.c:109 [..] xt_check_target+0x283/0x690 net/netfilter/x_tables.c:1019 check_target net/ipv4/netfilter/arp_tables.c:399 [inline] find_check_entry net/ipv4/netfilter/arp_tables.c:422 [inline] translate_table+0x1005/0x1d70 net/ipv4/netfilter/arp_tables.c:572 do_replace net/ipv4/netfilter/arp_tables.c:977 [inline] do_arpt_set_ctl+0x310/0x640 net/ipv4/netfilter/arp_tables.c:1456 Fixes: add67461240c1d ("netfilter: add struct net * to target parameters") Reported-by: syzbot+d7358a458d8a81aee898@syzkaller.appspotmail.com Signed-off-by: Florian Westphal Acked-by: Cong Wang Signed-off-by: Pablo Neira Ayuso Signed-off-by: Greg Kroah-Hartman --- net/ipv4/netfilter/arp_tables.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -384,10 +384,11 @@ next: ; return 1; } -static inline int check_target(struct arpt_entry *e, const char *name) +static int check_target(struct arpt_entry *e, struct net *net, const char *name) { struct xt_entry_target *t = arpt_get_target(e); struct xt_tgchk_param par = { + .net = net, .table = name, .entryinfo = e, .target = t->u.kernel.target, @@ -399,8 +400,9 @@ static inline int check_target(struct ar return xt_check_target(&par, t->u.target_size - sizeof(*t), 0, false); } -static inline int -find_check_entry(struct arpt_entry *e, const char *name, unsigned int size, +static int +find_check_entry(struct arpt_entry *e, struct net *net, const char *name, + unsigned int size, struct xt_percpu_counter_alloc_state *alloc_state) { struct xt_entry_target *t; @@ -419,7 +421,7 @@ find_check_entry(struct arpt_entry *e, c } t->u.kernel.target = target; - ret = check_target(e, name); + ret = check_target(e, net, name); if (ret) goto err; return 0; @@ -512,7 +514,9 @@ static inline void cleanup_entry(struct /* Checks and translates the user-supplied table segment (held in * newinfo). */ -static int translate_table(struct xt_table_info *newinfo, void *entry0, +static int translate_table(struct net *net, + struct xt_table_info *newinfo, + void *entry0, const struct arpt_replace *repl) { struct xt_percpu_counter_alloc_state alloc_state = { 0 }; @@ -569,7 +573,7 @@ static int translate_table(struct xt_tab /* Finally, each sanity check must pass */ i = 0; xt_entry_foreach(iter, entry0, newinfo->size) { - ret = find_check_entry(iter, repl->name, repl->size, + ret = find_check_entry(iter, net, repl->name, repl->size, &alloc_state); if (ret != 0) break; @@ -974,7 +978,7 @@ static int do_replace(struct net *net, c goto free_newinfo; } - ret = translate_table(newinfo, loc_cpu_entry, &tmp); + ret = translate_table(net, newinfo, loc_cpu_entry, &tmp); if (ret != 0) goto free_newinfo; @@ -1149,7 +1153,8 @@ compat_copy_entry_from_user(struct compa } } -static int translate_compat_table(struct xt_table_info **pinfo, +static int translate_compat_table(struct net *net, + struct xt_table_info **pinfo, void **pentry0, const struct compat_arpt_replace *compatr) { @@ -1217,7 +1222,7 @@ static int translate_compat_table(struct repl.num_counters = 0; repl.counters = NULL; repl.size = newinfo->size; - ret = translate_table(newinfo, entry1, &repl); + ret = translate_table(net, newinfo, entry1, &repl); if (ret) goto free_newinfo; @@ -1270,7 +1275,7 @@ static int compat_do_replace(struct net goto free_newinfo; } - ret = translate_compat_table(&newinfo, &loc_cpu_entry, &tmp); + ret = translate_compat_table(net, &newinfo, &loc_cpu_entry, &tmp); if (ret != 0) goto free_newinfo; @@ -1546,7 +1551,7 @@ int arpt_register_table(struct net *net, loc_cpu_entry = newinfo->entries; memcpy(loc_cpu_entry, repl->entries, repl->size); - ret = translate_table(newinfo, loc_cpu_entry, repl); + ret = translate_table(net, newinfo, loc_cpu_entry, repl); if (ret != 0) goto out_free;