From 7ca42d1e55bad48fed4cd0588ceef51bf4265ba7 Mon Sep 17 00:00:00 2001 From: Sameeh Jubran Date: Fri, 24 Apr 2026 15:00:32 +0300 Subject: [PATCH 1/3] bsdkm: return 0 from wolfkdriv_process() to comply with opencrypto(9) cryptodev_process must return 0 once crypto_done() has fired; errors are reported via crp_etype, otherwise the framework may re-dispatch an already-completed request. Signed-off-by: Sameeh Jubran --- bsdkm/wolfkmod.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bsdkm/wolfkmod.c b/bsdkm/wolfkmod.c index 57d982cda9e..84e8a014909 100644 --- a/bsdkm/wolfkmod.c +++ b/bsdkm/wolfkmod.c @@ -1020,7 +1020,8 @@ static int wolfkdriv_process(device_t dev, struct cryptop * crp, int hint) csp->csp_mode, csp->csp_cipher_alg, error); #endif /* WOLFSSL_BSDKM_VERBOSE_DEBUG */ - return (error); + /* opencrypto(9) contract: return 0 after crypto_done(); error is in crp_etype. */ + return (0); } /* From 2f660a3f7b88885d06519677e72e62bf1999bb4c Mon Sep 17 00:00:00 2001 From: Sameeh Jubran Date: Mon, 27 Apr 2026 11:15:23 +0300 Subject: [PATCH 2/3] linuxkm/linuxkm_wc_port.h: in my_memmove(), early-return when n == 0 to avoid size_t underflow The backward-copy branches compute (n - 1) as size_t, which wraps to SIZE_MAX for n == 0 and, with src below dest, drives the loop backward through kernel memory until it oopses; matches glibc / musl / kernel memmove(). Signed-off-by: Sameeh Jubran --- linuxkm/linuxkm_wc_port.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/linuxkm/linuxkm_wc_port.h b/linuxkm/linuxkm_wc_port.h index 22255af4560..50f7a1f050d 100644 --- a/linuxkm/linuxkm_wc_port.h +++ b/linuxkm/linuxkm_wc_port.h @@ -450,6 +450,8 @@ #define memset my_memset static inline void *my_memmove(void *dest, const void *src, size_t n) { + if (n == 0) + return dest; if (! (((uintptr_t)dest | (uintptr_t)src | (uintptr_t)n) & (uintptr_t)(sizeof(uintptr_t) - 1))) { From 75dc3e13fd1e903ba302acbe5cc3e1b3db895397 Mon Sep 17 00:00:00 2001 From: Sameeh Jubran Date: Mon, 27 Apr 2026 16:20:13 +0300 Subject: [PATCH 3/3] 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 --- linuxkm/x86_vector_register_glue.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/linuxkm/x86_vector_register_glue.c b/linuxkm/x86_vector_register_glue.c index 6879546337c..90ae0efcc15 100644 --- a/linuxkm/x86_vector_register_glue.c +++ b/linuxkm/x86_vector_register_glue.c @@ -162,16 +162,22 @@ static struct wc_thread_fpu_count_ent *wc_linuxkm_fpu_state_assoc_unlikely(int c __atomic_store_n(&slot->pid, my_pid, __ATOMIC_RELEASE); return slot; } else { + struct pid *slot_pid_struct; + /* if the slot is already occupied, that can be benign-ish due to a * unwanted migration, or due to a process crashing in kernel mode. * it will require fixup either here, or by the thread that owns the * slot, which will happen when it releases its lock. */ - if (find_get_pid(slot_pid) == NULL) { + slot_pid_struct = find_get_pid(slot_pid); + if (slot_pid_struct == NULL) { if (__atomic_compare_exchange_n(&slot->pid, &slot_pid, my_pid, 0, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE)) { 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); return slot; } + } else { + /* drop the refcount bumped by find_get_pid(). */ + put_pid(slot_pid_struct); } {