From nobody Sat Sep 26 18:53:07 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 6CA134766AB; Mon, 31 Aug 2026 13:35:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788183336; cv=none; b=f0bUixa3HT2+FK1GB7Z2vi1+w4CoyYxD4Z36wLbp06o48BhOFhzFlqIkLtCPY+7Dhu62UgFnOT2gnuD2tUO8lC+nijD2uaX3XlQi0acsXbc+zvu7SIyhKKR8GSzgHsAAJl1eFmtJWgDDFxjqzqlr66utXl8NX3JqeTq/FfaQKxs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788183336; c=relaxed/simple; bh=Ji3iuCbt85ZOnV7oyha6glxbxHK50IsmotDAdsBlp3Q=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=oALOHXaQnb3FlLYPxttEyvsVBL9rBf63MXoHaCa/1vgWt0FC2iHnyc5VDlxWrDEBgZcSv6oP7g3E4Q+TQF4bwAy0zHY1e72BHpgj0SiqBCiYJdfKkH5C922dSu/AosN3NOEFHZqqMoYPm70+GnaWMXEqWKFtNujzgfAlknjb+mw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dMCwncYk; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="dMCwncYk" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A2F571F00A3E; Mon, 31 Aug 2026 13:35:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788183334; bh=dyqWhSF0HVROorFdmbzrMiaIDT7tFT1lvgaoCfGYIDE=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=dMCwncYkoez6m149pRqUKZvocUcqSDoZJRlovyFAsLUTaw0FCsV6Vi31y1zzZ3mBQ ZREMpcpw917V4z94t1lyqBZL/psIk0UxIOVfc1ckK6gJY28+UNbZkGmVAN44lI46F9 j4H2G21mXFfg3Eo+zZg09HHvkl1YIhMz3giRGt+MWxQ6XC9ViPWrjo/k2ZQ3z7ynDR 6XP9OvQXidj4kGiPzrY8S+2z7sDsWcwFjauxpwL8lt8QFLtAkoMWGXBn7P5WM3oLQ0 gKCQr26XCO1Kk8uXHiqeAwP0HcC+55WjlfmZo6ce7z74Ix8moMTflupehQRUti2uIe da8FABIVDr/pg== From: Sasha Levin To: patches@lists.linux.dev, stable@vger.kernel.org Cc: Sanjay Chitroda , Jonathan Cameron , Sasha Levin , linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH AUTOSEL 6.18-5.10] iio: accel: mma8452: switch to non-devm request_threaded_irq() Date: Mon, 31 Aug 2026 09:21:54 -0400 Message-ID: <20260831133314.4125787-86-sashal@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260831133314.4125787-1-sashal@kernel.org> References: <20260831133314.4125787-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore X-stable-base: Linux 6.18.48 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable From: Sanjay Chitroda [ Upstream commit 0a6726ec20cd4c0101f2de0ca485a11676224dea ] Avoid using devm_request_threaded_irq() as the driver requires explicit error-handling path(s). Using devm_* API together with goto-based unwinding breaks the expected LIFO resource release model. Add explicit IRQ cleanup in the driver teardown paths to follow kernel resource management conventions. Signed-off-by: Sanjay Chitroda Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin --- LLM Generated explanations, may be completely bogus: ## Phase 1: Commit Message Forensics **Step 1.1 =E2=80=94 Subject line** Record: `[iio: accel: mma8452]` `[switch]` =E2=80=94 Replace `devm_request_threaded_irq()` with manual `request_threaded_irq()` and explicit `free_irq()` in probe error and remove paths. **Step 1.2 =E2=80=94 Tags** Record: - **Fixes:** =E2=80=94 none - **Reported-by:** =E2=80=94 none - **Tested-by:** =E2=80=94 none - **Reviewed-by:** =E2=80=94 none - **Acked-by:** =E2=80=94 none - **Link:** =E2=80=94 none - **Cc: stable:** =E2=80=94 none (expected for manual review) - **Signed-off-by:** Sanjay Chitroda (author), Jonathan Cameron (IIO maintainer) Notable: no fuzzer report, no user bug report, no explicit stable nomination. Maintainer sign-off is present. **Step 1.3 =E2=80=94 Body analysis** Record: - **Bug:** `devm_request_threaded_irq()` combined with manual `goto`-based probe unwind breaks devm=E2=80=99s LIFO release model; IRQ s= tays registered while driver manually tears down buffer/trigger/other resources. - **Symptom:** Interrupt handler can run during manual teardown (probe failure or `remove()`), accessing structures being destroyed. - **Root cause:** devm releases IRQ only after probe returns or after `remove()` completes, but the driver manually cleans up buffer/trigger/regulators before that point. **Step 1.4 =E2=80=94 Hidden bug fix?** Record: **Yes.** Despite =E2=80=9Cswitch=E2=80=9D/=E2=80=9Cconventions=E2= =80=9D wording, this is a real teardown-order bug fix, not style-only cleanup. --- ## Phase 2: Diff Analysis **Step 2.1 =E2=80=94 Inventory** Record: - **File:** `drivers/iio/accel/mma8452.c` (+12 / =E2=88=927) - **Functions:** `mma8452_probe()`, `mma8452_remove()` - **Scope:** Single-file surgical fix **Step 2.2 =E2=80=94 Code flow changes** Record: - **Hunk 1 (probe IRQ registration):** `devm_request_threaded_irq()` =E2=86= =92 `request_threaded_irq()` =E2=80=94 IRQ no longer tied to devm. - **Hunk 2 (probe error paths):** After IRQ registration, `pm_runtime_set_active()` / `iio_device_register()` failures now `goto free_irq` instead of `goto buffer_cleanup`. - **Hunk 3 (new `free_irq:` label):** Calls `free_irq(client->irq, indio_dev)` before `buffer_cleanup`. - **Hunk 4 (`remove()`):** Adds explicit `free_irq()` before `iio_triggered_buffer_cleanup()`. **Before =E2=86=92 after on probe failure after IRQ setup:** - Before: IRQ remains active through `buffer_cleanup` / `trigger_cleanup` - After: IRQ freed first, then buffer/trigger cleanup **Before =E2=86=92 after on `remove()`:** - Before: IRQ active for entire `remove()`; devm frees only after `remove()` returns - After: IRQ freed before buffer/trigger teardown **Step 2.3 =E2=80=94 Bug mechanism** Record: **Category:** teardown race / potential UAF in interrupt context. `mma8452_interrupt()` (lines 1053=E2=80=931083) can call `iio_trigger_poll_nested(indio_dev->trig)` and `iio_push_event()`. With devm, IRQ stays live while `iio_triggered_buffer_cleanup()` and `mma8452_trigger_cleanup()` run in probe error and remove paths. **Step 2.4 =E2=80=94 Fix quality** Record: Fix is minimal, obviously correct, and matches standard non-devm IRQ pattern. Low regression risk; no API changes. --- ## Phase 3: Git History Investigation **Step 3.1 =E2=80=94 Blame** Record: `devm_request_threaded_irq()` introduced in `28e3427824ccc8` (2015-06-01, =E2=80=9Ciio: mma8452: Basic support for transient events=E2= =80=9D). Bug present since v4.1 era; definitely present in this 6.18.y tree. **Step 3.2 =E2=80=94 Fixes: tag** Record: N/A =E2=80=94 no Fixes: tag. **Step 3.3 =E2=80=94 Related file history** Record: Part of v3 series =E2=80=9Ciio: accel: mma8452: improve coding styl= e, pm and resource cleanup=E2=80=9D (10 patches). Sibling patch `5bdff291d20c3` (=E2=80=9Chandle I2C read error(s)=E2=80=9D) **is already in this tree** as= stable commit `1cddef80a180a`. IRQ fix (`0a6726ec20cd4`) is **not** in this tree. **Step 3.4 =E2=80=94 Author context** Record: Sanjay Chitroda; Jonathan Cameron committed. Same author has another teardown fix already backported here: `04a4d98222109` (=E2=80=9Cssp_sensors: cancel delayed work_refresh on remove=E2=80=9D). **Step 3.5 =E2=80=94 Dependencies** Record: **Standalone.** Does not depend on other series patches (codestyle/header-sort patches are independent). `git apply --check` on current tree: **clean apply**. --- ## Phase 4: Mailing List and External Research **Step 4.1 =E2=80=94 Original discussion** Record: `b4 dig -c 0a6726ec20cd4` =E2=86=92 [PATCH v3 02/10](https://patch.= msgid .link/20260505174640.3998281-3-sanjayembedded@gmail.com). Series v2 and v3 found. Lore fetch blocked by bot protection; could not read thread replies. **Step 4.2 =E2=80=94 Reviewers** Record: `b4 dig -w` =E2=80=94 CC=E2=80=99d: `jic23@kernel.org`, `linux- iio@vger.kernel.org`, and other IIO maintainers/reviewers. **Step 4.3 =E2=80=94 Bug reports** Record: None found. **Step 4.4 =E2=80=94 Series context** Record: 10-patch series; this is patch 02/10. I2C read-error fix from same series already backported to 6.18.y; IRQ fix was not. **Step 4.5 =E2=80=94 Stable list** Record: UNVERIFIED =E2=80=94 lore stable search inaccessible. --- ## Phase 5: Code Semantic Analysis **Step 5.1 =E2=80=94 Key functions** Record: `mma8452_probe()`, `mma8452_remove()`, `mma8452_interrupt()` **Step 5.2 =E2=80=94 Callers** Record: `mma8452_probe()` =E2=80=94 I2C driver probe during device enumerat= ion. `mma8452_remove()` =E2=80=94 device unbind/module unload. `mma8452_interrup= t()` =E2=80=94 hardware IRQ thread. **Step 5.3 =E2=80=94 Callees in interrupt path** Record: `i2c_smbus_read_byte_data()`, `iio_trigger_poll_nested()`, `iio_push_event()` =E2=80=94 all touch live IIO/trigger state. **Step 5.4 =E2=80=94 Reachability** Record: Triggered when `client->irq` is non-zero (interrupt-capable board config). Probe error path reachable on `iio_device_register()` failure etc. Remove path runs on every unbind/unload. **Step 5.5 =E2=80=94 Similar patterns** Record: Same devm+goto anti-pattern exists in other IIO drivers; this fix is driver-specific. --- ## Phase 6: Cross-Reference Against Local Tree **Step 6.1 =E2=80=94 Buggy code present?** Record: **Yes.** Local tree is **Linux 6.18.44** (`git describe HEAD` =E2= =86=92 `v6.18.44`). `drivers/iio/accel/mma8452.c` still uses `devm_request_threaded_irq()` at line 1685 with `goto buffer_cleanup` on later failures; `remove()` has no `free_irq()`. **Step 6.2 =E2=80=94 Backport complications** Record: **Clean apply** verified with `git apply --check`. No conflicts expected. **Step 6.3 =E2=80=94 Related fixes already present?** Record: `1cddef80a180a` (I2C read error propagation) is present. IRQ teardown fix is **not** present. --- ## Phase 7: Subsystem Context **Step 7.1 =E2=80=94 Subsystem** Record: `drivers/iio/accel/` =E2=80=94 IIO accelerometer driver. **Critical= ity: PERIPHERAL** (hardware-specific, not core kernel). **Step 7.2 =E2=80=94 Activity** Record: Moderately active; several accel driver fixes backported to 6.18.y recently. --- ## Phase 8: Impact and Risk Assessment **Step 8.1 =E2=80=94 Who is affected** Record: Systems with Freescale/NXP MMA8452-family accelerometer on I2C **and** IRQ line configured (embedded/phone-class boards). Config- dependent (`CONFIG_MMA8452` or module). **Step 8.2 =E2=80=94 Trigger conditions** Record: - **Probe failure** after IRQ registration (e.g. `iio_device_register()` OOM) =E2=80=94 uncommon - **Driver remove/unbind** with IRQ configured and hardware generating interrupts =E2=80=94 more realistic - Unprivileged users cannot directly trigger; requires device presence/removal **Step 8.3 =E2=80=94 Failure mode severity** Record: IRQ handler may access buffer/trigger/device state during teardown =E2=86=92 possible kernel oops/UAF in interrupt context. **Severit= y: HIGH** (crash potential), but **low likelihood** (narrow race window, no reports in ~11 years). **Step 8.4 =E2=80=94 Risk-benefit** Record: - **Benefit:** Prevents teardown race on probe error and remove; correct resource ordering - **Risk:** Very low (12-line, localized change) - **Ratio:** Moderate benefit, very low risk --- ## Phase 9: Final Synthesis **Step 9.1 =E2=80=94 Evidence** **FOR:** - Real bug: IRQ active during manual teardown in probe error and remove paths - Interrupt handler touches IIO buffer/trigger state that is being destroyed - Small, surgical, maintainer-committed fix - Applies cleanly to 6.18.y - Bug present since 2015 in this driver - Same author=E2=80=99s teardown fixes have been backported to this tree be= fore **AGAINST:** - No crash reports, syzbot, or Fixes: tag - Peripheral driver; only IRQ-enabled MMA8452 hardware - Bug latent ~11 years without reported incidents - Stable already took sibling I2C-read fix from same series but not this one - Framed as resource-management correctness rather than demonstrated crash **UNRESOLVED:** - Lore thread review comments inaccessible - No confirmation of real-world crash reproduction **Step 9.2 =E2=80=94 Stable rules checklist** 1. Obviously correct and tested? **PASS** =E2=80=94 logic is sound; no Test= ed-by but maintainer committed 2. Fixes a real bug? **PASS** =E2=80=94 verified teardown ordering bug in c= ode 3. Important issue? **PASS (borderline)** =E2=80=94 crash/UAF potential on remove, but unreported and hardware-specific 4. Small and contained? **PASS** =E2=80=94 19 lines, one file 5. No new features/APIs? **PASS** 6. Can apply to local tree? **PASS** =E2=80=94 verified clean apply **Step 9.3 =E2=80=94 Exception categories** Record: None (not quirk/DT/build/docs). **Step 9.4 =E2=80=94 Decision rationale** This is a legitimate teardown-order bug: with `devm_request_threaded_irq()`, the IRQ remains registered while `mma8452_remove()` and probe error paths manually destroy the triggered buffer and trigger that `mma8452_interrupt()` uses. The fix is minimal, correct, and applies cleanly to 6.18.44. Severity is borderline for stable =E2=80=94 no reported crashes, niche hardware =E2=80=94 but the fail= ure mode (oops/UAF in IRQ context during driver removal) meets the conservative stable bar for teardown races, especially given very low backport risk. --- ## Verification - [Phase 1] `git show 0a6726ec20cd4 --format=3Dfuller`: parsed message, tags, no Fixes/Reported-by - [Phase 2] `git show 0a6726ec20cd4`: confirmed +12/=E2=88=927 diff in probe/remove - [Phase 2] Read `mma8452_interrupt()` at lines 1053=E2=80=931083: handler = uses trigger/events during teardown - [Phase 3] `git blame -L 1680,1720`: devm IRQ from `28e3427824ccc8` (2015) - [Phase 3] `git log all-next -- drivers/iio/accel/mma8452.c`: found commit `0a6726ec20cd4`, series context - [Phase 3] `git show 1cddef80a180a`: sibling I2C fix already in stable 6.18.y - [Phase 3] `git apply --check` on patch: clean apply to HEAD - [Phase 4] `b4 dig -c 0a6726ec20cd4`: lore URL found - [Phase 4] `b4 dig -c 0a6726ec20cd4 -a`: v2/v3 series revisions found - [Phase 4] `b4 dig -c 0a6726ec20cd4 -w`: maintainers CC=E2=80=99d - [Phase 4] WebFetch lore URL: **FAILED** (bot protection) - [Phase 5] Grep/read `mma8452.c`: confirmed interrupt =E2=86=92 `iio_trigger_poll_nested()` / `iio_push_event()` - [Phase 6] `git describe HEAD`: v6.18.44 - [Phase 6] Grep `devm_request_threaded_irq` in tree: still present (bug not fixed) - [Phase 6] `git branch --contains 0a6726ec20cd4`: not in stable branch - [Phase 7] `git log -20 -- drivers/iio/accel/`: subsystem activity assessed - [Phase 8] Read probe/remove error paths: confirmed `goto buffer_cleanup` with active IRQ before fix **YES** drivers/iio/accel/mma8452.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c index cefc7cf4bd835..279a9b3648860 100644 --- a/drivers/iio/accel/mma8452.c +++ b/drivers/iio/accel/mma8452.c @@ -1682,18 +1682,16 @@ static int mma8452_probe(struct i2c_client *client) goto trigger_cleanup; =20 if (client->irq) { - ret =3D devm_request_threaded_irq(&client->dev, - client->irq, - NULL, mma8452_interrupt, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, - client->name, indio_dev); + ret =3D request_threaded_irq(client->irq, NULL, mma8452_interrupt, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + client->name, indio_dev); if (ret) goto buffer_cleanup; } =20 ret =3D pm_runtime_set_active(&client->dev); if (ret < 0) - goto buffer_cleanup; + goto free_irq; =20 pm_runtime_enable(&client->dev); pm_runtime_set_autosuspend_delay(&client->dev, @@ -1702,7 +1700,7 @@ static int mma8452_probe(struct i2c_client *client) =20 ret =3D iio_device_register(indio_dev); if (ret < 0) - goto buffer_cleanup; + goto free_irq; =20 ret =3D mma8452_set_freefall_mode(data, false); if (ret < 0) @@ -1713,6 +1711,10 @@ static int mma8452_probe(struct i2c_client *client) unregister_device: iio_device_unregister(indio_dev); =20 +free_irq: + if (client->irq) + free_irq(client->irq, indio_dev); + buffer_cleanup: iio_triggered_buffer_cleanup(indio_dev); =20 @@ -1738,6 +1740,9 @@ static void mma8452_remove(struct i2c_client *client) pm_runtime_disable(&client->dev); pm_runtime_set_suspended(&client->dev); =20 + if (client->irq) + free_irq(client->irq, indio_dev); + iio_triggered_buffer_cleanup(indio_dev); mma8452_trigger_cleanup(indio_dev); mma8452_standby(iio_priv(indio_dev)); --=20 2.53.0