From patchwork Mon Oct 28 07:41:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2003138 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4XcQMr0C7Mz1xxZ for ; Mon, 28 Oct 2024 18:42:31 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1t5KOK-0002hL-Jz; Mon, 28 Oct 2024 07:42:20 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1t5KOH-0002gf-60 for kernel-team@lists.ubuntu.com; Mon, 28 Oct 2024 07:42:17 +0000 Received: from mail-pg1-f197.google.com (mail-pg1-f197.google.com [209.85.215.197]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id DB7AE3F175 for ; Mon, 28 Oct 2024 07:42:16 +0000 (UTC) Received: by mail-pg1-f197.google.com with SMTP id 41be03b00d2f7-7ea0069a8b0so3165749a12.0 for ; Mon, 28 Oct 2024 00:42:16 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730101335; x=1730706135; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=SbdSXm2TPN0uDBbhqrhsu9Iyy5AXdUaPSNoyNFZbHJY=; b=eNKfIz5X3SxVRDwodUHQY6s63BT2o933OXiQVuE6ok5+y4toZpHYOf7oQcp4IjRAzH t+bSvnLpGBbbw4khU4UFZSFSae2kZTQ9+vw+612GUBIvDaGSDSRb+/F/QysapztQtGSV YQPl4Sx/wD1XWg8i0XMw61K6tq3ksJY5hs2FbHuOkGIFyA/fqc6yrWheGdLozyX3LyPs rRWK0lME7f0kgF6sq7jah6RbnzdCa1LVJmP/D+4LmYgdYpRTsI8+pha3o0Qlm0qS43wl juPzVEJz3KK7euxVsqYRI0j7ukS4qaRBPmyr7ElludGQ3GpNuOMBquprWT5dW/fAfyer FPKw== X-Gm-Message-State: AOJu0YxT7DvbzUbhFR1+s38Lp9OXST1tGSJokvrB1/O1RAhxoJaPGJo+ /0p7YXhx2IPllxlYCBZ88OVbh6AKBd9t6+8Nwqye8LxcVeww5tBJQm60/4Er3W6SKCskdRI0im5 dhnn6SbJ+zPjcmGxkTepC3J2vhK0mrIVoUqfEuurQ+1OM1w9cmRcPoZMSR80MoOn7+ND8y/xxFo +/wyvav78X6w== X-Received: by 2002:a05:6a21:670b:b0:1d9:275b:4ef9 with SMTP id adf61e73a8af0-1d9a842e01cmr10075485637.19.1730101335206; Mon, 28 Oct 2024 00:42:15 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEEE8KpATBBLK1J784VRvwfHyLsTDGp2lIV0qDjYFDSDpFVaNu+Kb+Wq3ozXSP5U9xRvulTig== X-Received: by 2002:a05:6a21:670b:b0:1d9:275b:4ef9 with SMTP id adf61e73a8af0-1d9a842e01cmr10075468637.19.1730101334709; Mon, 28 Oct 2024 00:42:14 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:fc2f:5f77:13cb:653f]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-210bc0167f3sm45344785ad.150.2024.10.28.00.42.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Oct 2024 00:42:14 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][F][PATCH v2 1/3] net: asix: fix uninit value bugs Date: Mon, 28 Oct 2024 16:41:38 +0900 Message-ID: <20241028074150.112511-2-koichiro.den@canonical.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241028074150.112511-1-koichiro.den@canonical.com> References: <20241028074150.112511-1-koichiro.den@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Pavel Skripkin Syzbot reported uninit-value in asix_mdio_read(). The problem was in missing error handling. asix_read_cmd() should initialize passed stack variable smsr, but it can fail in some cases. Then while condidition checks possibly uninit smsr variable. Since smsr is uninitialized stack variable, driver can misbehave, because smsr will be random in case of asix_read_cmd() failure. Fix it by adding error handling and just continue the loop instead of checking uninit value. Added helper function for checking Host_En bit, since wrong loop was used in 4 functions and there is no need in copy-pasting code parts. Cc: Robert Foss Fixes: d9fe64e51114 ("net: asix: Add in_pm parameter") Reported-by: syzbot+a631ec9e717fb0423053@syzkaller.appspotmail.com Signed-off-by: Pavel Skripkin Signed-off-by: David S. Miller (backported from commit a786e3195d6af183033e86f0518ffd2c51c0e8ac) [koichiroden: Adjusted context due to missing commit d275afb66371 ("net: usb: asix: add error handling for asix_mdio_* functions"), which in turn depends on e532a096be0e ("net: usb: asix: ax88772: add phylib support"). Ref. [PATCH net-next v2 0/8] port asix ax88772 to the PHYlib https://lore.kernel.org/linux-usb/20210607082727.26045-1-o.rempel@pengutronix.de/] CVE-2021-47101 Signed-off-by: Koichiro Den --- drivers/net/usb/asix_common.c | 71 +++++++++++++++-------------------- 1 file changed, 31 insertions(+), 40 deletions(-) diff --git a/drivers/net/usb/asix_common.c b/drivers/net/usb/asix_common.c index 7bc6e8f856fe..12ce52600eaf 100644 --- a/drivers/net/usb/asix_common.c +++ b/drivers/net/usb/asix_common.c @@ -63,6 +63,29 @@ void asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, value, index, data, size); } +static int asix_check_host_enable(struct usbnet *dev, int in_pm) +{ + int i, ret; + u8 smsr; + + for (i = 0; i < 30; ++i) { + ret = asix_set_sw_mii(dev, in_pm); + if (ret == -ENODEV || ret == -ETIMEDOUT) + break; + usleep_range(1000, 1100); + ret = asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, + 0, 0, 1, &smsr, in_pm); + if (ret == -ENODEV) + break; + else if (ret < 0) + continue; + else if (smsr & AX_HOST_EN) + break; + } + + return ret; +} + static void reset_asix_rx_fixup_info(struct asix_rx_fixup_info *rx) { /* Reset the variables that have a lifetime outside of @@ -445,19 +468,11 @@ int asix_mdio_read(struct net_device *netdev, int phy_id, int loc) { struct usbnet *dev = netdev_priv(netdev); __le16 res; - u8 smsr; - int i = 0; int ret; mutex_lock(&dev->phy_mutex); - do { - ret = asix_set_sw_mii(dev, 0); - if (ret == -ENODEV || ret == -ETIMEDOUT) - break; - usleep_range(1000, 1100); - ret = asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, - 0, 0, 1, &smsr, 0); - } while (!(smsr & AX_HOST_EN) && (i++ < 30) && (ret != -ENODEV)); + + ret = asix_check_host_enable(dev, 0); if (ret == -ENODEV || ret == -ETIMEDOUT) { mutex_unlock(&dev->phy_mutex); return ret; @@ -478,22 +493,14 @@ void asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val) { struct usbnet *dev = netdev_priv(netdev); __le16 res = cpu_to_le16(val); - u8 smsr; - int i = 0; int ret; netdev_dbg(dev->net, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n", phy_id, loc, val); mutex_lock(&dev->phy_mutex); - do { - ret = asix_set_sw_mii(dev, 0); - if (ret == -ENODEV) - break; - usleep_range(1000, 1100); - ret = asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, - 0, 0, 1, &smsr, 0); - } while (!(smsr & AX_HOST_EN) && (i++ < 30) && (ret != -ENODEV)); + + ret = asix_check_host_enable(dev, 0); if (ret == -ENODEV) { mutex_unlock(&dev->phy_mutex); return; @@ -509,19 +516,11 @@ int asix_mdio_read_nopm(struct net_device *netdev, int phy_id, int loc) { struct usbnet *dev = netdev_priv(netdev); __le16 res; - u8 smsr; - int i = 0; int ret; mutex_lock(&dev->phy_mutex); - do { - ret = asix_set_sw_mii(dev, 1); - if (ret == -ENODEV || ret == -ETIMEDOUT) - break; - usleep_range(1000, 1100); - ret = asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, - 0, 0, 1, &smsr, 1); - } while (!(smsr & AX_HOST_EN) && (i++ < 30) && (ret != -ENODEV)); + + ret = asix_check_host_enable(dev, 1); if (ret == -ENODEV || ret == -ETIMEDOUT) { mutex_unlock(&dev->phy_mutex); return ret; @@ -543,22 +542,14 @@ asix_mdio_write_nopm(struct net_device *netdev, int phy_id, int loc, int val) { struct usbnet *dev = netdev_priv(netdev); __le16 res = cpu_to_le16(val); - u8 smsr; - int i = 0; int ret; netdev_dbg(dev->net, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n", phy_id, loc, val); mutex_lock(&dev->phy_mutex); - do { - ret = asix_set_sw_mii(dev, 1); - if (ret == -ENODEV) - break; - usleep_range(1000, 1100); - ret = asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, - 0, 0, 1, &smsr, 1); - } while (!(smsr & AX_HOST_EN) && (i++ < 30) && (ret != -ENODEV)); + + ret = asix_check_host_enable(dev, 1); if (ret == -ENODEV) { mutex_unlock(&dev->phy_mutex); return;