Received: by 2002:a05:6a10:2785:0:0:0:0 with SMTP id ia5csp11266pxb; Fri, 15 Jan 2021 04:37:25 -0800 (PST) X-Google-Smtp-Source: ABdhPJwd6mr9N527reuJ/Z8YA9ozcGwRKu0QRd80KqApxQ0beglQNoHbeFWTtqTT87fGDum6thCv X-Received: by 2002:a05:6402:7d7:: with SMTP id u23mr9153874edy.325.1610714245173; Fri, 15 Jan 2021 04:37:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1610714245; cv=none; d=google.com; s=arc-20160816; b=NDintMlJnuRlOc1klxXjFg2Wm1FEeIlQHR86jdnYKlYZueyhI97g50azc5+ciGa9oK 7je/AYa3vyIlax0+qO17LvRznuJHh4Lm8cWS1Lp+sMoaj2z/ujMr/pihFfhFxKmom3Ff dvPhU6XZwvNzTAb+Kh7kQPF3XMunYVS0iehBog4JMZJ/LSxWyeU3sFKFaJITjYCA560b KE/cDtrojDjHQlS/lCa70aswP1uA2L8bNS4iG7uRhQ5zIQviOlUB+Asya5dZRiLOj5LB QzsuVeH0hqKnVN/rKYlF16BruxtqnC++IXhZ0z/NbLOICce+4MzNt5dR70frwwiS+C3Z SBkA== 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=tz/jrph2eVtetmy//IPbaSV/58p3lFbQnlpbaKqilEA=; b=1CqTJ7Mb8n2je2eYQsQWeq3gnB0A8T9REkELJF5eneCbetgdJwCHCxt5aqmA5vKIv3 nVcN06Kha9wuidYtTTdLSQSzZhfx81TUVtJWyEogeudI37D+4PDpueRTQiUIeI2tTIHk kGRewXIGDRNtvuYDpj37cTRBm6VRv7yz6lm4VU4Unu8RkzFFe9AKcYZQaz8Hb42ZLdn8 RMdoJuc5Bp1XAEeB/dq7OTM5KNTrsV2KlmwQoSE3G0LGUQA9ASnK6zEqwMdoAdQElAQn Ryfyw9+KT6jFjSRC9hA7YEH/XQIc/USFwsnqcuPfAVsR8Q5YyLIYcItWwOwLT7KMGT/N xv8w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b="uef/yA8F"; 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 m10si3674157eji.137.2021.01.15.04.37.00; Fri, 15 Jan 2021 04:37:25 -0800 (PST) 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="uef/yA8F"; 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 S2387501AbhAOMei (ORCPT + 99 others); Fri, 15 Jan 2021 07:34:38 -0500 Received: from mail.kernel.org ([198.145.29.99]:41284 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387465AbhAOMeY (ORCPT ); Fri, 15 Jan 2021 07:34:24 -0500 Received: by mail.kernel.org (Postfix) with ESMTPSA id 5F0B523370; Fri, 15 Jan 2021 12:33:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1610714023; bh=Ezy3JaWQRCyS1ArtIJlFN47/XhhNKgcWf6RBUjyAxGo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uef/yA8F4ET7uKEaPjXOwfMlcmWT26IdBDePDxQ9aYJ5hLU5x8WoUkIktC59+GVGu cRjGHG3GnLgdrZUzg1eP6gEideFbKk7AaxJ139/FFDJp5hvk3mmk3uLHeslZr44cUv Qk5uDLAVJocU8porISvJ916Dw1YRvnsAvIvjInj4= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, "=?UTF-8?q?Jouni=20K . =20Sepp=C3=A4nen?=" , kernel test robot , =?UTF-8?q?Bj=C3=B8rn=20Mork?= , "David S. Miller" Subject: [PATCH 5.4 03/62] net: cdc_ncm: correct overhead in delayed_ndp_size Date: Fri, 15 Jan 2021 13:27:25 +0100 Message-Id: <20210115121958.566466769@linuxfoundation.org> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210115121958.391610178@linuxfoundation.org> References: <20210115121958.391610178@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: "Jouni K. Sepp?nen" [ Upstream commit 7a68d725e4ea384977445e0bcaed3d7de83ab5b3 ] Aligning to tx_ndp_modulus is not sufficient because the next align call can be cdc_ncm_align_tail, which can add up to ctx->tx_modulus + ctx->tx_remainder - 1 bytes. This used to lead to occasional crashes on a Huawei 909s-120 LTE module as follows: - the condition marked /* if there is a remaining skb [...] */ is true so the swaps happen - skb_out is set from ctx->tx_curr_skb - skb_out->len is exactly 0x3f52 - ctx->tx_curr_size is 0x4000 and delayed_ndp_size is 0xac (note that the sum of skb_out->len and delayed_ndp_size is 0x3ffe) - the for loop over n is executed once - the cdc_ncm_align_tail call marked /* align beginning of next frame */ increases skb_out->len to 0x3f56 (the sum is now 0x4002) - the condition marked /* check if we had enough room left [...] */ is false so we break out of the loop - the condition marked /* If requested, put NDP at end of frame. */ is true so the NDP is written into skb_out - now skb_out->len is 0x4002, so padding_count is minus two interpreted as an unsigned number, which is used as the length argument to memset, leading to a crash with various symptoms but usually including > Call Trace: > > cdc_ncm_fill_tx_frame+0x83a/0x970 [cdc_ncm] > cdc_mbim_tx_fixup+0x1d9/0x240 [cdc_mbim] > usbnet_start_xmit+0x5d/0x720 [usbnet] The cdc_ncm_align_tail call first aligns on a ctx->tx_modulus boundary (adding at most ctx->tx_modulus-1 bytes), then adds ctx->tx_remainder bytes. Alternatively, the next alignment call can occur in cdc_ncm_ndp16 or cdc_ncm_ndp32, in which case at most ctx->tx_ndp_modulus-1 bytes are added. A similar problem has occurred before, and the code is nontrivial to reason about, so add a guard before the crashing call. By that time it is too late to prevent any memory corruption (we'll have written past the end of the buffer already) but we can at least try to get a warning written into an on-disk log by avoiding the hard crash caused by padding past the buffer with a huge number of zeros. Signed-off-by: Jouni K. Seppänen Fixes: 4a0e3e989d66 ("cdc_ncm: Add support for moving NDP to end of NCM frame") Link: https://bugzilla.kernel.org/show_bug.cgi?id=209407 Reported-by: kernel test robot Reviewed-by: Bjørn Mork Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/cdc_ncm.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -1126,7 +1126,10 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev * accordingly. Otherwise, we should check here. */ if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) - delayed_ndp_size = ALIGN(ctx->max_ndp_size, ctx->tx_ndp_modulus); + delayed_ndp_size = ctx->max_ndp_size + + max_t(u32, + ctx->tx_ndp_modulus, + ctx->tx_modulus + ctx->tx_remainder) - 1; else delayed_ndp_size = 0; @@ -1307,7 +1310,8 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev if (!(dev->driver_info->flags & FLAG_SEND_ZLP) && skb_out->len > ctx->min_tx_pkt) { padding_count = ctx->tx_curr_size - skb_out->len; - skb_put_zero(skb_out, padding_count); + if (!WARN_ON(padding_count > ctx->tx_curr_size)) + skb_put_zero(skb_out, padding_count); } else if (skb_out->len < ctx->tx_curr_size && (skb_out->len % dev->maxpacket) == 0) { skb_put_u8(skb_out, 0); /* force short packet */