From nobody Tue Dec 2 00:25:41 2025 Received: from mail-pl1-f174.google.com (mail-pl1-f174.google.com [209.85.214.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F06FB3168E3 for ; Mon, 24 Nov 2025 16:59:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764003562; cv=none; b=ODGoJ+3n3nZXfEmLl4bRtO/fXrGbo9URHJJr0Nl7C7mX17RyoiElr+VmRG9Wccosyk6AbeoNA3u6n+LxVDq1+VhHHjJ3/dQB35L0T3Fm09inkXHaL2wykI/OnpXE0ArwYwg9r3e99Bog/WLAhczafd2d73gwJctvILD7AuwsFpw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764003562; c=relaxed/simple; bh=Bk3vqHmWdWkagFl0OVdo/ww+OVIz0PyDQHSxBfQvGlI=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=p3S83zx6B/exY3La7/7InCTWD2tfXvEXL4DRnXo0p9ErT2MammHJCUunuRSFieF47roi5luoClQRjVlknWoXB851JaO76MNEetX4C6CA0wXmzMMSucvG11iazSvi729zSWbHmwuNSzwG3W+cf1HdrE/H6R0dBOW5FJ+IVDdoiAQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=EtKjwNfX; arc=none smtp.client-ip=209.85.214.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="EtKjwNfX" Received: by mail-pl1-f174.google.com with SMTP id d9443c01a7336-29555b384acso56220275ad.1 for ; Mon, 24 Nov 2025 08:59:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1764003560; x=1764608360; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=1+woEIj8vkU1m30QcrdiJOloh7+MvziDDhh8/XjkPb4=; b=EtKjwNfXhd3TRdrELn6jyzzJQmkpXbAW6uMDmxBdEu3Y28mzpMsF4qFBv2vQW3b2Yn AfnQKWyoQqbq7iOQdjHbXxlSolqSZ4hXxTBac784CebvRof6G9p8wyhI1o2zgGK4iNUf 9RSJ508n/0Que3hJe8kCiFGtEtr5UBN8f/EDm4iYPsK9jWHHQzlbF02nnJfiPwC4xYRz LYvx6579Z95b9SzL/5Ez3VdBpk47siXkORFhBG8CNpHXAg4m+1sUb7sjzl0DrLsvmIVO CdRwQhtRYzPSG8X0UnGNH5VS72Wa3F7wcW88qKqIODVTa2gZDgCNf0Uw1UV17reefJ5U L+kA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764003560; x=1764608360; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=1+woEIj8vkU1m30QcrdiJOloh7+MvziDDhh8/XjkPb4=; b=M5UAKvvCFP1LhmmeRbD7fN8lU6FzjU3GRcJbQKq/oTOcrAvZcDnB/oi0VNv4HDpDpt PtOruApuxrs0dGhanUdi2wMd74pCT9uA5TVmVLWIbukptRsh6fbxh4w5AUGpXTQm4X5A 6w7f7jciSrAr8+8Yle8mYmKyf7WIorEULbUiAquc+wx+xd6ygUJZBo9qtQb+PQQWzM37 vt5ZrnQQNOGmrAfffCdrG+KwcWFBzG0O1/fv2vnf3uCOjDBVSYQ4UUfpkv+dhzp9WKTJ 7gXcuaBgT+dDIQb7t1LdDIVYxSP/ciB5JF+EK7LonY5RWpudRoy3neXsiNMh/Gv4GbPS P10A== X-Forwarded-Encrypted: i=1; AJvYcCW7ktPtMihdfNV0cE9tCIjznyDiUMAEBz0YbI3Al7HZ+/wJexWxl2tgQxpwmwvp1JqMfrR5/Nk9aPv7Z5w=@vger.kernel.org X-Gm-Message-State: AOJu0Yx21rG+bdawcQtpU3QP78be2PQQaTuYVpWIv5PH7OcDFngLrri+ r5ToGivwsEmXvNQNZmTiol/X8wL8G99RcZ9ERUz29GUAdtIdqzCkLRsE X-Gm-Gg: ASbGnctwwss1p6dCOzBkohmOxuSzKlxAobKZRIC4L3XXZThh71ron1PmTF9wOg9B+Kp S2NAlKma18FOTXQAf3MGnk1Al77oGPkmtERE4P5PvffRQNnekT4282uoFy4dmNzdwle+YhyrngC 7pCNo15pCDe2x0T7llUGThhHU8a8x+eGEZgICWppHwdEQ9QGeg7xmLlyz6/xOo+DnC06IUDjGQp yUl5HlddeKgIBktcIa3Je0KyF+rLlGt+RxiyvutG+3EpUsaPGYGwIW5yyh/LAEnZA7F1xhHXKtp 4u5hxVK40G6EWN7Gyz0WMqj4mS8T0M5ApcHyqREZK35HQszcoek/Lr9hyO4Jnrj6/8iJ09KygQC +i97vtjxQ48Ffh1a9keWNZJb7qlsNJ7pqV7ZX5Cjp0Ds/56O8dtnWVkfot0xbMNhdpSxeGVXB3N BF5vCCijdJqi6IjG52uTliwn5sS8xASZWwK9a7tmishHayJLBinVX8ZW7wnpEcxarF6CcLo0t/y w== X-Google-Smtp-Source: AGHT+IE7XTNKN2xNsyxsyFaphLUAv/u1x81sEA6Y8Wx1rsqQSfsgsMr0eA0bt5j2VPOIs/w95ZV3Lw== X-Received: by 2002:a17:903:2451:b0:295:96bc:868c with SMTP id d9443c01a7336-29b6c3c23f6mr122664435ad.5.1764003559968; Mon, 24 Nov 2025 08:59:19 -0800 (PST) Received: from 2045D.localdomain (234.sub-72-110-77.myvzw.com. [72.110.77.234]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-29b5b13e720sm137316875ad.42.2025.11.24.08.59.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Nov 2025 08:59:19 -0800 (PST) From: Gui-Dong Han To: vt8231@hiddenengine.co.uk, linux@roeck-us.net Cc: linux-hwmon@vger.kernel.org, linux-kernel@vger.kernel.org, Gui-Dong Han Subject: [PATCH] hwmon: (vt8231) Convert macros to functions to avoid TOCTOU Date: Tue, 25 Nov 2025 00:59:00 +0800 Message-ID: <20251124165900.4713-1-hanguidong02@gmail.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The macro FAN_FROM_REG evaluates its arguments multiple times. When used with shared driver data, this leads to Time-of-Check to Time-of-Use (TOCTOU) race conditions, potentially causing divide-by-zero errors. Convert the macro to a static function to ensure arguments are evaluated only once. Additionally, in fan_div_store, move the reading of the old register value and the calculation of the minimum limit inside the update lock. This ensures that the read-modify-write sequence operates on consistent data, preventing race conditions during fan divider updates. Link: https://lore.kernel.org/all/CALbr=3DLYJ_ehtp53HXEVkSpYoub+XYSTU8Rg=3D= o1xxMJ8=3D5z8B-g@mail.gmail.com/ Signed-off-by: Gui-Dong Han --- Based on the discussion in the link, I will submit a series of patches to address TOCTOU issues in the hwmon subsystem by converting macros to functions or adjusting locking where appropriate. --- drivers/hwmon/vt8231.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c index 3bf27c21845b..617bbea60690 100644 --- a/drivers/hwmon/vt8231.c +++ b/drivers/hwmon/vt8231.c @@ -138,7 +138,12 @@ static inline u8 FAN_TO_REG(long rpm, int div) return clamp_val(1310720 / (rpm * div), 1, 255); } =20 -#define FAN_FROM_REG(val, div) ((val) =3D=3D 0 ? 0 : 1310720 / ((val) * (d= iv))) +static int fan_from_reg(int val, int div) +{ + if (val =3D=3D 0) + return 0; + return 1310720 / (val * div); +} =20 struct vt8231_data { unsigned short addr; @@ -561,7 +566,7 @@ static ssize_t fan_show(struct device *dev, struct devi= ce_attribute *attr, struct sensor_device_attribute *sensor_attr =3D to_sensor_dev_attr(attr); int nr =3D sensor_attr->index; struct vt8231_data *data =3D vt8231_update_device(dev); - return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr], + return sprintf(buf, "%d\n", fan_from_reg(data->fan[nr], DIV_FROM_REG(data->fan_div[nr]))); } =20 @@ -571,7 +576,7 @@ static ssize_t fan_min_show(struct device *dev, struct = device_attribute *attr, struct sensor_device_attribute *sensor_attr =3D to_sensor_dev_attr(attr); int nr =3D sensor_attr->index; struct vt8231_data *data =3D vt8231_update_device(dev); - return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr], + return sprintf(buf, "%d\n", fan_from_reg(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr]))); } =20 @@ -613,9 +618,8 @@ static ssize_t fan_div_store(struct device *dev, struct sensor_device_attribute *sensor_attr =3D to_sensor_dev_attr(attr); unsigned long val; int nr =3D sensor_attr->index; - int old =3D vt8231_read_value(data, VT8231_REG_FANDIV); - long min =3D FAN_FROM_REG(data->fan_min[nr], - DIV_FROM_REG(data->fan_div[nr])); + int old; + long min; int err; =20 err =3D kstrtoul(buf, 10, &val); @@ -623,6 +627,9 @@ static ssize_t fan_div_store(struct device *dev, return err; =20 mutex_lock(&data->update_lock); + old =3D vt8231_read_value(data, VT8231_REG_FANDIV); + min =3D fan_from_reg(data->fan_min[nr], + DIV_FROM_REG(data->fan_div[nr])); switch (val) { case 1: data->fan_div[nr] =3D 0; --=20 2.34.1