Received: by 2002:a05:6a10:2785:0:0:0:0 with SMTP id ia5csp18614pxb; Fri, 15 Jan 2021 04:50:06 -0800 (PST) X-Google-Smtp-Source: ABdhPJwIU78w/ldKi52gscCW+T04CDUfw7u5xaFFzGPWLMEbWaGq0IyKokN8qoQHsDo83kyZwJ7i X-Received: by 2002:a17:906:4146:: with SMTP id l6mr8687673ejk.341.1610715006265; Fri, 15 Jan 2021 04:50:06 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1610715006; cv=none; d=google.com; s=arc-20160816; b=gv7x7n5xIB+JpXtVAJBPo8kBd0uGo4SCYjKiwRTGZyra051jNdjv2b97xcyvNrT4ux KQlPhL+8fXwcktqOhqsrSH97Hk269h5q1Cs6qa1oCv+wx8cqvmuXGZLXsGDhzI6r0GKY G2q2CRFlUR9WwoX+P7kVObmIcXKB+CJTGPUVAhbhSFklEXg9AnEgqTsVC4IpXmxKMFk9 dHywgsdbwb0GwZQuJjIRuN8AbHcTjbEYpzl8FEGtievNAX5GGZuXBpn4eUtUqDc251So PRbHArMQlMf0gYiCtYgshSWlIH/zEURH0YIARrZ7CZtzAKZW0xGNjGyBgEQrPqc/pZ6b ljrg== 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=Tqe0u7a2JFp2lwvd95Gi3GAamt2kadGDKBqSqiYSe78=; b=MCMVWJih+IAL22Memq7X4ZQQIpXVPto0kbLEARrlH+wNN821NyVhKOJALBbX5Ek3h3 I6hGMqB72c4kr9EQqY/FcB45iqNOJ1Q0D7bzNMrDdPJ6GoUnyOIKEkI0iZ4ueH5FrpWD YzRQa8XaZuLda0y9mFyV7vu1dXme5I1Js14EaUMBjIPRsuzzyZdGVFUi4h8Xc7Krv/X3 RIcW9IZOckPsz+mW6A1PJXiycP0f6gUuzI3qdBaafOmSTGFabaMv+lGpHLeZdMbolQHH QrWJFmQ09q5lzzAzFVI5uf9tsygLidw1Q9XG4mZc1HHLfQOGeu/gnaNuN/WgFro2TXlG mJog== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=if8VwOiJ; 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 y6si1506115ejo.417.2021.01.15.04.49.42; Fri, 15 Jan 2021 04:50:06 -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=if8VwOiJ; 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 S1733179AbhAOMs5 (ORCPT + 99 others); Fri, 15 Jan 2021 07:48:57 -0500 Received: from mail.kernel.org ([198.145.29.99]:43894 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387673AbhAOMgp (ORCPT ); Fri, 15 Jan 2021 07:36:45 -0500 Received: by mail.kernel.org (Postfix) with ESMTPSA id 7D29823356; Fri, 15 Jan 2021 12:36:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1610714165; bh=VIexA2XB9xy5BgODHWhP/3FXyv92x9BGNj7K4Onq5C0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=if8VwOiJdzwJwJj4EAGnjJ59NuslyPaDbj6axC5B7/34oQyqO+nJ1LXfkO0lBTt4c /e+QiY+w7Xy6BI9KHuBp86yVt98R0eOwMm9MWx7Psa7/cyCLsMxpULENOcSAFFAa1c ma2wuo/JQh9OqOrD8ImMTEBMQz5sqAAZFw/lLY6M= 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.10 013/103] net: cdc_ncm: correct overhead in delayed_ndp_size Date: Fri, 15 Jan 2021 13:27:06 +0100 Message-Id: <20210115122006.687846128@linuxfoundation.org> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210115122006.047132306@linuxfoundation.org> References: <20210115122006.047132306@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 @@ -1199,7 +1199,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; @@ -1410,7 +1413,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 */