lkml.org 
[lkml]   [2011]   [Apr]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[49/55] agp: fix arbitrary kernel memory writes
    2.6.38-stable review patch.  If anyone has any objections, please let us know.

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

    From: Vasiliy Kulikov <segoon@openwall.com>

    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 file changed, 8 insertions(+), 3 deletions(-)

    --- a/drivers/char/agp/generic.c
    +++ b/drivers/char/agp/generic.c
    @@ -1089,8 +1089,8 @@ int agp_generic_insert_memory(struct agp
    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;
    @@ -1124,7 +1124,7 @@ int agp_generic_remove_memory(struct agp
    {
    size_t i;
    struct agp_bridge_data *bridge;
    - int mask_type;
    + int mask_type, num_entries;

    bridge = mem->bridge;
    if (!bridge)
    @@ -1136,6 +1136,11 @@ int agp_generic_remove_memory(struct agp
    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: 2011-04-29 21:03    [W:0.022 / U:0.044 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site