Patch "netlink: fix potential sleeping issue in mqueue_flush_file" has been added to the 6.1-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    netlink: fix potential sleeping issue in mqueue_flush_file

to the 6.1-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     netlink-fix-potential-sleeping-issue-in-mqueue_flush.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit a9a8bc6ad086571b4d696bda2b83a19163225bf1
Author: Zhengchao Shao <shaozhengchao@xxxxxxxxxx>
Date:   Mon Jan 22 09:18:07 2024 +0800

    netlink: fix potential sleeping issue in mqueue_flush_file
    
    [ Upstream commit 234ec0b6034b16869d45128b8cd2dc6ffe596f04 ]
    
    I analyze the potential sleeping issue of the following processes:
    Thread A                                Thread B
    ...                                     netlink_create  //ref = 1
    do_mq_notify                            ...
      sock = netlink_getsockbyfilp          ...     //ref = 2
      info->notify_sock = sock;             ...
    ...                                     netlink_sendmsg
    ...                                       skb = netlink_alloc_large_skb  //skb->head is vmalloced
    ...                                       netlink_unicast
    ...                                         sk = netlink_getsockbyportid //ref = 3
    ...                                         netlink_sendskb
    ...                                           __netlink_sendskb
    ...                                             skb_queue_tail //put skb to sk_receive_queue
    ...                                         sock_put //ref = 2
    ...                                     ...
    ...                                     netlink_release
    ...                                       deferred_put_nlk_sk //ref = 1
    mqueue_flush_file
      spin_lock
      remove_notification
        netlink_sendskb
          sock_put  //ref = 0
            sk_free
              ...
              __sk_destruct
                netlink_sock_destruct
                  skb_queue_purge  //get skb from sk_receive_queue
                    ...
                    __skb_queue_purge_reason
                      kfree_skb_reason
                        __kfree_skb
                        ...
                        skb_release_all
                          skb_release_head_state
                            netlink_skb_destructor
                              vfree(skb->head)  //sleeping while holding spinlock
    
    In netlink_sendmsg, if the memory pointed to by skb->head is allocated by
    vmalloc, and is put to sk_receive_queue queue, also the skb is not freed.
    When the mqueue executes flush, the sleeping bug will occur. Use
    vfree_atomic instead of vfree in netlink_skb_destructor to solve the issue.
    
    Fixes: c05cdb1b864f ("netlink: allow large data transfers from user-space")
    Signed-off-by: Zhengchao Shao <shaozhengchao@xxxxxxxxxx>
    Link: https://lore.kernel.org/r/20240122011807.2110357-1-shaozhengchao@xxxxxxxxxx
    Signed-off-by: Paolo Abeni <pabeni@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index cb833302270a..6857a4965fe8 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -374,7 +374,7 @@ static void netlink_skb_destructor(struct sk_buff *skb)
 	if (is_vmalloc_addr(skb->head)) {
 		if (!skb->cloned ||
 		    !atomic_dec_return(&(skb_shinfo(skb)->dataref)))
-			vfree(skb->head);
+			vfree_atomic(skb->head);
 
 		skb->head = NULL;
 	}




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux