Skip to content

Commit 1d2717a

Browse files
kext: sysfs_iokit: make the snapshot RCU-safe
In sysfs_iokit.c, sysfs_snap_ensure() can race and free a snapshot another thread is still using. Only free the previous g_snapshot after a successful swap. Treat g_snapshot as RCU: readers always hold g_lock while accessing it.
1 parent 61e5650 commit 1d2717a

1 file changed

Lines changed: 11 additions & 3 deletions

File tree

kext/sysfs_iokit.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,9 @@ sysfs_snap_ensure(void)
304304
uint64_t now, elapsed_ns;
305305
clock_get_uptime(&now);
306306

307+
struct sysfs_snapshot *old_snap = nullptr;
308+
struct sysfs_snapshot *new_snap = nullptr;
309+
307310
/* Fast check under lock */
308311
if (g_lock != nullptr) {
309312
IOLockLock(g_lock);
@@ -318,30 +321,35 @@ sysfs_snap_ensure(void)
318321
}
319322

320323
/* Build new snapshot UNLOCKED (heavy IOKit traversal & IOMalloc happen here) */
321-
struct sysfs_snapshot *new_snap = sysfs_snap_build();
324+
new_snap = sysfs_snap_build();
322325
if (new_snap == nullptr) {
323326
return;
324327
}
325328

326329
/* Re-acquire lock to swap pointers safely */
327-
struct sysfs_snapshot *old_snap = nullptr;
328330
if (g_lock != nullptr) {
329331
IOLockLock(g_lock);
330332
if (g_snapshot != nullptr) {
331333
absolutetime_to_nanoseconds(now - g_snapshot->uptime, &elapsed_ns);
332334
if (elapsed_ns <= SYSFS_SNAP_TTL_NS) {
333-
/* Another thread refreshed it while unlocked; throw away our snapshot */
335+
/* Another thread refreshed it while unlocked */
336+
/* Throw away our snapshot, keep theirs */
334337
old_snap = new_snap;
338+
new_snap = nullptr;
335339
} else {
336340
old_snap = g_snapshot;
337341
g_snapshot = new_snap;
342+
new_snap = nullptr;
338343
}
339344
} else {
340345
g_snapshot = new_snap;
346+
new_snap = nullptr;
341347
}
342348
IOLockUnlock(g_lock);
343349
} else {
350+
/* No lock: we can’t safely publish, just discard */
344351
old_snap = new_snap;
352+
new_snap = nullptr;
345353
}
346354

347355
/* Free stale snapshot memory OUTSIDE the lock */

0 commit comments

Comments
 (0)