From nobody Mon Feb 9 08:24:51 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EABA219CD1B; Mon, 26 May 2025 07:03:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748243025; cv=none; b=PeuVne3Ubg8LQbzk238q1VTvUExD++GTP8v9BfYAY4q+/IslFUPlu4Z+o8UMClyvkx7uFSXIFm0kIfF3H1R6QAIkf73oHnMks2MPXtZZDjJp6wJWh1C4qKQ23y3mSpF9yhHtT1wzfqlZAkkdrmClVNUGWR6/HGwcEq2ANd3r90o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748243025; c=relaxed/simple; bh=MMk5/uMd+GF1UB5m73CeK6sdi688uKa5o4LyBYY2AI0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:Cc; b=WiIFdhimBLj/B/lsha0T6JYs3GNMz0Y0+CiaImVQcH5OpugZQkIS2OC2HjzTID7IwRKvoniUJGVKLO60VaLnGw4rCCFK/1q45io+0r3bkjDhFk9sZ8fV9LUKtncvXFnv0FGIQwslWB2RgTiJyZYGMuCJo3aLd6heE0W9SyrCrJ4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=B/Ki+qMh; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="B/Ki+qMh" Received: by smtp.kernel.org (Postfix) with ESMTPS id 5E491C4CEE7; Mon, 26 May 2025 07:03:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748243024; bh=MMk5/uMd+GF1UB5m73CeK6sdi688uKa5o4LyBYY2AI0=; h=From:Date:Subject:To:Cc:Reply-To:From; b=B/Ki+qMhgvcOxmPYEi4S16rbY/tc1Ze9VgXfNm507bQ11vqFThTL3//gpZkRNB7pg nSK4W9JpyHu4KLvCNoHWi3Z7wuSZ3bzKJ8a71tyddhf/QWnK7446WM3XDs3ft166zB Az9EgQuScgCLe7g4UwAvsmCTvxJ0Ow0dqbTBTlbE7xNskE9eqGGySbeeGBXJn4ssie VKZzyVgIXLzJYV/5RMTszNKVioJeBW+rYRiL/24JCpHlX0AAswo45LHu5aRmI8FnIS 0JBGOM7IP6riyJLN6bf7SG03qMU0HEKczmOiRwT/yu0O5V0gCahbH7Kbiplkb9GfAS NSQD3ixlByvWg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4A0FFC54FB3; Mon, 26 May 2025 07:03:44 +0000 (UTC) From: Maud Spierings via B4 Relay Date: Mon, 26 May 2025 09:03:40 +0200 Subject: [PATCH v3] iio: common: st_sensors: Fix use of uninitialize device structs Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250526-st_iio_fix-v3-1-039fec38707c@gocontroll.com> X-B4-Tracking: v=1; b=H4sIAEsSNGgC/3WMQQ6CMBAAv0L2bE270Aqe/IcxBNsCm2BrWtJoC H+3cFWPM8nMAtEGshHOxQLBJorkXYbyUIAeOzdYRiYzIEfJJSKLc0vk255eTGhZ98ZUpkIOOXg Gm/U+u94yjxRnH977O4nN/twkwQQzqm7upeyFEngZvPZuDn6ajto/YHsl/N9j7vmpK1FJ2TWN+ urXdf0ASZiCR+kAAAA= X-Change-ID: 20250522-st_iio_fix-1c58fdd4d420 To: Jonathan Cameron , David Lechner , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko , Christian Heusel , Linus Walleij Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org, Maud Spierings X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1748243023; l=11339; i=maudspierings@gocontroll.com; s=20250214; h=from:subject:message-id; bh=Qqt9XE7k6jzMfflRu7bsFCiZg9ry06DYpLkn0Zt2L2Q=; b=bqPTkRr9BBTpX41rBICDyxe77dGsOEIQir7BfcLJ+oYQYKlV1nplyL+70McBjpkcJcNl1ESAe Xli2YR/8adADEtM43uqEKTlyAVDNiq3qYipt0HUvTxULLb/L+JZRAqv X-Developer-Key: i=maudspierings@gocontroll.com; a=ed25519; pk=7chUb8XpaTQDvWhzTdHC0YPMkTDloELEC7q94tOUyPg= X-Endpoint-Received: by B4 Relay for maudspierings@gocontroll.com/20250214 with auth_id=341 X-Original-From: Maud Spierings Reply-To: maudspierings@gocontroll.com From: Maud Spierings Throughout the various probe functions &indio_dev->dev is used before it is initialized. This caused a kernel panic in st_sensors_power_enable() when the call to devm_regulator_bulk_get_enable() fails and then calls dev_err_probe() with the uninitialized device. This seems to only cause a panic with dev_err_probe(), dev_err(), dev_warn() and dev_info() don't seem to cause a panic, but are fixed as well. The issue is reported and traced here: [1] [1]: https://lore.kernel.org/all/AM7P189MB100986A83D2F28AF3FFAF976E39EA@AM7= P189MB1009.EURP189.PROD.OUTLOOK.COM/ Cc: stable@vger.kernel.org Signed-off-by: Maud Spierings --- When I search for general &indio_dev->dev usage, I see quite a lot more hits, but I am not sure if there are issues with those too. This issue has existed for a long time it seems and therefore it is nearly impossible to find a proper fixes tag. I would love to see it at least backported to 6.12 as that is where I encountered it, and I believe the patch should apply without conflicts. --- Changes in v3: - Added the stable cc to the commit message - Move the link to the original issue to the commit message - Fix function notation in the commit message - Move some more of the dev_*() calls to one line - Link to v2: https://lore.kernel.org/r/20250522-st_iio_fix-v2-1-07a32655a9= 96@gocontroll.com Changes in v2: - Added SoB in commit message - Link to v1: https://lore.kernel.org/r/20250522-st_iio_fix-v1-1-d689b35f16= 12@gocontroll.com --- drivers/iio/accel/st_accel_core.c | 10 +++--- drivers/iio/common/st_sensors/st_sensors_core.c | 36 ++++++++++--------= ---- drivers/iio/common/st_sensors/st_sensors_trigger.c | 20 ++++++------ 3 files changed, 31 insertions(+), 35 deletions(-) diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel= _core.c index 99cb661fabb2d9cc1943fa8d0a6f3becb71126e6..a7961c610ed203d039bbf298c88= 83031a578fb0b 100644 --- a/drivers/iio/accel/st_accel_core.c +++ b/drivers/iio/accel/st_accel_core.c @@ -1353,6 +1353,7 @@ static int apply_acpi_orientation(struct iio_dev *ind= io_dev) union acpi_object *ont; union acpi_object *elements; acpi_status status; + struct device *parent =3D indio_dev->dev.parent; int ret =3D -EINVAL; unsigned int val; int i, j; @@ -1371,7 +1372,7 @@ static int apply_acpi_orientation(struct iio_dev *ind= io_dev) }; =20 =20 - adev =3D ACPI_COMPANION(indio_dev->dev.parent); + adev =3D ACPI_COMPANION(parent); if (!adev) return -ENXIO; =20 @@ -1380,8 +1381,7 @@ static int apply_acpi_orientation(struct iio_dev *ind= io_dev) if (status =3D=3D AE_NOT_FOUND) { return -ENXIO; } else if (ACPI_FAILURE(status)) { - dev_warn(&indio_dev->dev, "failed to execute _ONT: %d\n", - status); + dev_warn(parent, "failed to execute _ONT: %d\n", status); return status; } =20 @@ -1457,12 +1457,12 @@ static int apply_acpi_orientation(struct iio_dev *i= ndio_dev) } =20 ret =3D 0; - dev_info(&indio_dev->dev, "computed mount matrix from ACPI\n"); + dev_info(parent, "computed mount matrix from ACPI\n"); =20 out: kfree(buffer.pointer); if (ret) - dev_dbg(&indio_dev->dev, + dev_dbg(parent, "failed to apply ACPI orientation data: %d\n", ret); =20 return ret; diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/= common/st_sensors/st_sensors_core.c index 8ce1dccfea4f5aaff45d3d40f6542323dd1f0b09..dac593be56958fd0be92e13f628= 350fcfd0f040d 100644 --- a/drivers/iio/common/st_sensors/st_sensors_core.c +++ b/drivers/iio/common/st_sensors/st_sensors_core.c @@ -154,7 +154,7 @@ static int st_sensors_set_fullscale(struct iio_dev *ind= io_dev, unsigned int fs) return err; =20 st_accel_set_fullscale_error: - dev_err(&indio_dev->dev, "failed to set new fullscale.\n"); + dev_err(indio_dev->dev.parent, "failed to set new fullscale.\n"); return err; } =20 @@ -231,8 +231,7 @@ int st_sensors_power_enable(struct iio_dev *indio_dev) ARRAY_SIZE(regulator_names), regulator_names); if (err) - return dev_err_probe(&indio_dev->dev, err, - "unable to enable supplies\n"); + return dev_err_probe(parent, err, "unable to enable supplies\n"); =20 return 0; } @@ -241,13 +240,14 @@ EXPORT_SYMBOL_NS(st_sensors_power_enable, "IIO_ST_SEN= SORS"); static int st_sensors_set_drdy_int_pin(struct iio_dev *indio_dev, struct st_sensors_platform_data *pdata) { + struct device *parent =3D indio_dev->dev.parent; struct st_sensor_data *sdata =3D iio_priv(indio_dev); =20 /* Sensor does not support interrupts */ if (!sdata->sensor_settings->drdy_irq.int1.addr && !sdata->sensor_settings->drdy_irq.int2.addr) { if (pdata->drdy_int_pin) - dev_info(&indio_dev->dev, + dev_info(parent, "DRDY on pin INT%d specified, but sensor does not support interrupts\= n", pdata->drdy_int_pin); return 0; @@ -256,29 +256,27 @@ static int st_sensors_set_drdy_int_pin(struct iio_dev= *indio_dev, switch (pdata->drdy_int_pin) { case 1: if (!sdata->sensor_settings->drdy_irq.int1.mask) { - dev_err(&indio_dev->dev, - "DRDY on INT1 not available.\n"); + dev_err(parent, "DRDY on INT1 not available.\n"); return -EINVAL; } sdata->drdy_int_pin =3D 1; break; case 2: if (!sdata->sensor_settings->drdy_irq.int2.mask) { - dev_err(&indio_dev->dev, - "DRDY on INT2 not available.\n"); + dev_err(parent, "DRDY on INT2 not available.\n"); return -EINVAL; } sdata->drdy_int_pin =3D 2; break; default: - dev_err(&indio_dev->dev, "DRDY on pdata not valid.\n"); + dev_err(parent, "DRDY on pdata not valid.\n"); return -EINVAL; } =20 if (pdata->open_drain) { if (!sdata->sensor_settings->drdy_irq.int1.addr_od && !sdata->sensor_settings->drdy_irq.int2.addr_od) - dev_err(&indio_dev->dev, + dev_err(parent, "open drain requested but unsupported.\n"); else sdata->int_pin_open_drain =3D true; @@ -336,6 +334,7 @@ EXPORT_SYMBOL_NS(st_sensors_dev_name_probe, "IIO_ST_SEN= SORS"); int st_sensors_init_sensor(struct iio_dev *indio_dev, struct st_sensors_platform_data *pdata) { + struct device *parent =3D indio_dev->dev.parent; struct st_sensor_data *sdata =3D iio_priv(indio_dev); struct st_sensors_platform_data *of_pdata; int err =3D 0; @@ -343,7 +342,7 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev, mutex_init(&sdata->odr_lock); =20 /* If OF/DT pdata exists, it will take precedence of anything else */ - of_pdata =3D st_sensors_dev_probe(indio_dev->dev.parent, pdata); + of_pdata =3D st_sensors_dev_probe(parent, pdata); if (IS_ERR(of_pdata)) return PTR_ERR(of_pdata); if (of_pdata) @@ -370,7 +369,7 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev, if (err < 0) return err; } else - dev_info(&indio_dev->dev, "Full-scale not possible\n"); + dev_info(parent, "Full-scale not possible\n"); =20 err =3D st_sensors_set_odr(indio_dev, sdata->odr); if (err < 0) @@ -405,7 +404,7 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev, mask =3D sdata->sensor_settings->drdy_irq.int2.mask_od; } =20 - dev_info(&indio_dev->dev, + dev_info(parent, "set interrupt line to open drain mode on pin %d\n", sdata->drdy_int_pin); err =3D st_sensors_write_data_with_mask(indio_dev, addr, @@ -593,21 +592,20 @@ EXPORT_SYMBOL_NS(st_sensors_get_settings_index, "IIO_= ST_SENSORS"); int st_sensors_verify_id(struct iio_dev *indio_dev) { struct st_sensor_data *sdata =3D iio_priv(indio_dev); + struct device *parent =3D indio_dev->dev.parent; int wai, err; =20 if (sdata->sensor_settings->wai_addr) { err =3D regmap_read(sdata->regmap, sdata->sensor_settings->wai_addr, &wai); if (err < 0) { - dev_err(&indio_dev->dev, - "failed to read Who-Am-I register.\n"); - return err; + return dev_err_probe(parent, err, + "failed to read Who-Am-I register.\n"); } =20 if (sdata->sensor_settings->wai !=3D wai) { - dev_warn(&indio_dev->dev, - "%s: WhoAmI mismatch (0x%x).\n", - indio_dev->name, wai); + dev_warn(parent, "%s: WhoAmI mismatch (0x%x).\n", + indio_dev->name, wai); } } =20 diff --git a/drivers/iio/common/st_sensors/st_sensors_trigger.c b/drivers/i= io/common/st_sensors/st_sensors_trigger.c index 9d4bf822a15dfcdd6c2835f6b9d7698cd3cb0b08..8a8ab688d7980f6dd43c660f90a= 0eba32c38388b 100644 --- a/drivers/iio/common/st_sensors/st_sensors_trigger.c +++ b/drivers/iio/common/st_sensors/st_sensors_trigger.c @@ -127,7 +127,7 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_d= ev, sdata->trig =3D devm_iio_trigger_alloc(parent, "%s-trigger", indio_dev->name); if (sdata->trig =3D=3D NULL) { - dev_err(&indio_dev->dev, "failed to allocate iio trigger.\n"); + dev_err(parent, "failed to allocate iio trigger.\n"); return -ENOMEM; } =20 @@ -143,7 +143,7 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_d= ev, case IRQF_TRIGGER_FALLING: case IRQF_TRIGGER_LOW: if (!sdata->sensor_settings->drdy_irq.addr_ihl) { - dev_err(&indio_dev->dev, + dev_err(parent, "falling/low specified for IRQ but hardware supports only rising/high:= will request rising/high\n"); if (irq_trig =3D=3D IRQF_TRIGGER_FALLING) irq_trig =3D IRQF_TRIGGER_RISING; @@ -156,21 +156,19 @@ int st_sensors_allocate_trigger(struct iio_dev *indio= _dev, sdata->sensor_settings->drdy_irq.mask_ihl, 1); if (err < 0) return err; - dev_info(&indio_dev->dev, + dev_info(parent, "interrupts on the falling edge or active low level\n"); } break; case IRQF_TRIGGER_RISING: - dev_info(&indio_dev->dev, - "interrupts on the rising edge\n"); + dev_info(parent, "interrupts on the rising edge\n"); break; case IRQF_TRIGGER_HIGH: - dev_info(&indio_dev->dev, - "interrupts active high level\n"); + dev_info(parent, "interrupts active high level\n"); break; default: /* This is the most preferred mode, if possible */ - dev_err(&indio_dev->dev, + dev_err(parent, "unsupported IRQ trigger specified (%lx), enforce rising edge\n", irq_t= rig); irq_trig =3D IRQF_TRIGGER_RISING; } @@ -179,7 +177,7 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_d= ev, if (irq_trig =3D=3D IRQF_TRIGGER_FALLING || irq_trig =3D=3D IRQF_TRIGGER_RISING) { if (!sdata->sensor_settings->drdy_irq.stat_drdy.addr) { - dev_err(&indio_dev->dev, + dev_err(parent, "edge IRQ not supported w/o stat register.\n"); return -EOPNOTSUPP; } @@ -214,13 +212,13 @@ int st_sensors_allocate_trigger(struct iio_dev *indio= _dev, sdata->trig->name, sdata->trig); if (err) { - dev_err(&indio_dev->dev, "failed to request trigger IRQ.\n"); + dev_err(parent, "failed to request trigger IRQ.\n"); return err; } =20 err =3D devm_iio_trigger_register(parent, sdata->trig); if (err < 0) { - dev_err(&indio_dev->dev, "failed to register iio trigger.\n"); + dev_err(parent, "failed to register iio trigger.\n"); return err; } indio_dev->trig =3D iio_trigger_get(sdata->trig); --- base-commit: 7bac2c97af4078d7a627500c9bcdd5b033f97718 change-id: 20250522-st_iio_fix-1c58fdd4d420 Best regards, --=20 Maud Spierings