Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: psp: check for device unregister when creating assoc

psp_assoc_device_get_locked() obtains a psp_dev reference via
psp_dev_get_for_sock() (which uses psp_dev_tryget() under RCU);
it then acquires psd->lock and drops the reference. Before
the lock is taken, psp_dev_unregister() can run to completion:
take psd->lock, clear out state, unlock, drop the registration
reference.

The expectation is that the lock prevents device unregistration,
but much like with netdevs special care has to be taken when
"upgrading" a reference to a locked device. Add the missing
check if device is still alive. psp_dev_is_registered() exists
already but had no callers, which makes me wonder if I either
forgot to add this or lost the check during refactoring...

Reported-by: Yiming Qian <yimingqian591@gmail.com>
Fixes: 6b46ca260e22 ("net: psp: add socket security association code")
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260427190606.366101-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+7 -3
+7 -3
net/psp/psp_nl.c
··· 305 305 306 306 psd = psp_dev_get_for_sock(socket->sk); 307 307 if (psd) { 308 - err = psp_dev_check_access(psd, genl_info_net(info)); 309 - if (err) { 308 + /* Extra care needed here, psp_dev_get_for_sock() only gives 309 + * us access to struct psp_dev's memory, which is quite weak. 310 + */ 311 + mutex_lock(&psd->lock); 312 + if (!psp_dev_is_registered(psd) || 313 + psp_dev_check_access(psd, genl_info_net(info))) { 314 + mutex_unlock(&psd->lock); 310 315 psp_dev_put(psd); 311 316 psd = NULL; 312 317 } ··· 324 319 325 320 id = info->attrs[PSP_A_ASSOC_DEV_ID]; 326 321 if (psd) { 327 - mutex_lock(&psd->lock); 328 322 if (id && psd->id != nla_get_u32(id)) { 329 323 mutex_unlock(&psd->lock); 330 324 NL_SET_ERR_MSG_ATTR(info->extack, id,