lkml.org 
[lkml]   [2022]   [May]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.10 33/70] NFC: netlink: fix sleep in atomic bug when firmware download timeout
    Date
    From: Duoming Zhou <duoming@zju.edu.cn>

    commit 4071bf121d59944d5cd2238de0642f3d7995a997 upstream.

    There are sleep in atomic bug that could cause kernel panic during
    firmware download process. The root cause is that nlmsg_new with
    GFP_KERNEL parameter is called in fw_dnld_timeout which is a timer
    handler. The call trace is shown below:

    BUG: sleeping function called from invalid context at include/linux/sched/mm.h:265
    Call Trace:
    kmem_cache_alloc_node
    __alloc_skb
    nfc_genl_fw_download_done
    call_timer_fn
    __run_timers.part.0
    run_timer_softirq
    __do_softirq
    ...

    The nlmsg_new with GFP_KERNEL parameter may sleep during memory
    allocation process, and the timer handler is run as the result of
    a "software interrupt" that should not call any other function
    that could sleep.

    This patch changes allocation mode of netlink message from GFP_KERNEL
    to GFP_ATOMIC in order to prevent sleep in atomic bug. The GFP_ATOMIC
    flag makes memory allocation operation could be used in atomic context.

    Fixes: 9674da8759df ("NFC: Add firmware upload netlink command")
    Fixes: 9ea7187c53f6 ("NFC: netlink: Rename CMD_FW_UPLOAD to CMD_FW_DOWNLOAD")
    Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
    Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
    Link: https://lore.kernel.org/r/20220504055847.38026-1-duoming@zju.edu.cn
    Signed-off-by: Paolo Abeni <pabeni@redhat.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    net/nfc/netlink.c | 4 ++--
    1 file changed, 2 insertions(+), 2 deletions(-)

    --- a/net/nfc/netlink.c
    +++ b/net/nfc/netlink.c
    @@ -1244,7 +1244,7 @@ int nfc_genl_fw_download_done(struct nfc
    struct sk_buff *msg;
    void *hdr;

    - msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
    + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
    if (!msg)
    return -ENOMEM;

    @@ -1260,7 +1260,7 @@ int nfc_genl_fw_download_done(struct nfc

    genlmsg_end(msg, hdr);

    - genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
    + genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_ATOMIC);

    return 0;


    \
     
     \ /
      Last update: 2022-05-10 16:00    [W:3.217 / U:0.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site