Re: [PATCH v13 01/11] can: bcm: defer rx_op deallocation to workqueue to fix thrtimer UAF

Oliver Hartkopp <[email protected]>
Newsgroups org.kernel.vger.linux-can,dev.linux.lists.sashiko-reviews
Message-ID <[email protected]>

On 14.07.26 12:39, [email protected] wrote:
> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> 
> New issues:
> - [High] Module exit sequence destroys the socket slab cache before flushing the deferred workqueue, causing a kernel warning and slab cache leak.
> 

Fixed later in patch 5.

> Pre-existing issues:
> - [High] Missing RCU-safe list primitives for rx_ops and tx_ops list modifications and traversals, causing potential crashes during procfs reads.
> --
> 
> --- Patch [1]: [PATCH v13 01/11] can: bcm: defer rx_op deallocation to workqueue to fix thrtimer UAF ---
> commit 9beb61cd8491cca022797eead8556214843e4d99
> Author: Lee Jones <[email protected]>
> 
> can: bcm: defer rx_op deallocation to workqueue to fix thrtimer UAF
> 
> This commit fixes a use-after-free by deferring the deallocation of
> bcm_op to a dedicated workqueue instead of using call_rcu(). It ensures
> that hrtimer cancellation and memory freeing occur in a sleepable context.
> It also takes a reference on the socket while the work is pending to
> prevent the socket from being freed prematurely.
> 
>> diff --git a/net/can/bcm.c b/net/can/bcm.c
>> index a4bef2c48a559..bdf53241bd7b3 100644
>> --- a/net/can/bcm.c
>> +++ b/net/can/bcm.c
> 
> [ ... ]
> 
>> @@ -1060,6 +1081,7 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
>>   
>>   		/* bcm_can_tx / bcm_tx_timeout_handler needs this */
>>   		op->sk = sk;
>> +		sock_hold(sk);
>>   		op->ifindex = ifindex;
>>   
>>   		/* initialize uninitialized (kzalloc) structure */
> 
> [Severity: High]
> This is a pre-existing issue, but can traversing the RCU-protected tx_ops
> and rx_ops lists without RCU-safe primitives cause crashes during procfs
> reads?
> 
> Looking at bcm_tx_setup() and bcm_rx_setup(), list_add() is used instead
> of list_add_rcu(), which lacks the smp_store_release() memory barriers:
> 
> bcm_tx_setup() {
>      ...
>      /* add this bcm_op to the list of the tx_ops */
>      list_add(&op->list, &bo->tx_ops);
>      ...
> }
> 
> Concurrently, if another thread reads /proc/net/can-bcm, bcm_proc_show()
> traverses bo->tx_ops locklessly under rcu_read_lock() using the non-RCU
> list_for_each_entry():
> 
> bcm_proc_show() {
>      ...
>      list_for_each_entry(op, &bo->tx_ops, list) {
>      ...
> }
> 
> Can weakly ordered CPUs reorder the initialization of the bcm_op structure
> after its insertion, allowing lockless RCU readers to observe uninitialized
> memory and crash?
> 
> [ ... ]
> 
>> @@ -1869,6 +1898,8 @@ static void __exit bcm_module_exit(void)
>>   	can_proto_unregister(&bcm_can_proto);
>>   	unregister_netdevice_notifier(&canbcm_notifier);
>>   	unregister_pernet_subsys(&canbcm_pernet_ops);
>> +	rcu_barrier();
>> +	destroy_workqueue(bcm_wq);
>>   }
> 
> [Severity: High]
> Does this module exit sequence destroy the socket slab cache before flushing
> the deferred workqueue?
> 
> Looking at bcm_free_op_work(), the deferred work item drops the final socket
> reference:
> 
> bcm_free_op_work() {
>      ...
>      sock_put(op->sk);
>      kfree(op);
> }
> 
> If there are pending work items in bcm_wq during module unload,
> can_proto_unregister() will call kmem_cache_destroy() on the protocol's
> slab cache while sockets are still allocated.
> 
> Will this cause a kernel warning and a slab cache leak, since
> destroy_workqueue() runs after can_proto_unregister() and will attempt to
> free sockets into the destroyed slab?
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.