Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp3408080pxf; Mon, 29 Mar 2021 01:07:25 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxKfQUY2hkYE+g9exrsao1rXRX2DL/Dy18p9yFMvaiA9HuyQiY6V5Z11SLi3mmZ3hbkZcHD X-Received: by 2002:a17:906:1408:: with SMTP id p8mr26861860ejc.89.1617005244847; Mon, 29 Mar 2021 01:07:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1617005244; cv=none; d=google.com; s=arc-20160816; b=Ssl0M8c5sWvZiYZmB3uGYMq7qg+XNgio0iWBW+aqvttjj+vZ+pYfnwKHo7yzXRV6yZ sQaIwQqWI92s022haNnZsUWQlkfAAP/ONYcIZ/ZdmX35oEQ2sSjG+yd2I6uCViAxwsp0 87m93vqLUmaxmOU+OUSrCOQ2v6QwEQ+CoCT2yiangMlFnTvg/UqI9MZ95sqtRSvIwykN 8pjvTH2QDpCrac+x9BqRPoMi4zWWw+NleRmgj5klYnmwCO2KCrbn7S/StWAcTMjKenTt 83y3NHE03GkAqYzZrFnWiG/QeZ1+wrTThdnEIp52u1CBL0pWMvHddJJwcyZNndtBfztQ V9mQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=8Qmwnoj4DLFBjWqXSTluy2Qq6a5d20CfumMqUgaSXDo=; b=oifkQGC3/jC6IiDvdqlh4/f8Z9KAAcTttd2mMgSC6DcTOJtcvhI5/goQW4qqTwJWLj 0MXp6Tr6noDTHwgwX6BIm+UveuJNV7ZEkQ2CSuDCx58l/ZACRvmzPF4y4k/KU9fgqMAF As9PjdiUfTAd+TVHIADxbhyuocxeq6QR5hok2mBvQEV4qZ5QbgbLE/+pJCaoJ2LoGPPH dbLW+EtGCynyjECJzOc66gZIt15iVUYyGrcQH6784vhqyH0/Rg5yceRgTp3257pdT1MR CYFS1efTTxx8ojRZ6mUptDQdPmyC7yJ63laQ55Zz2nUvBPeDXuwfa8hAj+nT+i7IOO5g hXZA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=CxOPuNXU; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id h18si12415931ejd.89.2021.03.29.01.07.02; Mon, 29 Mar 2021 01:07:24 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=CxOPuNXU; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232292AbhC2IGF (ORCPT + 99 others); Mon, 29 Mar 2021 04:06:05 -0400 Received: from mail.kernel.org ([198.145.29.99]:46592 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231529AbhC2IDo (ORCPT ); Mon, 29 Mar 2021 04:03:44 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 7553E6197F; Mon, 29 Mar 2021 08:03:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1617005024; bh=tqZMQWvnmuLFIUGCzxrH5iKoGmauhrdvP5QFvrqN6aQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CxOPuNXU0y72/p8a6RwVplwX8WGl9Je374pdAmtk9roDetH+XVQGiNJmYfj38m/ya DPRVkyvFKBnLswW4I2I4RD23QEqM5jIiVgEou+PRUkejh/ZXXg2TtYGtsh6HarJVNt YhGJWh57C5NDXZ/NKVwYUFu9GKOQRxzDrTsk7p+U= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Eric Dumazet , syzbot , "David S. Miller" Subject: [PATCH 4.9 51/53] net: sched: validate stab values Date: Mon, 29 Mar 2021 09:58:26 +0200 Message-Id: <20210329075609.193504389@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210329075607.561619583@linuxfoundation.org> References: <20210329075607.561619583@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Eric Dumazet commit e323d865b36134e8c5c82c834df89109a5c60dab upstream. iproute2 package is well behaved, but malicious user space can provide illegal shift values and trigger UBSAN reports. Add stab parameter to red_check_params() to validate user input. syzbot reported: UBSAN: shift-out-of-bounds in ./include/net/red.h:312:18 shift exponent 111 is too large for 64-bit type 'long unsigned int' CPU: 1 PID: 14662 Comm: syz-executor.3 Not tainted 5.12.0-rc2-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:79 [inline] dump_stack+0x141/0x1d7 lib/dump_stack.c:120 ubsan_epilogue+0xb/0x5a lib/ubsan.c:148 __ubsan_handle_shift_out_of_bounds.cold+0xb1/0x181 lib/ubsan.c:327 red_calc_qavg_from_idle_time include/net/red.h:312 [inline] red_calc_qavg include/net/red.h:353 [inline] choke_enqueue.cold+0x18/0x3dd net/sched/sch_choke.c:221 __dev_xmit_skb net/core/dev.c:3837 [inline] __dev_queue_xmit+0x1943/0x2e00 net/core/dev.c:4150 neigh_hh_output include/net/neighbour.h:499 [inline] neigh_output include/net/neighbour.h:508 [inline] ip6_finish_output2+0x911/0x1700 net/ipv6/ip6_output.c:117 __ip6_finish_output net/ipv6/ip6_output.c:182 [inline] __ip6_finish_output+0x4c1/0xe10 net/ipv6/ip6_output.c:161 ip6_finish_output+0x35/0x200 net/ipv6/ip6_output.c:192 NF_HOOK_COND include/linux/netfilter.h:290 [inline] ip6_output+0x1e4/0x530 net/ipv6/ip6_output.c:215 dst_output include/net/dst.h:448 [inline] NF_HOOK include/linux/netfilter.h:301 [inline] NF_HOOK include/linux/netfilter.h:295 [inline] ip6_xmit+0x127e/0x1eb0 net/ipv6/ip6_output.c:320 inet6_csk_xmit+0x358/0x630 net/ipv6/inet6_connection_sock.c:135 dccp_transmit_skb+0x973/0x12c0 net/dccp/output.c:138 dccp_send_reset+0x21b/0x2b0 net/dccp/output.c:535 dccp_finish_passive_close net/dccp/proto.c:123 [inline] dccp_finish_passive_close+0xed/0x140 net/dccp/proto.c:118 dccp_terminate_connection net/dccp/proto.c:958 [inline] dccp_close+0xb3c/0xe60 net/dccp/proto.c:1028 inet_release+0x12e/0x280 net/ipv4/af_inet.c:431 inet6_release+0x4c/0x70 net/ipv6/af_inet6.c:478 __sock_release+0xcd/0x280 net/socket.c:599 sock_close+0x18/0x20 net/socket.c:1258 __fput+0x288/0x920 fs/file_table.c:280 task_work_run+0xdd/0x1a0 kernel/task_work.c:140 tracehook_notify_resume include/linux/tracehook.h:189 [inline] Fixes: 8afa10cbe281 ("net_sched: red: Avoid illegal values") Signed-off-by: Eric Dumazet Reported-by: syzbot Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- include/net/red.h | 10 +++++++++- net/sched/sch_choke.c | 7 ++++--- net/sched/sch_gred.c | 2 +- net/sched/sch_red.c | 7 +++++-- net/sched/sch_sfq.c | 2 +- 5 files changed, 20 insertions(+), 8 deletions(-) --- a/include/net/red.h +++ b/include/net/red.h @@ -167,7 +167,8 @@ static inline void red_set_vars(struct r v->qcount = -1; } -static inline bool red_check_params(u32 qth_min, u32 qth_max, u8 Wlog, u8 Scell_log) +static inline bool red_check_params(u32 qth_min, u32 qth_max, u8 Wlog, + u8 Scell_log, u8 *stab) { if (fls(qth_min) + Wlog > 32) return false; @@ -177,6 +178,13 @@ static inline bool red_check_params(u32 return false; if (qth_max < qth_min) return false; + if (stab) { + int i; + + for (i = 0; i < RED_STAB_SIZE; i++) + if (stab[i] >= 32) + return false; + } return true; } --- a/net/sched/sch_choke.c +++ b/net/sched/sch_choke.c @@ -409,6 +409,7 @@ static int choke_change(struct Qdisc *sc struct sk_buff **old = NULL; unsigned int mask; u32 max_P; + u8 *stab; if (opt == NULL) return -EINVAL; @@ -424,8 +425,8 @@ static int choke_change(struct Qdisc *sc max_P = tb[TCA_CHOKE_MAX_P] ? nla_get_u32(tb[TCA_CHOKE_MAX_P]) : 0; ctl = nla_data(tb[TCA_CHOKE_PARMS]); - - if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Scell_log)) + stab = nla_data(tb[TCA_CHOKE_STAB]); + if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Scell_log, stab)) return -EINVAL; if (ctl->limit > CHOKE_MAX_QUEUE) @@ -478,7 +479,7 @@ static int choke_change(struct Qdisc *sc red_set_parms(&q->parms, ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Plog, ctl->Scell_log, - nla_data(tb[TCA_CHOKE_STAB]), + stab, max_P); red_set_vars(&q->vars); --- a/net/sched/sch_gred.c +++ b/net/sched/sch_gred.c @@ -356,7 +356,7 @@ static inline int gred_change_vq(struct struct gred_sched *table = qdisc_priv(sch); struct gred_sched_data *q = table->tab[dp]; - if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Scell_log)) + if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Scell_log, stab)) return -EINVAL; if (!q) { --- a/net/sched/sch_red.c +++ b/net/sched/sch_red.c @@ -169,6 +169,7 @@ static int red_change(struct Qdisc *sch, struct Qdisc *child = NULL; int err; u32 max_P; + u8 *stab; if (opt == NULL) return -EINVAL; @@ -184,7 +185,9 @@ static int red_change(struct Qdisc *sch, max_P = tb[TCA_RED_MAX_P] ? nla_get_u32(tb[TCA_RED_MAX_P]) : 0; ctl = nla_data(tb[TCA_RED_PARMS]); - if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Scell_log)) + stab = nla_data(tb[TCA_RED_STAB]); + if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog, + ctl->Scell_log, stab)) return -EINVAL; if (ctl->limit > 0) { @@ -206,7 +209,7 @@ static int red_change(struct Qdisc *sch, red_set_parms(&q->parms, ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Plog, ctl->Scell_log, - nla_data(tb[TCA_RED_STAB]), + stab, max_P); red_set_vars(&q->vars); --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -645,7 +645,7 @@ static int sfq_change(struct Qdisc *sch, } if (ctl_v1 && !red_check_params(ctl_v1->qth_min, ctl_v1->qth_max, - ctl_v1->Wlog, ctl_v1->Scell_log)) + ctl_v1->Wlog, ctl_v1->Scell_log, NULL)) return -EINVAL; if (ctl_v1 && ctl_v1->qth_min) { p = kmalloc(sizeof(*p), GFP_KERNEL);