lkml.org 
[lkml]   [2000]   [Nov]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    SubjectLocal root exploit with kmod and modutils > 2.1.121
    Date
    On Mon, 13 Nov 2000 20:23:07 +0000 (GMT), 
    Chris Evans <chris@scary.beasts.org> wrote:
    >Either the kernel or modprobe needs to treat the module name with
    >_extreme_ distrust, and I see no evidence of that.

    Agreed. modprobe was not designed to run suid. Calling modprobe from
    request_module has the same effect as running suid. dev_load() can
    take the interface name and pass it to modprobe unchanged and modprobe
    does not verify its input, it trusts root/kernel.

    >Without this distrust, there is a huge amount of code a malicious user can
    >play with. Looking at meta_expand() and split_line() in modprobe, there
    >are buffer overflows all over the place (lucky an interface name can only
    >be 15 characters!). Worse, user-defined input can be passed to sprawling
    >interfaces such as glob() and wordexp().

    The buffer overflows are not as bad as they look, most of them are on
    malloc strings which have calculated sizes. There are some strcat
    calls that are suspect and I have fixed those in my tree, and replaced
    the system() calls with safe equivalents. But that does not fix the
    other problems.

    (1) Some user defined input is passed directly through the kernel to
    modprobe running as root.

    (2) Current modprobe has no way of telling that it was invoked from the
    kernel instead of by root so it cannot apply different verification
    to its parameters for kmod input.

    (3) modprobe applies filename expansion to the user supplied input as
    well as the paths from modules.conf. The former is tainted, the
    latter is not but they are joined together in modprobe. This is
    fine for root, terrible for kmod.

    The only secure fix I can see is to add SAFEMODE=1 to modprobe's
    environment and change exec_modprobe.

    static char * envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", "SAFEMODE=1", NULL };

    In safemode, modprobe will treat its last argument as a module name,
    even if it starts with '-'. Also in safemode, no filename expansion
    will be applied to the module name, filename expansion will still be
    applied to paths in /etc/modules.conf.

    To cater for older kernels (including 2.2), modprobe will treat an
    environment of exactly this, and no more
    "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin"
    as requiring safemode. Why add SAFEMODE at all? In case we want to
    change the environment in future.

    Chris Evans raised another point.

    (4) Passing user defined input directly through the kernel to modprobe
    does more than expose modprobe to suspect input. If a user can
    find a program that the kernel trusts and whose input is passed
    straight through then they can load any module. Controlled loading
    with kernel generated names like net-pf-10, eth0 is fine,
    uncontrolled loading of any module name from user input is not.
    This is a pure kernel problem.

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 12:45    [W:0.023 / U:0.816 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site