Skip to content

fix: make kstorage write_kstorage find+replace atomic - #293

Open
AYwlilwYA wants to merge 1 commit into
bmax121:mainfrom
AYwlilwYA:fix-kstorage-race
Open

fix: make kstorage write_kstorage find+replace atomic#293
AYwlilwYA wants to merge 1 commit into
bmax121:mainfrom
AYwlilwYA:fix-kstorage-race

Conversation

@AYwlilwYA

Copy link
Copy Markdown

Problem

write_kstorage() had a race between finding an existing entry and replacing
it:

rcu_read_lock();
hlist_for_each_entry_rcu(pos, bucket, hnode) {  // lookup OUTSIDE the lock
    if (pos->did == did) { old = pos; break; }
}
spin_lock(lock);
if (old) {
    hlist_replace_rcu(&old->hnode, &new->hnode);  // replace INSIDE the lock
}

Two writers racing on the same did could both find the same old node.
The first thread replaces it (old->pprev becomes LIST_POISON2); the second
thread then calls hlist_replace_rcu() on the already-replaced node and
WRITE_ONCE(*old->pprev, new) writes through the poisoned pointer
(dead000000000122), causing a kernel Oops.

Observed in the field: apd (APatch daemon) crashed with
Unable to handle kernel paging request at virtual address dead000000000122
(LIST_POISON2) during APatch re-authorization after a system_server soft
restart, exactly at hlist_replace_rcu()'s old->pprev = LIST_POISON2.

Fix

Move the lookup inside the group spinlock so find + replace/add are atomic
under the same lock. remove_kstorage() already does its find+del under the
lock and is unaffected.

Verified: kstorage.c compiles cleanly (aarch64, no new warnings).

write_kstorage() looked up the existing node under rcu_read_lock() but
replaced it under the group spinlock. Two writers racing on the same did
could both find the same old node; the second hlist_replace_rcu() on an
already-replaced node wrote through its poisoned ->pprev (LIST_POISON2),
causing a kernel Oops (observed in apd during APatch re-authorization
after a system_server soft restart).

Move the lookup inside the spinlock so find+replace/add are atomic.
@Admirepowered

Copy link
Copy Markdown
Collaborator

kstorage在什么情况下会导致这样的情况,自旋锁会导致大量写入被拦截排队。正常使用不会触发到

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants