Thread (1 message) flat view 1 message, 1 author, 3d ago
HOTtoday

[PATCH AUTOSEL 6.18-5.10] phonet: check register_netdevice_notifier() error in phonet_device_init()

From: Sasha Levin <sashal@kernel.org>
Date: 2026-08-31 13:35:10
Also in: linux-patches, lkml, stable
Subsystem: networking [general], phonet protocol, the rest · Maintainers: "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Remi Denis-Courmont, Linus Torvalds

From: Minhong He <redacted>

[ Upstream commit d1ff66b66151c14b084e88040512a064b1c1e493 ]

phonet_device_init() registers a netdevice notifier before calling
phonet_netlink_register(), but does not check whether notifier
registration succeeded. On failure, netlink setup still proceeds and
init may return success without the notifier in place.

Also, the existing phonet_netlink_register() failure path called
phonet_device_exit(), which runs rtnl_unregister_all() even though
rtnl_register_many() already unwound any partial registration. Calling
the full exit helper on a partial init is not correct.

Check each registration error, including proc_create_net(), and unwind
only the steps that have succeeded so far, in reverse order.

Signed-off-by: Minhong He <redacted>
Link: https://patch.msgid.link/20260721093956.162617-1-heminhong@kylinos.cn
Signed-off-by: Jakub Kicinski <kuba@kernel.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: `[phonet]` `[check]` — Add missing error checking in
`phonet_device_init()` for notifier/proc registration and fix partial-
init unwind.

**Step 1.2 — Tags**

Record:
- `Signed-off-by: Minhong He [off-list ref]` (author)
- `Link:
  https://patch.msgid.link/20260721093956.162617-1-heminhong@kylinos.cn`
- `Signed-off-by: Jakub Kicinski [off-list ref]` (netdev maintainer)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Cc:
  stable@vger.kernel.org`, or syzbot tags

**Step 1.3 — Body analysis**

Record:
- **Bug:** `phonet_device_init()` registers a netdevice notifier and
  proc entry without checking return values. If notifier registration
  fails, netlink setup still runs and init can return success without
  the notifier.
- **Second bug:** On `phonet_netlink_register()` failure,
  `phonet_device_exit()` is called, which runs `rtnl_unregister_all()`
  even though `rtnl_register_many()` already unwound partial
  registrations.
- **Symptom:** Partially initialized Phonet subsystem reported as
  successfully loaded; incorrect teardown on failure paths.
- **Root cause:** Missing error checks and use of full exit helper
  instead of reverse-order partial unwind.

**Step 1.4 — Hidden bug fix?**

Record: **Yes.** Despite no "fix" in the subject, this is init error-
path correctness: unchecked registration failures and improper cleanup
on failure.

---

## Phase 2: Diff Analysis

**Step 2.1 — Inventory**

Record:
- **File:** `net/phonet/pn_dev.c` (~18 lines added, ~6 removed)
- **Functions:** `phonet_device_init()`, `phonet_device_exit()`
- **Scope:** Single-file, surgical init/exit fix

**Step 2.2 — Code flow changes**

Record:
- **Hunk 1 (`phonet_device_init`):** Before — `proc_create_net()` and
  `register_netdevice_notifier()` called with ignored return values;
  netlink failure calls full `phonet_device_exit()`. After — each step
  checked; labeled error paths unwind only completed steps in reverse
  order (`err_notifier` → `err_proc` → `err_pernet`).
- **Hunk 2 (`phonet_device_exit`):** Before —
  `unregister_pernet_subsys()` before `remove_proc_entry()`. After —
  `remove_proc_entry()` before `unregister_pernet_subsys()`, matching
  reverse of init order.

**Step 2.3 — Bug mechanism**

Record:
- **Category:** Error-path / resource-leak / logic correctness
- **Mechanism 1:** Ignored `register_netdevice_notifier()` failure →
  init can return 0 with no notifier; `phonet_device_notify()` never
  runs for `NETDEV_REGISTER`/`NETDEV_UNREGISTER`.
- **Mechanism 2:** Ignored `proc_create_net()` failure → silent loss of
  `/proc/net/pnresource`.
- **Mechanism 3:** `phonet_device_exit()` on netlink-only failure calls
  `rtnl_unregister_all(PF_PHONET)` after `__rtnl_register_many()`
  already unwound via `__rtnl_unregister_many()` (documented in
  `net/core/rtnetlink.c` lines 523–526).

**Step 2.4 — Fix quality**

Record: Fix is minimal, follows established netdev init patterns
(compare `mctp_device_init()` in this tree). Low regression risk; no API
changes.

---

## Phase 3: Git History Investigation

**Step 3.1 — Blame**

Record: Current buggy lines in `phonet_device_init()` are at
`net/phonet/pn_dev.c:351–372`. `git blame` attributes them to merge
`5d324e5159d9e` (2025-11-28); shallow stable history shows `pn_dev.c`
added in that merge, but file content dates to 2008 Phonet code.

**Step 3.2 — Fixes: tag**

Record: N/A — no `Fixes:` tag in commit message.

**Step 3.3 — Related file history**

Record:
- `52b8f5ef82c88` — phonet RCU UAF fix (already in this tree, `Cc:
  stable`)
- Other recent phonet stable backports: `a48a889b60f73` (pep UAF), skb
  overflow fixes
- **This commit is NOT yet in the tree**

**Step 3.4 — Author's other commits**

Record: Same author (Minhong He) has two nearly identical fixes
**already backported to this 6.18.44 tree**:
- `391a23c503856` — `mctp: check register_netdevice_notifier() error in
  mctp_device_init()`
- `50edffd0854fe` — `can: isotp: check register_netdevice_notifier()
  error in module init()`

**Step 3.5 — Dependencies**

Record: Standalone; no series or prerequisite commits required. All
symbols exist in this tree.

---

## Phase 4: Mailing List and External Research

**Step 4.1–4.5**

Record: **Could not verify** — `b4 dig` requires a commit hash not
present in this tree; lore.kernel.org and patch.msgid.link blocked by
bot protection (Anubis). No local mbox found for this patch.

UNVERIFIED: Reviewer stable nominations, NAKs, or thread discussion.

---

## Phase 5: Code Semantic Analysis

**Step 5.1 — Key functions**

Record: `phonet_device_init()`, `phonet_device_exit()`,
`phonet_device_notify()` (indirectly affected)

**Step 5.2 — Callers**

Record: `phonet_device_init()` called from `phonet_init()` in
`net/phonet/af_phonet.c:501` during `module_init`. Only runs when
`CONFIG_PHONET` module is loaded.

**Step 5.3 — Callees**

Record: `register_pernet_subsys()`, `proc_create_net()`,
`register_netdevice_notifier()`, `phonet_netlink_register()` →
`rtnl_register_many()`, and corresponding unregister/remove helpers.

**Step 5.4 — Reachability**

Record: Triggered at module load time under resource pressure (e.g.
`-ENOMEM` from notifier chain registration). Not userspace-syscall
reachable directly, but affects module load success semantics.

**Step 5.5 — Similar patterns**

Record: `phonet_init_net()` at line 325 already checks
`proc_create_net()` for the per-net `"phonet"` entry;
`phonet_device_init()` inconsistently does not check the `"pnresource"`
entry. Same notifier-check pattern fixed in `net/mctp/device.c` and
`net/can/isotp.c` in this tree.

---

## Phase 6: Cross-Reference Against Local Tree (6.18.44)

**Step 6.1 — Buggy code present?**

Record: **Yes.** Current code at `net/phonet/pn_dev.c:357–362`:

```351:363:net/phonet/pn_dev.c
int __init phonet_device_init(void)
{
        int err = register_pernet_subsys(&phonet_net_ops);
        if (err)
                return err;

        proc_create_net("pnresource", 0, init_net.proc_net,
&pn_res_seq_ops,
                        sizeof(struct seq_net_private));
        register_netdevice_notifier(&phonet_device_notifier);
        err = phonet_netlink_register();
        if (err)
                phonet_device_exit();
        return err;
}
**Step 6.2  Backport complications**

Record: **Clean apply expected**  no conflicting changes; only
`phonet_device_init()`/`phonet_device_exit()` affected.

**Step 6.3  Related fixes already present?**

Record: MCTP and CAN isotp notifier-check fixes present; phonet
equivalent absent. Phonet RCU/UAF fixes present, showing maintainers
accept phonet stable fixes.

---

## Phase 7: Subsystem Context

**Step 7.1  Subsystem and criticality**

Record: `net/phonet`  **PERIPHERAL** (Nokia Phonet protocol;
`CONFIG_PHONET` tristate, niche hardware). However, this tree actively
backports phonet fixes.

**Step 7.2  Activity**

Record: Multiple phonet stable backports in recent history (UAF, skb
overflow, RCU).

---

## Phase 8: Impact and Risk Assessment

**Step 8.1  Who is affected**

Record: Users who build/load the `phonet` kernel module (cellular modem
/ legacy Nokia platforms).

**Step 8.2  Trigger conditions**

Record: Failure of `register_netdevice_notifier()` or
`proc_create_net()` during module init  typically memory pressure
(`-ENOMEM`). Uncommon but possible.

**Step 8.3  Failure mode severity**

Record:
- **Partial success:** Module appears loaded but notifier missing 
  `phonet_device_notify()` never handles `NETDEV_UNREGISTER`, so
  `phonet_device_destroy()` and `phonet_route_autodel()` are skipped 
  **resource leaks and stale route state** (see `pn_dev.c:296309`).
- **Wrong cleanup:** Redundant/incorrect `rtnl_unregister_all()` on
  netlink registration failure.
- **Severity: MEDIUM**  not a hot-path crash, but real correctness bug
  with leak potential; module reports success when broken.

**Step 8.4  Risk vs benefit**

Record:
- **Benefit:** MEDIUM for Phonet users; prevents silently broken module
  load and improves failure-path correctness
- **Risk:** VERY LOW  ~25 lines, mirrors already-accepted mctp/isotp
  backports in this tree
- **Ratio:** Favorable

---

## Phase 9: Final Synthesis

**Evidence FOR backport:**
- Real init error-handling bug with partial-init-success path
- Missing notifier can skip unregister cleanup (`phonet_device_destroy`,
  `phonet_route_autodel`)
- Small, obviously correct, netdev-maintainer-reviewed
- Same author, same bug class, already backported here for MCTP and CAN
  isotp
- Phonet subsystem receives other stable fixes in this tree
- Applies cleanly to 6.18.44

**Evidence AGAINST:**
- Niche subsystem, few users
- Only triggers on init failure under resource pressure
- No syzbot/user reports
- Impact is correctness/leak, not demonstrated crash in production

**Stable rules checklist:**
1. Obviously correct and tested? **PASS** (pattern proven in-tree for
   mctp/isotp)
2. Fixes a real bug? **PASS**
3. Important issue? **PASS** (partial init success + cleanup bugs;
   MEDIUM severity)
4. Small and contained? **PASS**
5. No new features/APIs? **PASS**
6. Can apply to local tree? **PASS**

**Exception category:** None (standard init error-path fix).

---

## What This Fix Does and Why It Matters

`phonet_device_init()` can currently return success when the netdevice
notifier was never registered. Without that notifier, Phonet never
reacts to network device registration/unregistration events 
autoconfiguration is skipped and unregister cleanup
(`phonet_device_destroy`, `phonet_route_autodel`) never runs, leaving
leaked state in a module that appeared to load correctly.

The patch also adds the missing `proc_create_net()` check (consistent
with `phonet_init_net()` elsewhere in the same file) and replaces the
blunt `phonet_device_exit()` call on netlink failure with proper step-
by-step unwind.

For stable 6.18.44 users who enable Phonet, this is a low-risk
correctness fix in the same vein as two commits already accepted into
this tree from the same author.

---

## Verification

- [Phase 1] Parsed commit message from user query; tags listed above
- [Phase 2] Read diff and current `net/phonet/pn_dev.c:351372`;
  confirmed unchecked calls and `phonet_device_exit()` on netlink
  failure
- [Phase 2] Read `phonet_device_notify()` at `pn_dev.c:296309`;
  confirmed unregister cleanup depends on notifier
- [Phase 2] Read `__rtnl_register_many()` at `rtnetlink.c:523526`;
  confirmed partial unwind on failure
- [Phase 3] `git blame -L 351,372 net/phonet/pn_dev.c`  all lines from
  `5d324e5159d9e`
- [Phase 3] `git log --oneline -20 -- net/phonet/pn_dev.c`  2 commits
  visible
- [Phase 3] `git show 391a23c503856`, `git show 50edffd0854fe`  same-
  author notifier fixes already in tree with `Signed-off-by: Sasha
  Levin`
- [Phase 3] `git log --oneline --grep="phonet"`  multiple phonet stable
  backports present; this fix absent
- [Phase 4] UNVERIFIED: lore/patch.msgid.link blocked; `b4 dig` needs
  commit hash not in tree
- [Phase 5] `grep phonet_device_init`  caller `af_phonet.c:501`
- [Phase 5] Read `register_netdevice_notifier()` at `dev.c:19611999`;
  can return error with rollback
- [Phase 6] `git describe HEAD`  `v6.18.44-2-g1b9e1abadee04`; `make
  kernelversion`  `6.18.44`
- [Phase 6] Buggy code confirmed present; fix not yet applied
- [Phase 8] Compared with backported `mctp_device_init()` fix at
  `net/mctp/device.c:536556`

**YES**

 net/phonet/pn_dev.c | 30 ++++++++++++++++++++++++------
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c
index ec9363c337a9f..4bf8f63d45a9a 100644
--- a/net/phonet/pn_dev.c
+++ b/net/phonet/pn_dev.c
@@ -350,16 +350,34 @@ static struct pernet_operations phonet_net_ops = {
 /* Initialize Phonet devices list */
 int __init phonet_device_init(void)
 {
-	int err = register_pernet_subsys(&phonet_net_ops);
+	int err;
+
+	err = register_pernet_subsys(&phonet_net_ops);
 	if (err)
 		return err;
 
-	proc_create_net("pnresource", 0, init_net.proc_net, &pn_res_seq_ops,
-			sizeof(struct seq_net_private));
-	register_netdevice_notifier(&phonet_device_notifier);
+	if (!proc_create_net("pnresource", 0, init_net.proc_net,
+			     &pn_res_seq_ops, sizeof(struct seq_net_private))) {
+		err = -ENOMEM;
+		goto err_pernet;
+	}
+
+	err = register_netdevice_notifier(&phonet_device_notifier);
+	if (err)
+		goto err_proc;
+
 	err = phonet_netlink_register();
 	if (err)
-		phonet_device_exit();
+		goto err_notifier;
+
+	return 0;
+
+err_notifier:
+	unregister_netdevice_notifier(&phonet_device_notifier);
+err_proc:
+	remove_proc_entry("pnresource", init_net.proc_net);
+err_pernet:
+	unregister_pernet_subsys(&phonet_net_ops);
 	return err;
 }
 
@@ -367,8 +385,8 @@ void phonet_device_exit(void)
 {
 	rtnl_unregister_all(PF_PHONET);
 	unregister_netdevice_notifier(&phonet_device_notifier);
-	unregister_pernet_subsys(&phonet_net_ops);
 	remove_proc_entry("pnresource", init_net.proc_net);
+	unregister_pernet_subsys(&phonet_net_ops);
 }
 
 int phonet_route_add(struct net_device *dev, u8 daddr)
-- 
2.53.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help