lkml.org 
[lkml]   [2012]   [Feb]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH 04/91] agp: fix arbitrary kernel memory writes
    2.6.27-longterm review patch.  If anyone has any objections, please let us know.

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

    commit 194b3da873fd334ef183806db751473512af29ce upstream.

    pg_start is copied from userspace on AGPIOC_BIND and AGPIOC_UNBIND ioctl
    cmds of agp_ioctl() and passed to agpioc_bind_wrap(). As said in the
    comment, (pg_start + mem->page_count) may wrap in case of AGPIOC_BIND,
    and it is not checked at all in case of AGPIOC_UNBIND. As a result, user
    with sufficient privileges (usually "video" group) may generate either
    local DoS or privilege escalation.

    Signed-off-by: Vasiliy Kulikov <segoon@openwall.com>
    Signed-off-by: Dave Airlie <airlied@redhat.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
    ---
    drivers/char/agp/generic.c | 11 ++++++++---
    1 files changed, 8 insertions(+), 3 deletions(-)

    Index: longterm-2.6.27/drivers/char/agp/generic.c
    ===================================================================
    --- longterm-2.6.27.orig/drivers/char/agp/generic.c 2012-02-05 22:34:34.961915038 +0100
    +++ longterm-2.6.27/drivers/char/agp/generic.c 2012-02-05 22:34:35.500916106 +0100
    @@ -1099,8 +1099,8 @@
    return -EINVAL;
    }

    - /* AK: could wrap */
    - if ((pg_start + mem->page_count) > num_entries)
    + if (((pg_start + mem->page_count) > num_entries) ||
    + ((pg_start + mem->page_count) < pg_start))
    return -EINVAL;

    j = pg_start;
    @@ -1132,7 +1132,7 @@
    {
    size_t i;
    struct agp_bridge_data *bridge;
    - int mask_type;
    + int mask_type, num_entries;

    bridge = mem->bridge;
    if (!bridge)
    @@ -1144,6 +1144,11 @@
    if (type != mem->type)
    return -EINVAL;

    + num_entries = agp_num_entries();
    + if (((pg_start + mem->page_count) > num_entries) ||
    + ((pg_start + mem->page_count) < pg_start))
    + return -EINVAL;
    +
    mask_type = bridge->driver->agp_type_to_mask_type(bridge, type);
    if (mask_type != 0) {
    /* The generic routines know nothing of memory types */



    \
     
     \ /
      Last update: 2012-02-05 23:49    [W:0.020 / U:0.484 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site