Skip to content

Commit fd76e5c

Browse files
quic-clewdavem330
authored andcommitted
net: qrtr: ns: Fix module refcnt
The qrtr protocol core logic and the qrtr nameservice are combined into a single module. Neither the core logic or nameservice provide much functionality by themselves; combining the two into a single module also prevents any possible issues that may stem from client modules loading inbetween qrtr and the ns. Creating a socket takes two references to the module that owns the socket protocol. Since the ns needs to create the control socket, this creates a scenario where there are always two references to the qrtr module. This prevents the execution of 'rmmod' for qrtr. To resolve this, forcefully put the module refcount for the socket opened by the nameservice. Fixes: a365023 ("net: qrtr: combine nameservice into main module") Reported-by: Jeffrey Hugo <[email protected]> Tested-by: Jeffrey Hugo <[email protected]> Signed-off-by: Chris Lew <[email protected]> Reviewed-by: Manivannan Sadhasivam <[email protected]> Reviewed-by: Jeffrey Hugo <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 99975ad commit fd76e5c

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

net/qrtr/ns.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,24 @@ int qrtr_ns_init(void)
725725
if (ret < 0)
726726
goto err_wq;
727727

728+
/* As the qrtr ns socket owner and creator is the same module, we have
729+
* to decrease the qrtr module reference count to guarantee that it
730+
* remains zero after the ns socket is created, otherwise, executing
731+
* "rmmod" command is unable to make the qrtr module deleted after the
732+
* qrtr module is inserted successfully.
733+
*
734+
* However, the reference count is increased twice in
735+
* sock_create_kern(): one is to increase the reference count of owner
736+
* of qrtr socket's proto_ops struct; another is to increment the
737+
* reference count of owner of qrtr proto struct. Therefore, we must
738+
* decrement the module reference count twice to ensure that it keeps
739+
* zero after server's listening socket is created. Of course, we
740+
* must bump the module reference count twice as well before the socket
741+
* is closed.
742+
*/
743+
module_put(qrtr_ns.sock->ops->owner);
744+
module_put(qrtr_ns.sock->sk->sk_prot_creator->owner);
745+
728746
return 0;
729747

730748
err_wq:
@@ -739,6 +757,15 @@ void qrtr_ns_remove(void)
739757
{
740758
cancel_work_sync(&qrtr_ns.work);
741759
destroy_workqueue(qrtr_ns.workqueue);
760+
761+
/* sock_release() expects the two references that were put during
762+
* qrtr_ns_init(). This function is only called during module remove,
763+
* so try_stop_module() has already set the refcnt to 0. Use
764+
* __module_get() instead of try_module_get() to successfully take two
765+
* references.
766+
*/
767+
__module_get(qrtr_ns.sock->ops->owner);
768+
__module_get(qrtr_ns.sock->sk->sk_prot_creator->owner);
742769
sock_release(qrtr_ns.sock);
743770
}
744771
EXPORT_SYMBOL_GPL(qrtr_ns_remove);

0 commit comments

Comments
 (0)