Linux driver-core infrastructure
 help / color / mirror / Atom feed
* [PATCH AUTOSEL 6.18] regmap: irq: Free the irqdomain we create
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
@ 2026-10-19 13:45 ` Sasha Levin
  2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-6.6] regmap: maple: Workaround for another false-positive compiler warning Sasha Levin
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2026-10-19 13:45 UTC (permalink / raw)
  To: patches, stable
  Cc: Mark Brown, Farhad Alemi, Thomas Gleixner, Sasha Levin, gregkh,
	rafael, dakr, linux-kernel, driver-core

From: Mark Brown <broonie@kernel.org>

[ Upstream commit 2e42cade8ff1ff579e77976d9869db4df1feaf74 ]

When domain support was added to regmap-irq it was not possible to
remove domains, this was added later by 8ee99ada293b (irqdomain: Support
removal of IRQ domains.).  We did update the main removal path to free
the domain but forgot the error unwinding case during creation that is
now in regmap_add_irq_chip_fwnode() after some code motion, meaning that
errors during instantiation result in an unused irqchip being left
hanging around.  Add the missing irq_remove_domain() call where the
comment says it should be.

Reported-by: Farhad Alemi <farhad.alemi@berkeley.edu>
Reported-by: Thomas Gleixner <tglx@kernel.org>
Link: https://patch.msgid.link/20260901-regmap-irq-deallocate-domain-v1-1-4bfed4aff559@kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **6.18.57**. At that base,
`regmap_add_irq_chip_fwnode()` still has the “Should really dispose of
the domain but...” stub, so the leak exists here and the one-line
`irq_domain_remove()` change applies cleanly.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

**Step 1.1: PARSE THE SUBJECT LINE**
Record: `[regmap: irq:] [Free] [Release the irqdomain created during
chip setup]`

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- `Reported-by: Farhad Alemi <farhad.alemi@berkeley.edu>` (researcher
  report)
- `Reported-by: Thomas Gleixner <tglx@kernel.org>` (irq subsystem
  maintainer)
- `Link: https://patch.msgid.link/20260901-regmap-irq-deallocate-
  domain-v1-1-4bfed4aff559@kernel.org`
- `Signed-off-by: Mark Brown <broonie@kernel.org>` (regmap maintainer;
  author)
- No `Fixes:` tag (expected)
- No `Cc: stable` (expected)
- Pipeline-added `[Upstream commit 2e42cade8ff1...]` and Sasha Levin SOB
  ignored per instructions
- Notable: two reporters, one of them tglx

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- Bug: when irqdomain support was added to regmap-irq, domains could not
  be removed. `irq_domain_remove()` was added later (`58ee99ada293b`;
  the message cites `8ee99ada293b`, missing the leading `5`). The
  success teardown path was updated; the **creation error-unwind** path
  was not.
- Symptom: failed instantiation leaves an unused irqchip/domain hanging
  around.
- Failure mode: resource leak of a published irq domain on
  `request_threaded_irq()` failure after `regmap_irq_create_domain()`.
- Root cause (author): missing `irq_domain_remove()` at the
  `err_domain:` label (the comment already said it should be there). The
  message says `irq_remove_domain()`; the actual API is
  `irq_domain_remove()`.
- Version info: none beyond the historical API gap.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not hidden. This is an explicit error-path resource-leak fix.
External reporting (KASAN during CPU hotplug) shows the leaked objects
can become a use-after-free, not only a leak.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/base/regmap/regmap-irq.c` (`1` insertion, `1` deletion)
- Function: `regmap_add_irq_chip_fwnode()`
- Scope: single-file surgical fix

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
- Before: domain created → `request_threaded_irq()` fails → `goto
  err_domain` → comment only → mutex/key teardown → `kfree(d)` while
  `d->domain` stays published with `host_data = d`.
- After: same path calls `irq_domain_remove(d->domain)` before freeing
  `d`.
- Path affected: probe error path only, after successful domain
  creation.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record:
- Category: error-path resource leak; can escalate to UAF because the
  domain is published (`irq_domain_list` / fwnode) with `host_data`
  pointing at memory that is then freed.
- Mechanism: missing counterpart to the existing `irq_domain_remove()`
  in `regmap_del_irq_chip()`.

**Step 2.4: ASSESS THE FIX QUALITY**
Record:
- For `irq_base == 0` (most DT callers): obviously correct. Domain has
  no mappings yet; `irq_domain_remove()` is the right unwind and matches
  the del path.
- For `irq_base != 0` (legacy/`irq_alloc_descs()` path, including
  callers passing `-1`): incomplete. Domain creation associates IRQs up
  front. `irq_domain_remove()` does not dispose those mappings. tglx
  said the descriptor chip/domain pointers remain and the UAF remains.
- Regression risk: low for `irq_base == 0`. For `irq_base > 0`, the
  domain object is freed while descriptors still reference it (already a
  UAF on `desc->chip` before this patch). The change is still a subset
  of the correct unwind, not a new feature.
- Red flags: none on APIs/scope. Completeness gap is real but does not
  make the one-line change wrong for the common path.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

**Step 3.1: BLAME THE CHANGED LINES**
Record:
- Comment/label introduced by `4af8be67fd9989` (“regmap: Convert
  regmap_irq to use irq_domain”, 2012).
- Domain remove on the **del** path: `b5ab3e5cae097` (“regmap: irq:
  Remove domain on exit”, 2014).
- `err_domain:` still only had the comment at **v6.18.57**.
- This is long-lived error-path debt, not a brand-new 6.18-only bug.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No `Fixes:` tag. Historical introducer is `4af8be67fd9989`; that
commit **is** an ancestor of this tree.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record:
- Nearby: `1da33858af625` (mutex destroy on error), `76b6e14aa7b08`
  (lockdep key). Both already in v6.18.57; this patch’s context matches.
- Domain creation helper: `dde286ee57704` / `regmap_irq_create_domain()`
  already in this tree.
- Standalone 1-line fix, not patch X/Y.
- No follow-up in this tree adding `irq_dispose_mapping()` on
  `err_domain`.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Author is Mark Brown, **regmap maintainer**. He applied his own
patch to `broonie/regmap.git for-7.3` the same day.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record:
- Needs `irq_domain_remove()`: present (`58ee99ada293b`, exported in
  this tree).
- Needs `d->domain` and `err_domain:`: present.
- Can apply standalone to v6.18.57. No missing helpers.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- Lore/msgid: https://patch.msgid.link/20260901-regmap-irq-deallocate-
  domain-v1-1-4bfed4aff559@kernel.org
- Only v1 (`b4 dig -a`); no v2 in that thread.
- Thread:
  1. Mark posts the 1-line patch (1 Sep 2026).
  2. Mark applies it to for-7.3 ~1 hour later.
  3. tglx (4 Sep): “That won’t work” for the `irq_alloc_descs()` /
     `virq_base > 0` case; descriptors keep chip/domain pointers; UAF
     remains. First suggestion: `irq_domain_free_irqs()`.
  4. tglx follow-up: `irq_domain_free_irqs()` only works with
     hierarchical domains; use `irq_dispose_mapping(irq_base + i)` then
     remove the domain.
  5. Mark: “Ah, thanks - I’d expected removing the domain to clean
     everything up.”
- No NAK of calling `irq_domain_remove()` itself; the request is
  additional dispose before remove.
- No reviewer `Cc: stable` in the thread.

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record: Recipients were linux-kernel, Farhad Alemi, tglx, Mark Brown.
tglx reviewed after apply. No Acked-by/Reviewed-by on the committed
patch.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record:
- Public write-up (31 Aug 2026): KASAN invalid read in
  `irq_migrate_all_off_this_cpu` during CPU offline. tglx traced it to
  this failed-setup path: descriptors remain mapped to a caller-owned
  `irq_chip` after that chip/`regmap_irq_chip_data` is freed.
- Trigger: device IRQ setup fails, then CPU hotplug walks descriptors.
- Radu Rendec mentioned a similar syzbot hotplug stack; tglx criticized
  allocation info in that report. Overlap is suggestive, not proven
  identical.
- Unprivileged exploit/CVE: not established.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: Standalone v1. tglx’s dispose-mapping addition was not in this
series and is not in this tree. GitHub `master` snapshot still showed
the old comment, consistent with this being a 7.3-era fix not yet
universal.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: No useful stable-list hit that this was previously rejected or
requested. UNVERIFIED beyond search noise.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

**Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF**
Record: `regmap_add_irq_chip_fwnode()` only. Callees of interest:
`regmap_irq_create_domain()`, `request_threaded_irq()`,
`irq_domain_remove()`.

**Step 5.2: TRACE CALLERS**
Record:
- `regmap_add_irq_chip()` → `regmap_add_irq_chip_fwnode()`
- `devm_regmap_add_irq_chip_fwnode()` → same
- `git grep -l "regmap_add_irq_chip"` → **87** `.c` files
- Call context: driver probe (MFD/PMIC, ASoC codecs, power, GPIO, RTC,
  DSA). Not a syscall hot path; boot/enumeration and probe-retry.
- `irq_base != 0` callers exist, including popular PMICs: `rk8xx-core.c`
  (`-1`), `retu-mfd.c`, `88pm800.c`, `88pm805.c`, `mt6370.c`, plus board
  `irq_base` in tps65910/wm8994/tps65090.

**Step 5.3: TRACE CALLEES**
Record:
- `regmap_irq_create_domain()` → `irq_domain_instantiate()` with
  `virq_base = irq_base`, `host_data = d`. If `virq_base > 0`,
  `__irq_domain_instantiate()` runs `irq_domain_associate_many()`.
- `if (irq_base)` also calls `irq_alloc_descs()` first (`-1` is truthy).
- `irq_domain_remove()` unpublishes and `kfree`s the domain; comment
  requires mappings already disposed.

**Step 5.4: FOLLOW THE CALL CHAIN**
Record:
- Reachable from device probe of many PMICs/codecs.
- Userspace does not call this directly. Probe failure + later CPU
  offline is the documented KASAN path.
- Deferred probe retry can also leave a stale fwnode domain if the
  domain is not removed.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: `regmap_del_irq_chip()` already disposes mappings then calls
`irq_domain_remove()`. That is the model tglx wants on `err_domain` when
`irq_base > 0`. This patch only adds the remove.

===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: Yes, at v6.18.57 `drivers/base/regmap/regmap-irq.c`
`err_domain:` still has `/* Should really dispose of the domain but...
*/`. Introduced 2012; never unwound on this error path here.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: Expected **clean apply** to v6.18.57. Surrounding
`mutex_destroy` / `lockdep_unregister_key` already match.
`irq_domain_remove()` already used in the same file’s del path.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: Del-path domain remove is here (`b5ab3e5cae097`). No other fix
of this `err_domain` leak. No `irq_dispose_mapping` follow-up on that
label.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: `drivers/base/regmap` IRQ helper. **IMPORTANT** (shared by many
PMICs/MFDs, not core mm/sched, but widely used on ARM/embedded and
laptops).

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: Mature (2011+). Recent work is lockdep nesting, mutex free,
domain suffix. This is leftover unwind, not churn from a new subsystem.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: Driver-specific / config-specific (`CONFIG_REGMAP_IRQ`), but
that config is selected by many common PMICs. Affects anyone whose
regmap-irq probe fails after domain create.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record:
- Trigger: `regmap_irq_create_domain()` succeeds, then
  `request_threaded_irq()` fails (bad/missing IRQ, busy IRQ, probe
  deferral, etc.).
- Not every boot. Realistic on flaky firmware, wrong DT IRQ, deferred
  probe.
- Unprivileged trigger: not verified. CPU hotplug typically needs
  privilege. KASAN still shows a real kernel UAF.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record:
- Always: leaked published irq domain; `d` freed while domain
  `host_data` dangles.
- With `irq_base != 0`: leaked associated IRQ descriptors; `desc->chip`
  can UAF on CPU offline (`irq_migrate_all_off_this_cpu`). **HIGH** (UAF
  / KASAN).
- This patch fully fixes the domain leak; it does **not** fully fix the
  descriptor UAF when `irq_base > 0`.

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record:
- Benefit: high for a 1-line unwind of a published irq domain used by
  dozens of drivers; needed for probe retry and to stop leaking domain
  objects.
- Risk: very low for `irq_base == 0`. For `irq_base > 0`, incomplete;
  not a new feature; same class of UAF already existed.
- Ratio: benefit > risk. Follow-up dispose-mapping should also be
  backported when it exists; that is not a reason to keep the domain
  leak.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- Real error-path leak of a published irq domain; comment admitted the
  gap since 2012.
- Reported by tglx; KASAN UAF on CPU hotplug is a serious failure mode.
- 1 line, same API already used in `regmap_del_irq_chip()`.
- Buggy code is in v6.18.57; `irq_domain_remove()` is in this tree;
  applies cleanly.
- Author is the regmap maintainer; 87 in-tree callers.
- Probe-path resource leaks are standard stable material.

AGAINST:
- Incomplete vs the reported `irq_base > 0` UAF; tglx asked for
  `irq_dispose_mapping()` first; Mark agreed the remove-alone assumption
  was wrong.
- No `Fixes:`/`Cc: stable` (not a negative by itself).
- Applied to for-7.3 before tglx’s review; no v2 in that thread.

UNRESOLVED:
- Whether a later mainline follow-up with `irq_dispose_mapping()` landed
  after this tree’s branch.
- Whether the KASAN report was reproduced on 6.18.y specifically (code
  path is present).
- No stable-list discussion found.

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** for the domain leak (`irq_base
   == 0` and domain object itself). Incomplete for preassociated
   descriptors, but the added call is the correct API and is already
   used on the del path.
2. Fixes a real bug that affects users? **PASS** — leaked irq domain on
   failed probe; KASAN UAF documented on related leftover mappings.
3. Important issue? **PASS** — UAF / resource leak of irq core objects,
   not cosmetic.
4. Small and contained? **PASS** — 1 line, one function.
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — v6.18.57 has the exact hunk
   context.

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: Not ID/quirk/DT/docs. Ordinary error-path leak fix. Build-fix
exception N/A.

**Step 9.4: MAKE YOUR DECISION**
This should be backported to **this** 6.18.y tree. The bug is here, the
helper is here, and the change is the missing unwind the code has
documented for years. Incompleteness for `irq_base > 0` means a later
dispose-mapping patch is still needed for the full KASAN UAF; it does
not make this line a net negative.

### What the commit solves, and why it matters here
`regmap_add_irq_chip_fwnode()` publishes an irq domain, then on
`request_threaded_irq()` failure frees `struct regmap_irq_chip_data`
without removing that domain. Stable 6.18.57 still does this. The
leftover domain stays on the global list with dangling `host_data`, and
on the legacy `irq_base != 0` path associated descriptors can later be
walked during CPU hotplug (KASAN UAF). Many PMICs/MFDs use this helper,
including rk8xx with `irq_base = -1`.

### Stable rules / risk
Small, obviously intended, no new API, applies cleanly. Benefit is
fixing a real leak/UAF-adjacent unwind; risk is a 1-line call that the
same file already uses on teardown.

Verification:
- [Phase 1] Tags: Farhad Alemi + tglx Reported-by; lore msgid link; Mark
  Brown SOB; no Fixes/Cc stable
- [Phase 1] Body describes creation-path domain leak after
  `8ee99ada293b`; actual SHA in this tree is `58ee99ada293b`
- [Phase 2] Diff is 1 line in `regmap_add_irq_chip_fwnode()`
  `err_domain:`: comment → `irq_domain_remove(d->domain)`
- [Phase 3] `git blame` at v6.18.57: comment from `4af8be67fd9989`
  (2012); del-path remove `b5ab3e5cae097` (2014)
- [Phase 3] `git merge-base --is-ancestor 4af8be67fd9989 HEAD` yes;
  `58ee99ada293b` is ancestor of v6.18.57
- [Phase 3] No follow-up dispose-mapping commit on this file in this
  tree
- [Phase 4] `b4 dig -c 4784831655ab5`: v1 only, applied to for-7.3 same
  day
- [Phase 4] tglx: remove-alone does not clear associated descriptors
  when `virq_base > 0`; use `irq_dispose_mapping` then remove
- [Phase 4] Mark acknowledged he expected remove to clean everything up
- [Phase 4] External write-up: KASAN in `irq_migrate_all_off_this_cpu`
  after failed regmap IRQ setup
- [Phase 5] 87 files call `regmap_add_irq_chip*`; probe of
  MFD/PMIC/codec/etc.
- [Phase 5] `if (irq_base) irq_alloc_descs()` plus `virq_base`
  associate_many confirmed in this tree
- [Phase 6] `git describe HEAD` → `v6.18.57-155-gcdf239ca885b2`; `make
  kernelversion` → 6.18.57
- [Phase 6] v6.18.57 still has the dispose comment;
  `irq_domain_remove()` already in `regmap_del_irq_chip()`
- [Phase 8] Failure mode: leaked irq domain; UAF on CPU hotplug for
  preassociated IRQs; severity HIGH
- UNVERIFIED: later mainline follow-up with `irq_dispose_mapping` on
  `err_domain`; whether syzbot report is the same bug; stable-list
  history beyond unsuccessful search

**YES**

 drivers/base/regmap/regmap-irq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
index 6112d942499be..8c297156ea402 100644
--- a/drivers/base/regmap/regmap-irq.c
+++ b/drivers/base/regmap/regmap-irq.c
@@ -941,7 +941,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
 	return 0;
 
 err_domain:
-	/* Should really dispose of the domain but... */
+	irq_domain_remove(d->domain);
 err_mutex:
 	mutex_destroy(&d->lock);
 	lockdep_unregister_key(&d->lock_key);
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH AUTOSEL 6.18-6.6] regmap: maple: Workaround for another false-positive compiler warning
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
  2026-10-19 13:45 ` [PATCH AUTOSEL 6.18] regmap: irq: Free the irqdomain we create Sasha Levin
@ 2026-10-19 13:47 ` Sasha Levin
  2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-6.12] regmap: Remove debugfs before cache teardown Sasha Levin
  2026-10-19 13:53 ` [PATCH AUTOSEL 6.18-5.10] driver core: attribute_container: Unwind device_add() on attr failure Sasha Levin
  3 siblings, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2026-10-19 13:47 UTC (permalink / raw)
  To: patches, stable
  Cc: Uwe Kleine-König (The Capable Hub), Mark Brown, Sasha Levin,
	gregkh, rafael, dakr, linux-kernel, driver-core

From: Uwe Kleine-König (The Capable Hub) <u.kleine-koenig@baylibre.com>

[ Upstream commit dffd32eb2b0e714a8ae23f98518ad7152cb06369 ]

Similar to the issue fixed in commit 542440fd7b30 ("regmap: maple: work
around gcc-14.1 false-positive warning"), I see an uninitialized warning
for upper_index and upper_last.

Happens with arc-linux-gnu-gcc (Debian 15.3.0-1) 15.3.0 on an
allmodconfig for ARCH=arc.

Signed-off-by: Uwe Kleine-König (The Capable Hub) <u.kleine-koenig@baylibre.com>
Link: https://patch.msgid.link/20260626060427.2548578-2-u.kleine-koenig@baylibre.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

I have the tree version, the pre-image at v6.18.53, the lore thread, and
the call-path context. Compiling the nine-phase analysis next.

---

## Phase 1: Commit message forensics

**Step 1.1: Subject**
Record: `[regmap: maple:] [Workaround] [silence a gcc false-positive
-Wuninitialized on upper_index/upper_last]`

**Step 1.2: Tags**
Record:
- Link: https://patch.msgid.link/20260626060427.2548578-2-u.kleine-
  koenig@baylibre.com
- Signed-off-by: Uwe Kleine-König (author)
- Signed-off-by: Mark Brown (regmap maintainer)
- No Fixes:, Reported-by, Tested-by, Reviewed-by, Acked-by, or Cc:
  stable (absence expected)
- Mentions prior commit 542440fd7b30

**Step 1.3: Body**
Record: [Bug] gcc 15.3.0 on ARCH=arc allmodconfig reports
-Wuninitialized for `upper_index` and `upper_last` in
`regcache_maple_drop()`. Same class as the gcc-14.1 false-positive
already worked around for `lower_index`/`lower_last`. [Symptom] compiler
warning; with `CONFIG_WERROR` it is a hard build failure
(`-Werror=uninitialized`). [Versions] gcc 15.3.0 (Debian), ARCH=arc
allmodconfig. [Root cause] compiler cannot see that those locals are
only read after they are assigned (guarded by `if (upper)`).

**Step 1.4: Hidden bug fix?**
Record: Not a hidden runtime bug. It is an explicit compiler-warning
workaround. It is a **build fix**, which the stable rules treat as an
allowed exception.

---

## Phase 2: Diff analysis

**Step 2.1: Inventory**
Record: `drivers/base/regmap/regcache-maple.c` — 1 line changed
(`+1/-1`). Function: `regcache_maple_drop()`. Scope: single-file, one-
line surgical change.

**Step 2.2: Flow**
Record: Before: `unsigned long upper_index, upper_last;` uninitialized.
After: `= 0` on both. No control-flow change. `upper_index`/`upper_last`
are assigned at lines 146–147 only when `mas.last > max`, which is also
when `upper` is allocated; they are consumed only under `if (upper)`
(line 171). Initializing to 0 is a dead store on the real path.

**Step 2.3: Bug mechanism**
Record: [Category] Build / compiler false-positive (not a runtime
uninitialized use). [Mechanism] gcc 15 cannot prove initialization
through the maple-tree loop and warns; with Werror that fails the build.
Fix: same dummy init already used for `lower_index`/`lower_last`.

**Step 2.4: Fix quality**
Record: Obviously correct; matches the existing comment and the gcc-14
workaround. Zero runtime behavior change. Regression risk: negligible (0
is never consumed unless `upper` is set, and that path always assigns
first).

---

## Phase 3: Git history

**Step 3.1: Blame**
Record: `regcache_maple_drop()` introduced in f033c26de5a57 (“regmap:
Add maple tree based register cache”, 2023-03-30, ~v6.4). `lower_index`
dummy init: 542440fd7b309 (2024-07-19, in this tree). `upper_index` was
left uninitialized until this commit.

**Step 3.2: Fixes: tag**
Record: None. Related original: 542440fd7b309, already an ancestor of
HEAD and of v6.18.53.

**Step 3.3: File history**
Record: Recent real fixes in this file (`00bb549d7d63a` cache
corruption, `eaa03486d9325` uninitialized `ret`, `f08f2d2907675` leak on
store failure) are independent. This commit is standalone, not patch X/Y
of a functional series.

**Step 3.4: Author**
Record: Uwe Kleine-König is a regular driver-core contributor, not the
regmap maintainer. Mark Brown applied it. No other related maple commits
by this author.

**Step 3.5: Dependencies**
Record: Needs the maple cache (present since v6.4) and the existing
`lower_*` init comment (present). Applies standalone. No new helpers or
struct fields.

---

## Phase 4: Mailing list

**Step 4.1: Original discussion**
Record: [Lore]
https://patch.msgid.link/20260626060427.2548578-2-u.kleine-
koenig@baylibre.com
[Revisions] v1 only (`b4 dig -a`). Thread: submission + Mark Brown
“Applied to broonie/regmap.git for-7.3”. No NAKs, no stable nomination,
no reviewer risk flags.

**Step 4.2: Recipients (`b4 dig -w`)**
Record: To: Mark Brown. Cc: Greg Kroah-Hartman, Rafael Wysocki, Danilo
Krummrich, linux-kernel, driver-core. Maintainer received and applied
it.

**Step 4.3: Bug report**
Record: Author-reported compiler warning on arc-linux-gnu-gcc 15.3.0
allmodconfig. No syzbot/bugzilla. Severity: build warning/error, not a
runtime crash.

**Step 4.4: Series**
Record: msgid `…2548578-2` but subject is `[PATCH v1]` and Mark applied
it as `[1/1]`. Standalone.

**Step 4.5: Stable list**
Record: No lore.kernel.org/stable discussion of this specific fix found.

---

## Phase 5: Semantic analysis

**Step 5.1: Functions**
Record: `regcache_maple_drop()` only.

**Step 5.2: Callers**
Record: Wired as `regcache_ops.drop`. Reached via
`regcache_drop_region()` (exported). Callers: regmap core, kunit tests,
various drivers. The *warning* triggers at compile time whenever this
file is built, independent of runtime callers.

**Step 5.3: Callees**
Record: maple-tree `mas_*`, `kmemdup_array`, `kfree`. Unchanged.

**Step 5.4: Reachability**
Record: Compile-time: `drivers/base/regmap/regcache-maple.c` is built
with `CONFIG_REGMAP` (common). Runtime drop path is not relevant to the
failure mode.

**Step 5.5: Similar patterns**
Record: Same function already initializes `lower_index`/`lower_last` for
the same reason (542440fd7b309) and `ret` for smatch (eaa03486d9325).
This completes the remaining pair.

---

## Phase 6: Local tree (this checkout)

**Step 6.1: Does the buggy code exist?**
Record: Local tree is **6.18.53** (`git describe`:
v6.18.53-5049-g0f0bdc2b0dffb; Makefile VERSION=6 PATCHLEVEL=18
SUBLEVEL=53). At **v6.18.53**:
```
unsigned long upper_index, upper_last;
```
exists; `lower_index = 0` is already present. Upstream dffd32eb2b0e is
**not** an ancestor of v6.18.53. Maple cache has been here since ~v6.4.

**Step 6.2: Backport difficulty**
Record: Clean apply on v6.18.53. Surrounding function matches the hunk.
No refactor in the way.

**Step 6.3: Related fixes already here?**
Record: gcc-14 `lower_*` workaround is in v6.18.53. Nothing already
initializes `upper_*`.

---

## Phase 7: Subsystem context

**Step 7.1**
Record: [Subsystem] drivers/base/regmap (maple register cache).
[Criticality] IMPORTANT — used by many hardware drivers; this change is
compile-time only.

**Step 7.2**
Record: Mature cache implementation (since v6.4), modest ongoing churn.
Not staging.

---

## Phase 8: Impact and risk

**Step 8.1: Who is affected**
Record: Anyone compiling this file with gcc that emits the warning.
Documented trigger: ARCH=arc, gcc 15.3.0, allmodconfig. `CONFIG_WERROR`
defaults to `COMPILE_TEST` (`init/Kconfig`); allmodconfig enables that,
so the warning becomes `-Werror=uninitialized` (same diagnostic the
gcc-14 commit showed as a hard error). Distro production configs usually
have WERROR=n, so they see a warning rather than a failed build.

**Step 8.2: Trigger**
Record: Compile of `regcache-maple.c`. Not a runtime race. Not
userspace-triggerable.

**Step 8.3: Failure mode**
Record: Build warning, or build *error* when WERROR is on. Severity:
MEDIUM for CI/allmodconfig (broken compile), LOW at runtime (no
functional bug).

**Step 8.4: Risk-benefit**
Record: Benefit: restores allmodconfig/WERROR builds on gcc 15 (and
likely similar compilers). Risk: very low — one-line initializer, proven
pattern in the same function. Ratio: favorable.

---

## Phase 9: Synthesis

**Step 9.1: Evidence**

FOR:
- Explicit **build-fix** exception (compilation warnings/errors).
- Reproduced: gcc 15.3.0, ARCH=arc allmodconfig.
- With `CONFIG_WERROR` this is a hard build failure
  (`-Werror=uninitialized`), same class as 542440fd7b309, which is
  already in this tree.
- One line, obviously correct, no runtime change.
- Buggy (uninitialized) locals exist in v6.18.53; patch applies cleanly.
- Maintainer (Mark Brown) applied it; no NAKs.

AGAINST:
- Not a runtime crash/corruption/security bug.
- Applied to for-7.3 (merge window), not a -fixes pull, so not treated
  as urgent by the maintainer.
- Narrowest documented trigger is ARC + gcc 15 + allmodconfig.
- No Cc: stable (expected; not a negative).

UNRESOLVED:
- Whether gcc 15 also warns on x86/arm allmodconfig for 6.18 was not
  reproduced here (author only cited ARC).
- lore.kernel.org HTTP fetch returned 403; discussion recovered via `b4
  dig -m` and openwall/patchew mirrors.

**Step 9.2: Stable rules**
1. Obviously correct and tested? **PASS** — dummy init; author built ARC
   allmodconfig; maintainer applied.
2. Real bug affecting users? **PASS** as a build break under
   WERROR/allmodconfig; not a runtime bug.
3. Important (crash/security/corruption/deadlock)? **FAIL** as a runtime
   issue; **PASS** under the build-fix exception.
4. Small and contained? **PASS** — 1 line, 1 file.
5. No new features/APIs? **PASS**.
6. Can apply to this tree? **PASS** — v6.18.53 has the pre-image.

**Step 9.3: Exception**
Record: **Build fix** (compiler warning that becomes a compile error
with WERROR).

**Step 9.4: Decision**
This is a one-line, zero-risk workaround for a real gcc 15 false-
positive that breaks `CONFIG_WERROR` builds of a file this 6.18.y tree
already ships. It matches the gcc-14 workaround already present here. It
meets the build-fix exception and applies cleanly.

---

### What the commit solves for this tree

v6.18.53 still declares `upper_index`/`upper_last` uninitialized in
`regcache_maple_drop()`. gcc 15.3.0 (ARC allmodconfig) warns; with
WERROR that fails the kernel build. Initializing them to 0, as already
done for `lower_index`/`lower_last`, silences the diagnostic without
changing runtime behavior.

### Risk vs benefit

Benefit is restoring compiles for WERROR/allmodconfig (and silencing the
warning otherwise). Risk is a dead store of 0. No prerequisites beyond
code already in 6.18.y.

### Verification
- [Phase 1] Parsed tags: Link to msgid, SOBs from Uwe Kleine-König and
  Mark Brown; no Fixes/Reported-by/Cc: stable
- [Phase 2] Diff: 1 line in `regcache_maple_drop()`; `upper_index,
  upper_last` → `= 0`
- [Phase 2] Read function: `upper_*` assigned only when `mas.last >
  max`, used only under `if (upper)`
- [Phase 3] blame: maple cache f033c26de5a57 (v6.4); lower_* init
  542440fd7b309 (in this tree)
- [Phase 3] `git merge-base --is-ancestor 542440fd7b309 HEAD` → yes;
  `dffd32eb2b0e` vs v6.18.53 → not ancestor
- [Phase 3] `git show 542440fd7b309`: same -Werror=uninitialized class
  for `lower_index`
- [Phase 4] `b4 dig -c dffd32eb2b0e`: lore msgid
  20260626060427.2548578-2; v1 only; applied for-7.3
- [Phase 4] `b4 dig -w`: Mark Brown, Greg KH, driver-core CC’d
- [Phase 4] mbox: Mark Brown applied [1/1]; no NAK, no stable Cc
- [Phase 4] WebFetch lore/msgid.link: 403; recovered via openwall +
  patchew + mbox
- [Phase 5] callers: `regcache_ops.drop` → `regcache_drop_region()`;
  warning is compile-time
- [Phase 6] `git describe HEAD` / `make kernelversion`: 6.18.53
- [Phase 6] `v6.18.53:drivers/base/regmap/regcache-maple.c` still has
  `unsigned long upper_index, upper_last;`
- [Phase 7] init/Kconfig: `config WERROR` default `COMPILE_TEST`;
  Makefile.extrawarn adds `-Werror`
- [Phase 8] Failure mode: compile warning/error, not runtime oops
- UNVERIFIED: whether gcc 15 warns on non-ARC 6.18 allmodconfig (author
  only reported ARC)

**YES**

 drivers/base/regmap/regcache-maple.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/base/regmap/regcache-maple.c b/drivers/base/regmap/regcache-maple.c
index 9cf0384ce7b95..615ecb89d5377 100644
--- a/drivers/base/regmap/regcache-maple.c
+++ b/drivers/base/regmap/regcache-maple.c
@@ -112,7 +112,7 @@ static int regcache_maple_drop(struct regmap *map, unsigned int min,
 	unsigned long *entry, *lower, *upper;
 	/* initialized to work around false-positive -Wuninitialized warning */
 	unsigned long lower_index = 0, lower_last = 0;
-	unsigned long upper_index, upper_last;
+	unsigned long upper_index = 0, upper_last = 0;
 	int ret = 0;
 
 	lower = NULL;
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH AUTOSEL 6.18-6.12] regmap: Remove debugfs before cache teardown
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
  2026-10-19 13:45 ` [PATCH AUTOSEL 6.18] regmap: irq: Free the irqdomain we create Sasha Levin
  2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-6.6] regmap: maple: Workaround for another false-positive compiler warning Sasha Levin
@ 2026-10-19 13:50 ` Sasha Levin
  2026-10-19 13:53 ` [PATCH AUTOSEL 6.18-5.10] driver core: attribute_container: Unwind device_add() on attr failure Sasha Levin
  3 siblings, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2026-10-19 13:50 UTC (permalink / raw)
  To: patches, stable
  Cc: Michael Reeves, Peng Fan, Mark Brown, Sasha Levin, gregkh, rafael,
	dakr, linux-kernel, driver-core

From: Michael Reeves <michael.reeves077@gmail.com>

[ Upstream commit 834035934cef9e60169de682f4dc9feafd49e51a ]

regmap_exit() and regmap_reinit_cache() destroy the register cache before
removing debugfs. A concurrent debugfs cache operation can therefore
access cache state after the backend exit callback starts freeing it.

Remove debugfs before cache teardown, and clear the debugfs pointer after
removal. During cache reinitialization, recreate debugfs only after the
new cache initializes successfully.

Signed-off-by: Michael Reeves <michael.reeves077@gmail.com>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Link: https://patch.msgid.link/20261006-regcache-lifecycle-submit-v3-1-37bdd82fd47c@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **6.18.57**. The buggy teardown order is present at
`v6.18.57`; this commit is a small UAF-lifecycle fix that applies here
and should be backported.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

**Step 1.1: PARSE THE SUBJECT LINE**
Record: `[regmap] [Remove] Remove debugfs before cache teardown`

- Subsystem: `regmap` (drivers/base/regmap)
- Verb: “Remove” — here it is a lifecycle reorder, not a feature
  deletion
- Intent: tear down debugfs *before* the register cache so concurrent
  debugfs cache ops cannot touch freed cache state

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- `Reviewed-by: Peng Fan <peng.fan@nxp.com>` — NXP reviewer, active on
  regmap
- `Link: https://patch.msgid.link/20261006-regcache-lifecycle-
  submit-v3-1-37bdd82fd47c@gmail.com`
- `Signed-off-by: Michael Reeves <michael.reeves077@gmail.com>` (author)
- `Signed-off-by: Mark Brown <broonie@kernel.org>` (regmap maintainer)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Acked-by:`, or `Cc:
  stable` (absence is expected for this review)
- Ignored pipeline markers: `[Upstream commit 834035934cef…]`, `Signed-
  off-by: Sasha Levin`

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** `regmap_exit()` and `regmap_reinit_cache()` call
  `regcache_exit()` *before* `regmap_debugfs_exit()`. A concurrent
  debugfs cache operation can then run after the backend `exit` callback
  has started freeing cache memory.
- **Symptom:** use-after-free / invalid cache access from debugfs
  (registers dump, rbtree dump, `cache_only` sync).
- **Root cause:** debugfs lifetime is not drained before cache teardown.
  `debugfs_remove_recursive()` is the drain point and must run first.
- **Fix:** remove debugfs first; NULL `map->debugfs` after removal; on
  reinit, recreate debugfs only after `regcache_init()` succeeds.
- **Versions:** none named. Blame shows this order has existed since
  2011–2012.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not disguised. It is an explicit UAF/lifecycle fix. The reinit
change also closes a second hole: old code recreated debugfs *before*
the new cache existed, so `cache_ops->debugfs_init` / cache dumps could
run against a destroyed cache.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

**Step 2.1: INVENTORY THE CHANGES**
Record:
- `drivers/base/regmap/regmap-debugfs.c`: +1 (`map->debugfs = NULL`)
- `drivers/base/regmap/regmap.c`: +9 / −6
- Functions: `regmap_debugfs_exit()`, `regmap_reinit_cache()`,
  `regmap_exit()`
- Scope: surgical, two files, net +4 lines in this tree (`1/0` and
  `9/6`)

Mainline context in the submission has `debugfs_dummy_id` / `dummy_ida`;
this 6.18 tree does not. The functional hunks are the same and already
applied as `944c051717d77`.

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:

Hunk 1 — `regmap_debugfs_exit()`:
- Before: `debugfs_remove_recursive(map->debugfs)` left a stale dentry
  pointer.
- After: `map->debugfs = NULL` immediately after removal.

Hunk 2 — `regmap_reinit_cache()`:
- Before: `regcache_exit` → `regmap_debugfs_exit` →
  `regmap_debugfs_init` → `regcache_init`.
- After: `regmap_debugfs_exit` → `regcache_exit` → `regcache_init` → on
  success `regmap_debugfs_init`. Failed cache init leaves debugfs down
  instead of exposing a dead cache.

Hunk 3 — `regmap_exit()`:
- Before: `regcache_exit` then `regmap_debugfs_exit`.
- After: reverse that order.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: **(d) Memory safety / UAF** plus **(g) lifecycle correctness**.

Verified mechanism:
- `regcache_rbtree_exit()` does `kfree(map->cache); map->cache = NULL`.
- `rbtree_show()` does `rbtree_ctx = map->cache` then walks
  `rbtree_ctx->root` under the map lock.
- `regmap_read_debugfs()` calls `regmap_read()`, which can hit
  `regcache_read()` / `cache_ops`.
- `regmap_cache_only_write_file()` can call `regcache_sync()` on a
  destroyed cache.

`debugfs_remove_recursive()` waits for in-flight file ops
(`debugfs_file_get` / `active_users_drained` in `fs/debugfs/file.c`).
Calling it *after* `regcache_exit()` is the wrong order: ops already in
flight (or still open until remove starts) can touch freed cache.
Calling it first drains those ops, then the cache can be freed.

**Step 2.4: ASSESS THE FIX QUALITY**
Record: Obviously correct. Standard “remove debugfs, then free private
data” pattern. No API/data-structure change.
`debugfs_remove_recursive()` already sleeps, so moving it earlier does
not add a new sleep-in-atomic constraint. Reinit already documents that
callers must serialize against other *regmap* calls; this still
serializes *userspace* debugfs, which the driver cannot.

Regression risk: **low**. Failed `regcache_init()` now skips debugfs
recreate (debugfs stays gone). That is safer than the old “debugfs live,
cache dead/uninitialized” window.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

**Step 3.1: BLAME THE CHANGED LINES**
Record (on parent of `944c051717d77`):
- `regcache_exit` before debugfs in `regmap_reinit_cache`:
  `bf315173359b2` (Mark Brown, 2011-12-03)
- `regmap_debugfs_exit` added there: `a24f64a6483767` (2012-01-26)
- `regcache_exit` before debugfs in `regmap_exit`: `5d1729e7f02f05`
  (2011-09-19) then `31244e396fa9e4` (2011-07-20)
- `debugfs_remove_recursive` without NULL: `a52eaeb1898bc0` (2013-10-24)

The buggy order is ancient and is in this 6.18 tree.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No `Fixes:` tag. Not applicable. Introduced with original regmap
debugfs/cache teardown, not a recent regression.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record:
- `530792efa6cb8` “regmap: Call regmap_debugfs_exit() prior to _init()”
  — same “debugfs off before reuse” idea.
- `9f711c9321cff` “regmap: get rid of redundant
  debugfs_file_{get,put}()” — debugfs core now owns the drain; this
  patch is the remaining lifecycle piece.
- This is **patch 1/2** of “regmap: Fix cache lifecycle locking and
  teardown”. Patch 2 (“Drop map lock during cache init and exit”) is a
  **separate lockdep** fix (`Fixes: fd4ebc07b4df`). Patch 2’s upstream
  `abff0a48b110` is **not** in this tree and is **not** a prerequisite
  for patch 1.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Only this commit by Michael Reeves under `drivers/base/regmap/`
in this tree. Not the subsystem maintainer. Applied by **Mark Brown**.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: Standalone. Uses existing `regmap_debugfs_exit` /
`regcache_exit` / `regcache_init`. Dummy-ida context from later mainline
is absent here and is not required.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig -c 944c051717d77` →
  https://patch.msgid.link/20261006-regcache-lifecycle-
  submit-v3-1-37bdd82fd47c@gmail.com
- Revisions:
  - v1 (2026-09-25): lockdep-only, no debugfs reorder
  - v2 (2026-10-04): added this debugfs ordering fix
  - v3 (2026-10-06): this version; maple irqsave helpers are **patch 2
    only**
- Peng Fan: `Reviewed-by` on patch 1; no NAK
- Mark Brown applied both to `broonie/regmap.git for-7.3`
  (`834035934cef`, `abff0a48b110`)
- No reviewer asked for `Cc: stable`
- Cover letter testing (Apple M3, lockdep, KUnit) is mainly for patch 2;
  patch 1 is justified by code inspection

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record (`b4 dig -w`): Mark Brown, Greg Kroah-Hartman, Rafael Wysocki,
Danilo Krummrich, Liam Howlett; lists: linux-kernel, driver-core, maple-
tree, asahi, linux-mm. Subsystem maintainer received and applied it.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: No syzbot, bugzilla, or user crash report. Bug is from code
analysis of teardown vs debugfs.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: Series of 2. This patch does not depend on maple irqsave helpers
or dropping the map lock. Patch 2 is a different bug (lockdep during
Apple GPIO probe).

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: No stable-list discussion found (lore.kernel.org returned 403;
searches did not hit this subject). UNVERIFIED beyond that negative
search.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

**Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF**
Record: `regmap_debugfs_exit`, `regmap_reinit_cache`, `regmap_exit`
(callers of `regcache_exit` / debugfs init).

**Step 5.2: TRACE CALLERS**
Record:
- `regmap_exit()`: many drivers (ASoC via
  `snd_soc_component_exit_regmap`, HDA, MFD, media/DVB, IIO, input, USB,
  leds, syscon, kunit, `devres` cleanup). Common unbind/remove path.
- `regmap_reinit_cache()`: ASoC (mt8192/mt8183, tas2764/tas2770, da7219,
  ssm3515), MFD (wm8994, wm8400), IIO (kx022a, several light/pressure
  sensors), pinctrl-aw9523. Probe/runtime rediscovery.
- `regmap_debugfs_exit()` also from `regmap_attach_dev()` (already exit-
  then-init) and `__regmap_init` error paths.

**Step 5.3: TRACE CALLEES**
Record: `debugfs_remove_recursive` (sleeps until file ops drain),
`regmap_debugfs_free_dump_cache`, `regcache_exit` → `cache_ops->exit`
(rbtree/maple/flat free `map->cache`).

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: Reachable from userspace:
1. Open `/sys/kernel/debug/regmap/<dev>/registers` or `rbtree`
2. Concurrent unbind / module unload / `regmap_reinit_cache()`
3. Old order frees cache while the read can still run → UAF

Needs `CONFIG_DEBUG_FS` (stubs make this a no-op otherwise) and
typically debugfs access (often root). Distro/Android kernels commonly
enable debugfs.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: Only rbtree implements `cache_ops->debugfs_init` here.
Maple/flat have no extra debugfs file, but the shared `registers` /
`cache_only` files still go through the cache. Same class of bug as
other “remove debugfs before free private data” fixes.

===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: **Yes.** `git describe HEAD` = `v6.18.57-155-gcdf239ca885b2`.
`make kernelversion` = `6.18.57`. At tag `v6.18.57`,
`regmap_exit`/`regmap_reinit_cache` still call `regcache_exit` first.
`git merge-base --is-ancestor 944c051717d77 v6.18.57` is false — the fix
is not in the 6.18.57 baseline.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: **Clean apply.** Candidate `944c051717d77` applied here with
only missing dummy-ida context vs mainline. No refactor blocking it.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: No other commit in this tree reorders cache vs debugfs teardown.
Patch 2 is absent and not required.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: `drivers/base/regmap` — **IMPORTANT/CORE-adjacent**. Shared
register cache for ASoC, MFD, IIO, pinctrl, regulators, etc.

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: Mature (2011+) and still actively maintained by Mark Brown. This
is a long-standing lifecycle bug, not a brand-new subsystem.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: Any user with `CONFIG_REGMAP` + `CONFIG_DEBUG_FS` and a cached
regmap. Driver-specific devices, but the core path is widely used. No-op
if debugfs is off.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record: Concurrent debugfs access during
`regmap_exit`/`regmap_reinit_cache`. Timing-dependent. Typical trigger
is root/debugfs; unprivileged access depends on debugfs mount mode.
Unbind during a dump is realistic (USB audio, codec remove, module
unload).

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record: Use-after-free of cache memory → oops or memory corruption.
**HIGH** (UAF). Not a guaranteed panic on every unbind; still a real
memory-safety bug.

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record:
- **Benefit:** Prevents UAF on a common infrastructure path when debugfs
  is used around teardown/reinit.
- **Risk:** Very low — ~10 lines, order swap + NULL + delayed debugfs
  recreate.
- **Ratio:** Favor backport.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- Real UAF: cache freed while debugfs files can still run
  (`rbtree_show`, `regmap_read_debugfs`, `regcache_sync` from
  `cache_only`)
- `debugfs_remove_recursive()` is the documented drain; it must run
  before `regcache_exit`
- Bug present in this 6.18.57 tree since 2011–2012
- Small, obviously correct, reviewed, applied by the regmap maintainer
- Applies cleanly; no dependency on patch 2
- Hidden extra fix: do not recreate debugfs on a not-yet-initialized
  cache

AGAINST:
- No syzbot/user report
- Needs debugfs and concurrent teardown
- Series patch 1/2 (but self-contained)
- Maintainer queued it for 7.3, not as an emergency -fixes drop
- No `Cc: stable` (not a negative per these rules)

UNRESOLVED:
- lore.kernel.org HTTP 403; thread recovered via `b4 dig` + LKML mirrors
- No stable-list thread found

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — order is the documented
   debugfs lifetime rule; v3 reviewed; KUnit mentioned in the series;
   maintainer applied it
2. Fixes a real bug that affects users? **PASS** — UAF on debugfs vs
   cache teardown
3. Important issue? **PASS** — UAF/oops, HIGH; not a style change
4. Small and contained? **PASS** — 2 files, ~10 net lines
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — clean against 6.18.57

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: Not an ID/quirk/DT/build/docs exception. Ordinary memory-safety
fix.

**Step 9.4: MAKE YOUR DECISION**
Backport. The bug exists in this tree, the fix is the correct lifecycle,
and risk is minimal. Debugfs-only does not make a UAF incommensurate
with stable: CONFIG_DEBUG_FS is common, and `regmap_exit` runs on
ordinary unbind.

What it solves for stable users: a use-after-free if debugfs is used
while a cached regmap is torn down or its cache is reinitialized. That
is a crash/corruption class bug in widely used driver-core code.

Risk vs benefit: large benefit relative to a four-line-class reorder. No
public API change. Patch 2 is not required.

===============================================================
Verification
===============================================================
- [Phase 1] Parsed tags: Reviewed-by Peng Fan; Link msgid; SOB Reeves +
  Mark Brown; no Fixes/Reported-by/Cc-stable
- [Phase 2] Diff: +NULL after `debugfs_remove_recursive`; swap
  `regcache_exit`/`regmap_debugfs_exit` in exit and reinit; delay
  `regmap_debugfs_init` until `regcache_init` succeeds
- [Phase 2] `regcache_rbtree_exit` kfree’s `map->cache`; `rbtree_show`
  dereferences it — UAF confirmed in this tree
- [Phase 2] `fs/debugfs/file.c`: `debugfs_remove_recursive` waits on
  `debugfs_file_get` / `active_users_drained`
- [Phase 3] Blame: teardown order from 2011–2012 (Brown/Papastamos)
- [Phase 3] `git merge-base --is-ancestor 944c051717d77 v6.18.57` → not
  in 6.18.57 baseline
- [Phase 3] Patch 2 `abff0a48b110` not an ancestor of HEAD; not a
  prerequisite
- [Phase 3] `fd4ebc07b4df` is in HEAD (only relevant to patch 2)
- [Phase 4] `b4 dig -c 944c051717d77`: lore msgid 20261006-regcache-
  lifecycle-submit-v3-1-…
- [Phase 4] `b4 dig -a`: v1 lockdep-only → v2 added this fix → v3
  applied
- [Phase 4] `b4 dig -w`: Mark Brown, driver-core, Greg KH CC’d; Peng Fan
  Reviewed-by; Mark applied to for-7.3
- [Phase 4] lore.kernel.org WebFetch 403; used b4 mbox + lkml.iu.edu
- [Phase 5] Callers: many `regmap_exit` sites; `regmap_reinit_cache` in
  ASoC/MFD/IIO/pinctrl
- [Phase 6] `git describe HEAD` = v6.18.57-155-gcdf239ca885b2; `make
  kernelversion` = 6.18.57; buggy order present at v6.18.57
- [Phase 6] Candidate diff vs this tree is clean (no dummy_ida here)
- [Phase 8] Failure mode: UAF → oops/corruption, HIGH; trigger: debugfs
  + teardown
- UNVERIFIED: no stable@ thread located (search did not find this
  subject)

**YES**

 drivers/base/regmap/regmap-debugfs.c |  1 +
 drivers/base/regmap/regmap.c         | 15 +++++++++------
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c
index c9b4c04b1cf60..98debe5020641 100644
--- a/drivers/base/regmap/regmap-debugfs.c
+++ b/drivers/base/regmap/regmap-debugfs.c
@@ -657,6 +657,7 @@ void regmap_debugfs_exit(struct regmap *map)
 {
 	if (map->debugfs) {
 		debugfs_remove_recursive(map->debugfs);
+		map->debugfs = NULL;
 		mutex_lock(&map->cache_lock);
 		regmap_debugfs_free_dump_cache(map);
 		mutex_unlock(&map->cache_lock);
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index a648218507236..b80bbe9033188 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1424,8 +1424,8 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
 {
 	int ret;
 
-	regcache_exit(map);
 	regmap_debugfs_exit(map);
+	regcache_exit(map);
 
 	map->max_register = config->max_register;
 	map->max_register_is_set = map->max_register ?: config->max_register_is_0;
@@ -1441,12 +1441,16 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
 	if (ret)
 		return ret;
 
-	regmap_debugfs_init(map);
-
 	map->cache_bypass = false;
 	map->cache_only = false;
 
-	return regcache_init(map, config);
+	ret = regcache_init(map, config);
+	if (ret)
+		return ret;
+
+	regmap_debugfs_init(map);
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(regmap_reinit_cache);
 
@@ -1460,9 +1464,8 @@ void regmap_exit(struct regmap *map)
 	struct regmap_async *async;
 
 	regmap_detach_dev(map->dev, map);
-	regcache_exit(map);
-
 	regmap_debugfs_exit(map);
+	regcache_exit(map);
 	regmap_range_exit(map);
 	if (map->bus && map->bus->free_context)
 		map->bus->free_context(map->bus_context);
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] driver core: attribute_container: Unwind device_add() on attr failure
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (2 preceding siblings ...)
  2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-6.12] regmap: Remove debugfs before cache teardown Sasha Levin
@ 2026-10-19 13:53 ` Sasha Levin
  3 siblings, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2026-10-19 13:53 UTC (permalink / raw)
  To: patches, stable
  Cc: Yuho Choi, Greg Kroah-Hartman, Sasha Levin, rafael, dakr,
	driver-core, linux-kernel

From: Yuho Choi <dbgh9129@gmail.com>

[ Upstream commit 8cfe7ad274bb42c4653b645267410d4a3a23db98 ]

attribute_container_add_class_device() first calls device_add() and then
creates the container attributes. If attribute_container_add_attrs() fails,
the helper returns the error with the class device still registered.

Callers use an error from this helper as a failed add and do not call
device_del() on that path. Undo the successful device_add() before
returning the attribute creation error.

Signed-off-by: Yuho Choi <dbgh9129@gmail.com>
Link: https://patch.msgid.link/20260608172717.88657-1-dbgh9129@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## Phase 1: Commit message forensics

**Step 1.1: Subject line**
Record: **[driver core / attribute_container] [Unwind] [on
`device_add()` success, roll back if attribute creation fails]**

**Step 1.2: Tags**
Record:
- **Link:**
  `https://patch.msgid.link/20260608172717.88657-1-dbgh9129@gmail.com`
- **Signed-off-by:** Yuho Choi (author)
- **Signed-off-by:** Greg Kroah-Hartman (driver-core maintainer)
- **Committer:** Danilo Krummrich
- **No** `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Acked-
  by:`, or `Cc: stable` (absence of the last two is expected for this
  review)
- Ignore any pipeline `Signed-off-by: Sasha Levin` / `[Upstream commit
  …]` markers; they are not in the real commit

**Step 1.3: Body**
Record:
- **Bug:** `attribute_container_add_class_device()` does `device_add()`
  then `attribute_container_add_attrs()`. If attrs fail, the helper
  returns the error while the class device stays registered.
- **Symptom:** Callers treat the helper error as a failed add and do
  **not** `device_del()` that classdev.
- **Root cause:** Missing unwind of a successful `device_add()` on a
  later failure (classic probe-style leak).
- **Version info:** None in the message. History shows this pattern
  since 2005/2008.

**Step 1.4: Hidden bug fix?**
Record: **Not hidden.** This is an explicit error-path unwind /
leftover-registered-device fix, not a style cleanup.

---

## Phase 2: Diff analysis

**Step 2.1: Inventory**
Record:
- **File:** `drivers/base/attribute_container.c` — **+6 / −1**
- **Function:** `attribute_container_add_class_device()`
- **Scope:** single-file, surgical, error path only

**Step 2.2: Code flow**
Record: **Before:** `device_add()` success → `return
attribute_container_add_attrs()` (classdev stays registered on attr
failure). **After:** store attr error; on failure call
`device_del(classdev)`; return that error. Normal success path
unchanged.

**Step 2.3: Bug mechanism**
Record: **[error-path resource leak / incomplete unwind]**
`device_add()` publishes the classdev (sysfs, parent child list,
kobject). `attribute_container_add_attrs()` can fail via
`sysfs_create_group()` or `device_create_file()` (typically `-ENOMEM`,
also `-EEXIST` / other sysfs errors). Returning that error without
`device_del()` leaves a live classdev. Pairing is correct: callers
`device_initialize()` + this helper’s `device_add()`, so unwind is
`device_del()`, not `device_unregister()`.

**Step 2.4: Fix quality**
Record: **Obviously correct, textbook unwind, no API/data-structure
change.** Regression risk is low. Verified callers of this helper do
**not** `device_del(classdev)` on this error (they go to
`tclass->remove` only). `tclass->remove` implementations
(`sas_host_remove`, `fc_host_remove`, `iscsi_remove_host`,
`raid_remove`) do not `device_del` the classdev. No double-`device_del`.

---

## Phase 3: Git history

**Step 3.1: Blame**
Record: Missing unwind is original behavior.
- Function in `1da177e4c3f41` (Linux 2.6.12-rc2, 2005) as
  `class_device_add` + attrs.
- `ee959b00c335d7` (2008) converted it to `device_add` (`SCSI: convert
  struct class_device to struct device`).
- Bug present for ~18 years. This tree’s current lines 428–433 are this
  commit.

**Step 3.2: Fixes: tag**
Record: **None.** Equivalent historical target would be `1da177e4c3f41`
/ `ee959b00c335d7`. Both are ancestors of this tree.

**Step 3.3: File history**
Record (recent, this file): related error-path work already here:
- `e5da06b27ff5a` (2023) — `transport_class`: call `->remove()` if
  `transport_add_device()` fails (Fixes: `1da177e4c3f4`)
- `cd7ea70bb00aa` — propagate transport add errors
- `6e328b4a208f7` — unwind statistics group if encryption group create
  fails
This commit is **standalone** (not `n/m`). It complements those; it does
not depend on `6e328b4a208f7`.

**Step 3.4: Author**
Record: Yuho Choi is not the subsystem maintainer (a few driver-
core/regmap error-path patches). Weight comes from **Greg Kroah-Hartman
SOB** and **Danilo Krummrich** committing it.

**Step 3.5: Dependencies**
Record: **None.** Needs only `device_add` / `device_del` /
`attribute_container_add_attrs()`, all long-standing. Applies
standalone. `git merge-base --is-ancestor 8cfe7ad274bb4 HEAD` → **yes**
(commit is already in this checkout).

---

## Phase 4: Mailing list / external

**Step 4.1:**
Record: `b4 dig -c 8cfe7ad274bb4` →
https://patch.msgid.link/20260608172717.88657-1-dbgh9129@gmail.com
`b4 dig -a`: **v1 only**, 2026-06-08. Saved mbox: **one message** (the
patch), **no replies**. Direct lore fetch returned **403**. No NAKs
found. No public reviewer request for `Cc: stable`.

**Step 4.2:**
Record: `b4 dig -w` recipients: Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich, `driver-core@lists.linux.dev`, `linux-
kernel@vger.kernel.org`. Right maintainers were on the original To/Cc.

**Step 4.3:**
Record: **No bugzilla/syzbot/user report.** Looks like code inspection,
not a production crash report.

**Step 4.4:**
Record: Standalone v1, not a multi-patch series.

**Step 4.5:**
Record: Web search of lore/stable for this subject/author found **no**
stable-list discussion (search results were unrelated). **UNVERIFIED:**
whether anyone previously rejected it for stable.

---

## Phase 5: Semantic / call graph

**Step 5.1:**
Record: Modified function: `attribute_container_add_class_device()`.

**Step 5.2: Callers**
Record (this tree):
1. `transport_add_class_device()` in `drivers/base/transport_class.c` —
   **the live caller**. On helper error → `err_remove` →
   `tclass->remove` only, **not**
   `attribute_container_class_device_del()`.
2. Default `fn == NULL` path in `attribute_container_add_device()` —
   still present; **no in-tree caller passes NULL**
   (`attribute_container_add_device` is only used from
   `transport_setup_device()` with `transport_setup_classdev`).

`transport_add_device()` / `transport_register_device()` are used by
SCSI (SAS/FC/iSCSI/SRP/SPI, `scsi_sysfs.c`) and **libata**. Always-
built: `drivers/base/Makefile` lists `attribute_container.o` and
`transport_class.o`.

**Step 5.3: Callees**
Record: `device_add`, `attribute_container_add_attrs` →
`sysfs_create_group` / `device_create_file`, and on failure
`device_del`.

**Step 5.4: Reachability**
Record: **Yes, from normal storage bring-up**, not a syscall gadget.
Path: SCSI/ATA device add → `transport_add_device()` →
`transport_add_class_device()` → this helper. Trigger is **attr creation
failure**, not every boot. Unprivileged users cannot typically force it
except via memory pressure / device hotplug.

**Step 5.5: Similar patterns**
Record: Same file already uses `attribute_container_class_device_del()`
= remove attrs + `device_del`. `e5da06b27ff5a` is the sibling leak on
the transport `->setup()`/`->remove()` side. This fills the remaining
`device_add` hole.

---

## Phase 6: This checkout

**Step 6.1:**
Record: **Local tree: `v7.3-rc4-27-gf0100363d8c37`, `make kernelversion`
= 7.3.0-rc4** (mainline, VERSION 7 / PATCHLEVEL 3).
Buggy pre-image exists as parent of `8cfe7ad274bb4`; the **fix is
already in HEAD**. Surrounding helper and SCSI/ATA callers exist and
match the commit’s claim. Bug introduced ~2.6.12 / 2008 conversion —
**long before this tree**.

**Step 6.2:**
Record: Function body before the commit is exactly the diff context.
**Clean apply** on this lineage. No conflicting refactor of this helper.

**Step 6.3:**
Record: Related transport unwind (`e5da06b27ff5a`, `6e328b4a208f7`) is
already here. **No alternate fix** of this specific
`device_add`/`add_attrs` hole besides `8cfe7ad274bb4`.

---

## Phase 7: Subsystem context

**Step 7.1:**
Record: **driver core (`drivers/base/`)** used by SCSI/ATA transport
classes. Criticality: **IMPORTANT** (not mm/scheduler, but common on
servers/storage). Not staging.

**Step 7.2:**
Record: File is mature (2005); recent commits are small fixes and
treewide alloc changes, not a rewrite. Fits a long-standing error-path
hole, not a new-API follow-up.

---

## Phase 8: Impact and risk

**Step 8.1:**
Record: **Driver-core + SCSI/ATA/iSCSI/FC/SAS users** (large storage
population). Not universal for every kernel, but a default
`drivers/base` object.

**Step 8.2:**
Record: Trigger = `attribute_container_add_attrs()` failure after
successful `device_add()`. Uncommon (mostly ENOMEM / sysfs errors)
during host/target/rport/phy add. Not a race. Not a normal unprivileged
syscall.

**Step 8.3:**
Record: **Failure mode: leftover registered classdev** (sysfs node,
parent child, refs). Callers that then `device_del()` the **parent**
(verified: `ata_tport_add`, `sas_phy_add`) can tear down a parent while
the classdev child is still registered. That is sysfs/kobject
inconsistency, leak, and possible later `-EEXIST` / warnings — **HIGH**,
not a panic on the happy path. Not a CVE-class issue from the evidence
found.

**Step 8.4:**
Record: **Benefit: medium-high** for storage error paths (correct
unwind, avoids stale classdev). **Risk: very low** (5 net lines, error
path, pairing `device_add`/`device_del`). Ratio favors inclusion.

---

## Phase 9: Synthesis

**Step 9.1: Evidence**

**For:**
- Real incomplete unwind: registered device returned as failure
- Callers verified not to `device_del(classdev)` on that error
- Parent `device_del` after this failure is a concrete consistency
  hazard (libata/SAS)
- Tiny, obviously correct; Greg KH signed off
- Same class as `e5da06b27ff5a`, which treated this area as a real leak
  (`Fixes: 1da177e4c3f4`)
- Code and callers exist in this tree; no extra commits required
- Always-built driver core, SCSI/ATA bring-up

**Against:**
- No `Reported-by` / syzbot / crash log
- Error path only; not a guaranteed oops
- No public review comments in the matched thread
- No `Fixes:` (author omission, not a reason to reject)

**Unresolved:** lore HTTP 403; no stable-list hit; how often
`add_attrs()` fails in the field.

**Step 9.2: Stable rules**
1. Obviously correct and tested? **PASS** — pairing is standard; merged
   by driver-core (no extra test tags).
2. Real user-affecting bug? **PASS** — leftover classdev on SCSI/ATA add
   failure.
3. Important (crash/security/corruption/deadlock)? **PASS** at leak /
   kobject-inconsistency severity (HIGH, not panic). Matches error-path
   leak fixes stable routinely takes.
4. Small and contained? **PASS** — one function, +6/−1.
5. No new features/APIs? **PASS**.
6. Can apply to this tree? **PASS** — context matches; already ancestor
   of HEAD, so no backport conflict here.

**Step 9.3: Exception category**
Record: **None** (not a device ID/quirk/DT/build/doc exception). It is a
normal small bugfix.

**Step 9.4: Decision**
This tree is **mainline 7.3-rc4**, which already contains the fix. That
does not make the change “already selected for stable”; it means the
buggy helper and the SCSI/ATA callers this commit talks about **are this
tree’s code**. The patch is a self-contained unwind of a leaked
registered class device. It should be treated as stable-worthy for this
codebase.

---

## What the commit solves for this tree

`attribute_container_add_class_device()` is the helper behind SCSI/ATA
transport class devices. It published the classdev, then created
attributes, and on attribute failure returned an error while leaving the
classdev registered. `transport_add_class_device()` treats that as a
failed add and only runs `tclass->remove()` (bsg/raid cleanup), not
`device_del()`. ATA/SAS callers then `device_del()` the **parent**. That
is a real leak and a parent/child sysfs mismatch on a failed add.

The fix is five lines: `device_del()` if
`attribute_container_add_attrs()` fails. No new API, no series
dependency, low regression risk.

---

## Verification

- **[Phase 1]** Parsed `8cfe7ad274bb4`: Link + two SOBs (Yuho Choi, Greg
  KH); committer Danilo Krummrich; no Fixes/Reported-by/Cc:stable
- **[Phase 2]** Diff: `attribute_container_add_class_device()` +6/−1;
  `device_del` on attr error only
- **[Phase 2]** Read `transport_add_class_device()`: helper error →
  `err_remove`, not `err_del` / `attribute_container_class_device_del`
- **[Phase 2]** Read `sas_host_remove` / `fc_host_remove` /
  `iscsi_remove_host` / `raid_remove`: no `device_del(classdev)`
- **[Phase 3]** `git blame`: hole from `1da177e4c3f41` (2005) /
  `ee959b00c335d7` (2008)
- **[Phase 3]** `git show 8cfe7ad274bb4^`: pre-image is `return
  attribute_container_add_attrs(classdev);`
- **[Phase 3]** Related: `e5da06b27ff5a` (2023 transport remove-on-add-
  fail), already in this tree
- **[Phase 3]** `git merge-base --is-ancestor 8cfe7ad274bb4 HEAD` → yes
- **[Phase 4]** `b4 dig -c/-a/-w/-m`: v1 only; maintainers CC’d; mbox
  has patch only, no replies
- **[Phase 4]** WebFetch lore: 403; stable search: no matching thread
- **[Phase 5]** Callers: `transport_class.c` + unused-looking NULL-fn
  path with no in-tree NULL caller
- **[Phase 5]** `transport_add_device` used from SCSI transports +
  `libata-transport.c` + `scsi_sysfs.c`
- **[Phase 5]** Confirmed `ata_tport_add` / `sas_phy_add` `device_del()`
  the parent on `transport_add_device()` error
- **[Phase 6]** `git describe HEAD` = `v7.3-rc4-27-gf0100363d8c37`;
  `make kernelversion` = 7.3.0-rc4
- **[Phase 6]** `drivers/base/Makefile`: `attribute_container.o` always
  built
- **[Phase 8]** Failure mode: leftover registered classdev / parent-
  child unwind bug, severity HIGH not panic
- **UNVERIFIED:** in-field hit rate of `add_attrs()` failure; any
  private review beyond the empty lore thread

**YES**

 drivers/base/attribute_container.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c
index b6f941a6ab693..b1d6eb6ab46b5 100644
--- a/drivers/base/attribute_container.c
+++ b/drivers/base/attribute_container.c
@@ -427,7 +427,12 @@ attribute_container_add_class_device(struct device *classdev)
 
 	if (error)
 		return error;
-	return attribute_container_add_attrs(classdev);
+
+	error = attribute_container_add_attrs(classdev);
+	if (error)
+		device_del(classdev);
+
+	return error;
 }
 
 /**
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-10-19 14:06 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20261019135441.1420968-1-sashal@kernel.org>
2026-10-19 13:45 ` [PATCH AUTOSEL 6.18] regmap: irq: Free the irqdomain we create Sasha Levin
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-6.6] regmap: maple: Workaround for another false-positive compiler warning Sasha Levin
2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-6.12] regmap: Remove debugfs before cache teardown Sasha Levin
2026-10-19 13:53 ` [PATCH AUTOSEL 6.18-5.10] driver core: attribute_container: Unwind device_add() on attr failure Sasha Levin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox