lkml.org 
[lkml]   [2017]   [Feb]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 3.16 295/306] fbdev: color map copying bounds checking
    3.16.40-rc1 review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Kees Cook <keescook@chromium.org>

    commit 2dc705a9930b4806250fbf5a76e55266e59389f2 upstream.

    Copying color maps to userspace doesn't check the value of to->start,
    which will cause kernel heap buffer OOB read due to signedness wraps.

    CVE-2016-8405

    Link: http://lkml.kernel.org/r/20170105224249.GA50925@beast
    Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
    Signed-off-by: Kees Cook <keescook@chromium.org>
    Reported-by: Peter Pi (@heisecode) of Trend Micro
    Cc: Min Chong <mchong@google.com>
    Cc: Dan Carpenter <dan.carpenter@oracle.com>
    Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
    Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    drivers/video/fbdev/core/fbcmap.c | 26 ++++++++++++++------------
    1 file changed, 14 insertions(+), 12 deletions(-)

    diff --git a/drivers/video/fbdev/core/fbcmap.c b/drivers/video/fbdev/core/fbcmap.c
    index f89245b8ba8e..68a113594808 100644
    --- a/drivers/video/fbdev/core/fbcmap.c
    +++ b/drivers/video/fbdev/core/fbcmap.c
    @@ -163,17 +163,18 @@ void fb_dealloc_cmap(struct fb_cmap *cmap)

    int fb_copy_cmap(const struct fb_cmap *from, struct fb_cmap *to)
    {
    - int tooff = 0, fromoff = 0;
    - int size;
    + unsigned int tooff = 0, fromoff = 0;
    + size_t size;

    if (to->start > from->start)
    fromoff = to->start - from->start;
    else
    tooff = from->start - to->start;
    - size = to->len - tooff;
    - if (size > (int) (from->len - fromoff))
    - size = from->len - fromoff;
    - if (size <= 0)
    + if (fromoff >= from->len || tooff >= to->len)
    + return -EINVAL;
    +
    + size = min_t(size_t, to->len - tooff, from->len - fromoff);
    + if (size == 0)
    return -EINVAL;
    size *= sizeof(u16);

    @@ -187,17 +188,18 @@ int fb_copy_cmap(const struct fb_cmap *from, struct fb_cmap *to)

    int fb_cmap_to_user(const struct fb_cmap *from, struct fb_cmap_user *to)
    {
    - int tooff = 0, fromoff = 0;
    - int size;
    + unsigned int tooff = 0, fromoff = 0;
    + size_t size;

    if (to->start > from->start)
    fromoff = to->start - from->start;
    else
    tooff = from->start - to->start;
    - size = to->len - tooff;
    - if (size > (int) (from->len - fromoff))
    - size = from->len - fromoff;
    - if (size <= 0)
    + if (fromoff >= from->len || tooff >= to->len)
    + return -EINVAL;
    +
    + size = min_t(size_t, to->len - tooff, from->len - fromoff);
    + if (size == 0)
    return -EINVAL;
    size *= sizeof(u16);

    \
     
     \ /
      Last update: 2017-02-16 01:17    [W:4.621 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site