From patchwork Tue Sep 24 17:37:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nick Desaulniers X-Patchwork-Id: 174294 Delivered-To: patch@linaro.org Received: by 2002:ac9:19ad:0:0:0:0:0 with SMTP id d45csp4126617oce; Tue, 24 Sep 2019 10:37:33 -0700 (PDT) X-Google-Smtp-Source: APXvYqyWzJDF6m5TC3d1pYQfEDtMDjrRYSsfTd7oIo61SEjI+SwjyXVZUIbbOfG0aBmOagbFRGAA X-Received: by 2002:a17:906:53d6:: with SMTP id p22mr3632403ejo.91.1569346653523; Tue, 24 Sep 2019 10:37:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1569346653; cv=none; d=google.com; s=arc-20160816; b=XC1pNPAp6NMNvstX/DYqgGD0bUpwq+HYMfH2L0bQadbqpxObINxO2CFRqyGcjMat3q l7r3re2mRtPAPAl2c2Z0OwfxEQ2RztEoqseaDof/QDt79PfHjxJS/f3891HUWaQdy/3W zghvVefkjhuyjznjfmZElv6o0xBa7j06VXf51+M1dm5Mf6/P+8/CT0TOKMB/BjhHI6IL 6HVKkR3J+KFVV3cPmUGDJB1zjBFe7wRA6ypi96iyy+sQ46b8ezlqLDagIHacOX6zBCJl ou9GwE/gpYIBFPXzGa1je0rwO8V9fekLCy9Gfs2xvI3ib3BzimSMwP08v3z+eA7mCzU+ U5Qw== 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:cc:to:from :subject:mime-version:message-id:date:dkim-signature; bh=cqlaQgskXZZonmcDyxSMH60accriyGsyjcSMTQXFDVo=; b=Z3KOo0oTHC4d2F12u+Yjam3i9YUF5QuC3oaZkPaOR6kNq0kp/QjcwtflkQp+EQ4sZq qV/Vpyjz3RixUskMaOn8m4UitHyPFFLavoOURoAkLVellzL6UkmWI//WeYNp00KH5XVs 3ec0A/0ToOpyjE+rD8njDNJI0ailLqFUjBTvqXcIBEu7v1KJdY/b69wa4sh8qyKHZHF8 cxTRWZE88tO9dPGqjHTY7PR1IQ+7Jv7uCexh89RY0xhJW57X665Bj4h3Uvqk3MmN2pIo 7vfRiLY3MSeUGNcCvitutDZIl8l6oxFuNSmyXpZeqxzHPe0ImiXK9LfVsPGFD47rlAm/ mqXA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=GrQ96GoV; 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; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id jr9si1266387ejb.118.2019.09.24.10.37.33; Tue, 24 Sep 2019 10:37:33 -0700 (PDT) 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=@google.com header.s=20161025 header.b=GrQ96GoV; 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; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2502058AbfIXRhc (ORCPT + 26 others); Tue, 24 Sep 2019 13:37:32 -0400 Received: from mail-vk1-f201.google.com ([209.85.221.201]:40572 "EHLO mail-vk1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728460AbfIXRhc (ORCPT ); Tue, 24 Sep 2019 13:37:32 -0400 Received: by mail-vk1-f201.google.com with SMTP id 70so12469vkc.7 for ; Tue, 24 Sep 2019 10:37:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:message-id:mime-version:subject:from:to:cc :content-transfer-encoding; bh=cqlaQgskXZZonmcDyxSMH60accriyGsyjcSMTQXFDVo=; b=GrQ96GoVZCaNN10oq89i4aHnK6PqT2oRCB+KP7YvdXoO+LiXCSCjS521zmlVq6Ngzw fM2S18l+9Km3sNnAmAbitUsbC6SBoKbGecKzFdVmVg1AxV6EUHdpe8i38U4Gj+i4HC0t lrej3ZbBabIukl5yDVt6G/jtjgKZC8hsElSG15QXzs6TipHUEECTZyCxOp2xv0c9a5hJ U+sLpWkh0OMCYw2zirPhoETlurM94zdCChQgipuBAFlG76p+hCpvnCjGoScdYPmbyYBb j8Cw160KdYDFqJY1r2MoFJESTBVjT6gMqXG/ZveD/85LX+62wRCDEewHYGBUeCbkQlmB 0zdg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:message-id:mime-version:subject:from:to:cc :content-transfer-encoding; bh=cqlaQgskXZZonmcDyxSMH60accriyGsyjcSMTQXFDVo=; b=Ad1pdvA1W5tfYX3WummEIzUtQuGK2fv1oTZhZgOE9t/0Jy1yX9udnwVVX3tBLEAh+q 2ahbxA1ArW0CuApfs6exHnO2v3rxrOSVmZJFLas9PKd6CVFbdGb3wLyvFnptHT5QAcys xmRLDeEW6zjJXJC6h+otytEi7wBMJijzmLnL5YD9bdlSugyKi33vctBrwXnEu4dXLgpc ZrSrDx36W/byX99ylhYflZ7bCOyDzxDrXczQ9uFJ9s4u6nJRQjHbjv1hc4BHg1maPTpG J9elJWSgm/t6ApnK2Nfri/+J0B2vveCimJODxmKJl2Jbg8C2W5Upe1OP0AOz9LJgmTs8 sDFA== X-Gm-Message-State: APjAAAW6ZTFK9LOmXjVuOh3VIRXQKH/HX0miU9R6o2d3qjyQkp76Gh+B WWwm+WjCl2CUjoWEKmeVjbkTkB4LLuznhzPogyk= X-Received: by 2002:a1f:3f10:: with SMTP id m16mr11725vka.15.1569346649344; Tue, 24 Sep 2019 10:37:29 -0700 (PDT) Date: Tue, 24 Sep 2019 10:37:17 -0700 Message-Id: <20190924173717.198637-1-ndesaulniers@google.com> Mime-Version: 1.0 X-Mailer: git-send-email 2.23.0.351.gc4317032e6-goog Subject: [PATCH] hwmon: (applesmc) fix UB and udelay overflow From: Nick Desaulniers To: linux@roeck-us.net Cc: clang-built-linux@googlegroups.com, jdelvare@suse.com, Nick Desaulniers , "=?UTF-8?q?Tomasz=20Pawe=C5=82=20Gajc?=" , Nathan Chancellor , Henrik Rydberg , linux-hwmon@vger.kernel.org, linux-kernel@vger.kernel.org Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Fixes the following 2 issues in the driver: 1. Left shifting a signed integer is undefined behavior. Unsigned integral types should be used for bitwise operations. 2. The delay scales from 0x0010 to 0x20000 by powers of 2, but udelay will result in a linkage failure when given a constant that's greater than 20000 (0x4E20). Agressive loop unrolling can fully unroll the loop, resulting in later iterations overflowing the call to udelay. 2 is fixed via splitting the loop in two, iterating the first up to the point where udelay would overflow, then switching to mdelay, as suggested in Documentation/timers/timers-howto.rst. Reported-by: Tomasz Paweł Gajc Link: https://github.com/ClangBuiltLinux/linux/issues/678 Debugged-by: Nathan Chancellor Signed-off-by: Nick Desaulniers --- drivers/hwmon/applesmc.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) -- 2.23.0.351.gc4317032e6-goog diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 183ff3d25129..2bc12812f52f 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -46,6 +46,7 @@ #define APPLESMC_MIN_WAIT 0x0010 #define APPLESMC_RETRY_WAIT 0x0100 #define APPLESMC_MAX_WAIT 0x20000 +#define APPLESMC_UDELAY_MAX 20000 #define APPLESMC_READ_CMD 0x10 #define APPLESMC_WRITE_CMD 0x11 @@ -157,14 +158,23 @@ static struct workqueue_struct *applesmc_led_wq; static int wait_read(void) { u8 status; - int us; - for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) { + unsigned int us; + + for (us = APPLESMC_MIN_WAIT; us < APPLESMC_UDELAY_MAX; us <<= 1) { udelay(us); status = inb(APPLESMC_CMD_PORT); /* read: wait for smc to settle */ if (status & 0x01) return 0; } + /* switch to mdelay for longer sleeps */ + for (; us < APPLESMC_MAX_WAIT; us <<= 1) { + mdelay(us); + status = inb(APPLESMC_CMD_PORT); + /* read: wait for smc to settle */ + if (status & 0x01) + return 0; + } pr_warn("wait_read() fail: 0x%02x\n", status); return -EIO; @@ -177,10 +187,10 @@ static int wait_read(void) static int send_byte(u8 cmd, u16 port) { u8 status; - int us; + unsigned int us; outb(cmd, port); - for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) { + for (us = APPLESMC_MIN_WAIT; us < APPLESMC_UDELAY_MAX; us <<= 1) { udelay(us); status = inb(APPLESMC_CMD_PORT); /* write: wait for smc to settle */ @@ -196,6 +206,23 @@ static int send_byte(u8 cmd, u16 port) udelay(APPLESMC_RETRY_WAIT); outb(cmd, port); } + /* switch to mdelay for longer sleeps */ + for (; us < APPLESMC_MAX_WAIT; us <<= 1) { + mdelay(us); + status = inb(APPLESMC_CMD_PORT); + /* write: wait for smc to settle */ + if (status & 0x02) + continue; + /* ready: cmd accepted, return */ + if (status & 0x04) + return 0; + /* timeout: give up */ + if (us << 1 == APPLESMC_MAX_WAIT) + break; + /* busy: long wait and resend */ + udelay(APPLESMC_RETRY_WAIT); + outb(cmd, port); + } pr_warn("send_byte(0x%02x, 0x%04x) fail: 0x%02x\n", cmd, port, status); return -EIO;