lkml.org 
[lkml]   [2021]   [Mar]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH] PCI: hotplug: fix null-ptr-dereferencd in cpcihp error path
    Date
    There is an issue in the error path, which cpci_thread may remain NULL.
    Calling kthread_stop(cpci_thread) will trigger a BUG().
    It is better to check whether the thread is really created and started
    before stop it.

    [ 1.292859] BUG: kernel NULL pointer dereference, address: 0000000000000028
    [ 1.293252] #PF: supervisor write access in kernel mode
    [ 1.293533] #PF: error_code(0x0002) - not-present page
    [ 1.295163] RIP: 0010:kthread_stop+0x22/0x170
    [ 1.300491] Call Trace:
    [ 1.300628] cpci_hp_unregister_controller+0xf6/0x130
    [ 1.300906] zt5550_hc_init_one+0x27a/0x27f [cpcihp_zt5550]

    Signed-off-by: Tong Zhang <ztong0001@gmail.com>
    ---
    drivers/pci/hotplug/cpci_hotplug_core.c | 12 ++++++------
    1 file changed, 6 insertions(+), 6 deletions(-)

    diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c
    index d0559d2faf50..b44da397d631 100644
    --- a/drivers/pci/hotplug/cpci_hotplug_core.c
    +++ b/drivers/pci/hotplug/cpci_hotplug_core.c
    @@ -47,7 +47,7 @@ static atomic_t extracting;
    int cpci_debug;
    static struct cpci_hp_controller *controller;
    static struct task_struct *cpci_thread;
    -static int thread_finished;
    +static int thread_started;

    static int enable_slot(struct hotplug_slot *slot);
    static int disable_slot(struct hotplug_slot *slot);
    @@ -447,7 +447,7 @@ event_thread(void *data)
    msleep(500);
    } else if (rc < 0) {
    dbg("%s - error checking slots", __func__);
    - thread_finished = 1;
    + thread_started = 0;
    goto out;
    }
    } while (atomic_read(&extracting) && !kthread_should_stop());
    @@ -479,7 +479,7 @@ poll_thread(void *data)
    msleep(500);
    } else if (rc < 0) {
    dbg("%s - error checking slots", __func__);
    - thread_finished = 1;
    + thread_started = 0;
    goto out;
    }
    } while (atomic_read(&extracting) && !kthread_should_stop());
    @@ -501,7 +501,7 @@ cpci_start_thread(void)
    err("Can't start up our thread");
    return PTR_ERR(cpci_thread);
    }
    - thread_finished = 0;
    + thread_started = 1;
    return 0;
    }

    @@ -509,7 +509,7 @@ static void
    cpci_stop_thread(void)
    {
    kthread_stop(cpci_thread);
    - thread_finished = 1;
    + thread_started = 0;
    }

    int
    @@ -571,7 +571,7 @@ cpci_hp_unregister_controller(struct cpci_hp_controller *old_controller)
    int status = 0;

    if (controller) {
    - if (!thread_finished)
    + if (thread_started)
    cpci_stop_thread();
    if (controller->irq)
    free_irq(controller->irq, controller->dev_id);
    --
    2.25.1
    \
     
     \ /
      Last update: 2021-03-21 06:52    [W:2.227 / U:0.880 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site