From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pf1-f174.google.com (mail-pf1-f174.google.com [209.85.210.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 4A2A83624B2 for ; Fri, 12 Jun 2026 06:05:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.174 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781244319; cv=none; b=hlvtAX/PwfjvTnGV0ywR4onJcVQzSG8r+S2ciUo3hHKHkfEjnbhQpM3RjpTABRbIMHJWjzoX3lFOYDD9RZ/wuo0NFe2lh1EtLYIWGjrvj4KqtTbIyaXsmcrPDoQq7cGXqNarsuFB5YmQcl1oRoo96+AYmJ13YCZlOScTRXqUjB8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781244319; c=relaxed/simple; bh=RGbsxkupUge19BKTktVT3c2j6x8Gro8DhveJEyZMbKE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=aefotNsQXz53T0EHbD3b7iMzT0rna/VbJjt2m9rOZoHM454vLOAUrsc2soVaqbgLAW0sVYoztx395dfwML72xF8ZbHNceUgHk2kiytgaIdtPo3FN2H/bbnLcAKnHV3a0GfkblJg7d7khKqYZvhQ4+1HNYUM+AXGmRRA4gEU6yJc= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=CuE0C/+n; arc=none smtp.client-ip=209.85.210.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="CuE0C/+n" Received: by mail-pf1-f174.google.com with SMTP id d2e1a72fcca58-84237c55ef9so477936b3a.0 for ; Thu, 11 Jun 2026 23:05:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1781244309; x=1781849109; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=gZhVY0AvrduauhTvBrssxSpj3AMAEp/6iK3/KNj+gtk=; b=CuE0C/+nwi8OqN+tUGUujBoRSGDeHTJ6UhhelCWrb2v43Lj2TlEJrmDGWaysaSLiNs i6yFCwt9q10D9V4p6aBtTYSlBO13jimt/HjOP1+GAKgR4mBy79O9wDfb9q62qJQaSxUi M+1D/9PIhzA1nZo51J2GqJBx+4BcMcLfOn35c= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781244309; x=1781849109; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=gZhVY0AvrduauhTvBrssxSpj3AMAEp/6iK3/KNj+gtk=; b=MRH32S99h6mjfKw+5ZPpZV+HRN4e1uSw6HQQvrw369HZPJ3w6k1f6wCffBnT8gim4w 9YAqvt8vv0zUpokzgBrnYGBQjHGrr3qftBB57FtjBKD/VUtD5zonKptD6zgkBMc3grS4 cTuV2XAPZoZz5zPZZZcEj9LVJoQ0V557OI+sanvGpUo5F6J4elWh7oNus9AInInWntkU Va8tW0h+/lettvbUy9y8N5psJEyjBYrdVJ4TwjA4DaYP+EIKlJ9VmVSCPjOunEDfWUjU MpMOoqTkRJ0DdQgQoWr4hJNu3/PYN53XATTbWlgpvpwj+6nvvAOpkQmZWpQdfChYyrWt x+cg== X-Forwarded-Encrypted: i=1; AFNElJ8B1JOUuMK7W1GM5v+UCxtADEC6EZfU0AFiRWAbJ/avef0AcYsBBW7rxDzbUcaswUD2DNVH8PEUGIe8cbM=@vger.kernel.org X-Gm-Message-State: AOJu0YwGGJnMvAJT2PFGoVBkLksoPeA+jf45D85ZsBwj0LUp6TaMJ5Kd leNKRJ1WzPLZwgYRqjP9yMRZx5PgoxcCrsFJrssFiegaaUhDb2NDzCsIGgb5ZzSTXJuDqoTZM4k xWImH3w== X-Gm-Gg: Acq92OE7KpoYzDPcrmyVoV3qhXnIXvixK6e1AAlw24fuz6FjMAIib8yE48aMrk1B5bM 0AnQBTVZJGyXOj5rIvYSSwNaCuM8T8nhHhTEoHMuRHFlbDdcZhiqs48TahhS9BBmAL0V/iTmtME GNl/UlKpEDLipzImhC9moP0yc+3cL1ZQR2TZLs1poaX5rLD+RLq4VUF9iK14OVwaOrkNrUaA6E/ LsWMdp/5/p1wp7s3PaoVZXZIaNOcebOnK587DSHAj1s2nEuM3wYQm/xa1Uc0XEPjp8Iq8Cw89wC sbriOc+pp0ksiAtURlkOva16YyUnQt3Cr3Fzrm32dOJmmsWefSEGhDHmcnfSX9Z71sXQZKVI6yp 2w8/GoSvHz7meqNR6cKiQ+DAHUqZcRKC9yYjEDODRST/tbhjO6AJ6tc9QRpJv00dhnw+aAsTXuD zDlyKvXrzPdg8yVOrOv5J82ZsYHDd0h29hmNa7sjZY/wEe0GRf6TnRxU88q+YvRpeMrwBJEgUQz 6mkn1hEqHA2zd3Oc/vqd0sGqGQQ16ETyrk= X-Received: by 2002:a05:6a00:4fc7:b0:842:54c1:8e15 with SMTP id d2e1a72fcca58-8434ce42058mr1569469b3a.29.1781244309171; Thu, 11 Jun 2026 23:05:09 -0700 (PDT) Received: from ranjankumar.c.googlers.com.com (127.128.126.34.bc.googleusercontent.com. [34.126.128.127]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-8434b04808dsm1084616b3a.52.2026.06.11.23.05.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 Jun 2026 23:05:08 -0700 (PDT) From: Ranjan Kumar To: dmitry.torokhov@gmail.com Cc: bleung@chromium.org, bentiss@kernel.org, linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, Ranjan Kumar Subject: [PATCH v4] Input: elan_i2c - prevent division by zero and arithmetic underflow Date: Fri, 12 Jun 2026 06:03:39 +0000 Message-ID: <20260612060339.3829666-1-kumarranja@chromium.org> X-Mailer: git-send-email 2.54.0.1136.gdb2ca164c4-goog In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit The Elan I2C touchpad driver queries the device for its physical dimensions and trace counts to calculate the device resolution and width. However, if the device firmware or device tree provides invalid zero values for x_traces or y_traces, it results in a fatal division-by-zero exception leading to a kernel panic during device probe. Add checks to ensure these parameters are non-zero before performing the division. If invalid trace values are detected, fall back to a safe default of 1. Additionally, prevent an arithmetic underflow in the touch reporting logic. Previously, if the calculated or fallback width was smaller than ETP_FWIDTH_REDUCE (90), the subtraction would underflow, resulting in a massive unsigned integer being reported to userspace. Clamp the adjusted width to a minimum of 0 to safely handle small physical dimensions and fallback scenarios. Completing the probe with safe fallback values ensures the sysfs nodes are created, keeping the firmware update path intact so a recovery firmware can be flashed to the device. Fixes: 6696777c6506 ("Input: add driver for Elan I2C/SMbus touchpad") Fixes: e3a9a1290688 ("Input: elan_i2c - do not query the info if they are provided") Signed-off-by: Ranjan Kumar --- Changes in v4: - Reverted probe fallback width back to 1. - Added check in elan_report_contact() to clamp adjusted widths to a minimum of 0, fixing the root cause of the arithmetic underflow. Changes in v3: - Changed fallback width from 1 to ETP_FWIDTH_REDUCE to prevent underflow. Changes in v2: - Added check for invalid trace values of 0 to prevent division by zero. drivers/input/mouse/elan_i2c_core.c | 36 ++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c index 5cba02a156ce..edb0a28d25aa 100644 --- a/drivers/input/mouse/elan_i2c_core.c +++ b/drivers/input/mouse/elan_i2c_core.c @@ -428,8 +428,17 @@ static int elan_query_device_parameters(struct elan_tp_data *data) if (error) return error; } - data->width_x = data->max_x / x_traces; - data->width_y = data->max_y / y_traces; + + if (!x_traces || !y_traces) { + dev_warn(&client->dev, + "invalid trace numbers: x=%u, y=%u\n", + x_traces, y_traces); + data->width_x = 1; + data->width_y = 1; + } else { + data->width_x = data->max_x / x_traces; + data->width_y = data->max_y / y_traces; + } if (device_property_read_u32(&client->dev, "touchscreen-x-mm", &x_mm) || @@ -443,8 +452,16 @@ static int elan_query_device_parameters(struct elan_tp_data *data) data->x_res = elan_convert_resolution(hw_x_res, data->pattern); data->y_res = elan_convert_resolution(hw_y_res, data->pattern); } else { - data->x_res = (data->max_x + 1) / x_mm; - data->y_res = (data->max_y + 1) / y_mm; + if (unlikely(x_mm == 0 || y_mm == 0)) { + dev_warn(&client->dev, + "invalid physical dimensions: x_mm=%u, y_mm=%u\n", + x_mm, y_mm); + data->x_res = 1; + data->y_res = 1; + } else { + data->x_res = (data->max_x + 1) / x_mm; + data->y_res = (data->max_y + 1) / y_mm; + } } if (device_property_read_bool(&client->dev, "elan,clickpad")) @@ -956,6 +973,7 @@ static void elan_report_contact(struct elan_tp_data *data, int contact_num, if (data->report_features & ETP_FEATURE_REPORT_MK) { unsigned int mk_x, mk_y, area_x, area_y; + int adj_width_x, adj_width_y; u8 mk_data = high_precision ? packet[ETP_MK_DATA_OFFSET + contact_num] : finger_data[3]; @@ -967,8 +985,14 @@ static void elan_report_contact(struct elan_tp_data *data, int contact_num, * To avoid treating large finger as palm, let's reduce * the width x and y per trace. */ - area_x = mk_x * (data->width_x - ETP_FWIDTH_REDUCE); - area_y = mk_y * (data->width_y - ETP_FWIDTH_REDUCE); + + adj_width_x = data->width_x > ETP_FWIDTH_REDUCE ? + data->width_x - ETP_FWIDTH_REDUCE : 0; + adj_width_y = data->width_y > ETP_FWIDTH_REDUCE ? + data->width_y - ETP_FWIDTH_REDUCE : 0; + + area_x = mk_x * adj_width_x; + area_y = mk_y * adj_width_y; input_report_abs(input, ABS_TOOL_WIDTH, mk_x); input_report_abs(input, ABS_MT_TOUCH_MAJOR, -- 2.54.0.1099.g489fc7bff1-goog