Skip to content

Commit 75dc3e1

Browse files
committed
linuxkm/x86_vector_register_glue.c: fix struct pid refcount leak from find_get_pid() in wc_linuxkm_fpu_state_assoc_unlikely().
find_get_pid() returns a struct pid * with the refcount bumped via get_pid(); callers must release it with put_pid(). The probe here is purely a liveness check on the slot's previous owner, and the returned pointer was discarded -- leaking one struct pid reference every time the unlikely contested-slot path was hit with a still-live owner. Capture the pointer and put_pid() it on the live-owner branch; behavior on the orphaned-slot branch is unchanged. Signed-off-by: Sameeh Jubran <sameeh@wolfssl.com>
1 parent 2f660a3 commit 75dc3e1

1 file changed

Lines changed: 7 additions & 1 deletion

File tree

linuxkm/x86_vector_register_glue.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,16 +162,22 @@ static struct wc_thread_fpu_count_ent *wc_linuxkm_fpu_state_assoc_unlikely(int c
162162
__atomic_store_n(&slot->pid, my_pid, __ATOMIC_RELEASE);
163163
return slot;
164164
} else {
165+
struct pid *slot_pid_struct;
166+
165167
/* if the slot is already occupied, that can be benign-ish due to a
166168
* unwanted migration, or due to a process crashing in kernel mode.
167169
* it will require fixup either here, or by the thread that owns the
168170
* slot, which will happen when it releases its lock.
169171
*/
170-
if (find_get_pid(slot_pid) == NULL) {
172+
slot_pid_struct = find_get_pid(slot_pid);
173+
if (slot_pid_struct == NULL) {
171174
if (__atomic_compare_exchange_n(&slot->pid, &slot_pid, my_pid, 0, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE)) {
172175
pr_warn("WARNING: wc_linuxkm_fpu_state_assoc_unlikely fixed up orphaned slot on CPU %d owned by dead PID %d.\n", my_cpu, slot_pid);
173176
return slot;
174177
}
178+
} else {
179+
/* drop the refcount bumped by find_get_pid(). */
180+
put_pid(slot_pid_struct);
175181
}
176182

177183
{

0 commit comments

Comments
 (0)