Local root exploit with kmod and modutils > 2.1.121

From: Keith Owens (kaos@ocs.com.au)
Date: Mon Nov 13 2000 - 18:11:42 EST


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/



This archive was generated by hypermail 2b29 : Wed Nov 15 2000 - 21:00:24 EST