lkml.org 
[lkml]   [2016]   [Mar]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.12 103/116] rfkill: fix rfkill_fop_read wait_event usage
    Date
    From: Johannes Berg <johannes.berg@intel.com>

    3.12-stable review patch. If anyone has any objections, please let me know.

    ===============

    commit 6736fde9672ff6717ac576e9bba2fd5f3dfec822 upstream.

    The code within wait_event_interruptible() is called with
    !TASK_RUNNING, so mustn't call any functions that can sleep,
    like mutex_lock().

    Since we re-check the list_empty() in a loop after the wait,
    it's safe to simply use list_empty() without locking.

    This bug has existed forever, but was only discovered now
    because all userspace implementations, including the default
    'rfkill' tool, use poll() or select() to get a readable fd
    before attempting to read.

    Fixes: c64fb01627e24 ("rfkill: create useful userspace interface")
    Reported-by: Dmitry Vyukov <dvyukov@google.com>
    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
    Signed-off-by: Jiri Slaby <jslaby@suse.cz>
    ---
    net/rfkill/core.c | 16 ++++------------
    1 file changed, 4 insertions(+), 12 deletions(-)

    diff --git a/net/rfkill/core.c b/net/rfkill/core.c
    index 5a14f55a1926..918c5ebd239e 100644
    --- a/net/rfkill/core.c
    +++ b/net/rfkill/core.c
    @@ -1080,17 +1080,6 @@ static unsigned int rfkill_fop_poll(struct file *file, poll_table *wait)
    return res;
    }

    -static bool rfkill_readable(struct rfkill_data *data)
    -{
    - bool r;
    -
    - mutex_lock(&data->mtx);
    - r = !list_empty(&data->events);
    - mutex_unlock(&data->mtx);
    -
    - return r;
    -}
    -
    static ssize_t rfkill_fop_read(struct file *file, char __user *buf,
    size_t count, loff_t *pos)
    {
    @@ -1107,8 +1096,11 @@ static ssize_t rfkill_fop_read(struct file *file, char __user *buf,
    goto out;
    }
    mutex_unlock(&data->mtx);
    + /* since we re-check and it just compares pointers,
    + * using !list_empty() without locking isn't a problem
    + */
    ret = wait_event_interruptible(data->read_wait,
    - rfkill_readable(data));
    + !list_empty(&data->events));
    mutex_lock(&data->mtx);

    if (ret)
    --
    2.7.2
    \
     
     \ /
      Last update: 2016-03-04 11:01    [W:4.073 / U:0.452 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site