Linux 2.2.12 mini-audit

From: Solar Designer (solarat_private)
Date: Mon Sep 13 1999 - 01:10:38 PDT

  • Next message: Ivo van der Wijk: "Re: CGI security"

    Hello,
    
    This post serves three purposes: (1) let people know that they could
    want to upgrade to 2.2.13 when it comes out, for security reasons;
    (2) announce the new location for downloading my patches, as well as
    the fact that they're now available for Linux 2.2; and (3) distribute
    the fingerprint of the PGP key I'll be using to sign future versions
    of the patches.
    
    I've finally ported (actually, mostly re-coded) my patch to Linux
    2.2, which has obviously resulted in some form of an audit of the
    relevant parts of the kernel.  Many of the issues have already been
    discussed on the security-audit list, and some are even fixed in
    2.2.13 pre-patches.  Of course, my patches for both 2.2 and 2.0 (as
    some of the issues turned out to affect 2.0 as well) have either
    fixes or workarounds (to be improved in the future) for all of the
    issues I'll be talking about, below. ;-)  Note that the issues are
    relatively minor, no instant root or such, but are still bad enough
    to be worth fixing.
    
    As this post is going to be fairly long, let me start by providing
    the new URL and the key fingerprint.  The new download location for
    future versions of my patches, is:
    
    	http://www.openwall.com/linux/
    
    The patches also no longer call themselves "Secure Linux", to stop
    giving a false sense of security (I've spent quite a while to make
    sure the documentation doesn't, either, as those things appear to be
    quite important), and to avoid confusion with the Linux distribution
    being developed under the same codename.  On the new site, you will
    also find a link to the PGP key:
    
    Type Bits/KeyID    Date       User ID
    pub  1024/295029F1 1999/09/13 Openwall Project <signaturesat_private>
                Key fingerprint = 0C 29 43 AE 1E CD 24 EA  6E 0C B6 EE F5 84 25 69
    
    (Some people were concerned about the site getting moved without a
    prior announcement, and thus suspected a break-in.  In reality, one
    of the reasons for the move was exactly to ensure better security, as
    I have physical access to this new place.  As no site is perfectly
    secure, I also took this opportunity to start signing the patches,
    and will do the same for other stuff I'm distributing, soon.  This is
    something that I should have done quite a bit earlier, but I'm lazy,
    and, fortunately, nothing bad has happened, anyway.)
    
    Well, done with that, now we can get to the security issues.  To save
    space, I'll put either (2.0.38) or (2.2.12), or both, before every
    description, to indicate which kernel versions it applies to.  Also,
    a (*) will mean that 2.2.13pre7 contains a fix, and a (+) will mean
    that this hasn't been on security-audit, to let those on both lists
    look through this post a bit faster. ;-)
    
    (2.2.12) (*)
    Tymm Twillman has reported a problem with execve(2) halting the
    system when passed some illegal addresses.  After some testing, the
    problem turned out to be a missing error check on the return from
    strlen_user(), which was used on user-supplied arguments, and thus
    could indicate a fault; execve(2), in turn, should have converted
    that into a EFAULT.
    
    (2.0.38) (2.2.12) (*)
    While investigating the problem mentioned above, as well as porting
    Pavel Kankovsky's fd 0-2 fix to Linux 2.2, I've noticed yet another
    problem with execve(2), which has a similar impact.  The problem is
    that all arguments are first counted, and their lengths measured, and
    only after that the results are checked against the limit (32 pages,
    or 128 KB on x86).  Thus, it is possible to make execve(2) spend a
    significant amount of CPU cycles in the kernel, with the big kernel
    lock obtained.  In terms of real time, I was able to get 25 minutes
    for one execve(2) call on Alpha (the 64-bit address space helps), and
    several seconds on modern x86 boxes.  The latter can still be halted
    to death by repeating the call in a loop, and in a few processes.
    
    Fixing this required a trivial modification to the argument counting
    function, and a switch to strnlen_user() for the strings (on 2.2).
    The latter is an architecture-specific assembly function.  My patch
    only fixes it on x86 and Alpha, and 2.2.13 will do that for some more
    architectures (but maybe not all supported by Linux 2.2, yet).  Linux
    2.0 didn't have a strlen_user(), and thus used a simple loop in this
    place, which had the same vulnerability (but not in my 2.0.38 patch,
    of course).
    
    Note that RLIMIT_AS can be used as a workaround for this problem, and
    you should probably be using it for other reasons, anyway.
    
    (2.0.38) (+)
    There was an intentional lack of fault checking when accessing the
    arguments, as indicated by a comment in the code.  This allowed a
    user to generate kernel-mode faults inside execve(2), after some
    kernel resources have been allocated (and would never be freed).
    Simply fixing the problem mentioned above seemed uninteresting, so
    I've re-written the argument counting code to do all the necessary
    checking, and to share the same checks with measuring the lengths of
    individual arguments.  I've even managed to make it have the same
    performance that it used to; the new count() function looks a bit
    like a puzzle because of that, though.  Actually, this is something
    that should have been done earlier; now it can only remain in my
    2.0.38 patch.
    
    (2.0.38) (2.2.12) (*)
    /proc/<pid> directories, and /proc/<pid>/fd symlinks could also be
    accessed with any amount of zeroes prepended to their names.  This
    could be used, say, to obtain an overly long cwd.  There's no obvious
    security impact, but something to be fixed anyway (and that has been
    done).
    
    (2.0.38) (2.2.12) (*)
    CLONE_PID could be set from the user-space, thus producing two user
    processes with the same PID.  Attacks include: stopping SUID programs
    from sending signals to themselves (even raise(3) wouldn't work),
    covering your high resource usage by the other dummy process, making
    unkillable processes that can still be running just fine (covered by
    dummy zombie processes with the same PID).
    
    (2.0.38) (2.2.12)
    It is possible to request any exit_signal, not just SIGCHLD, via
    clone(2).  This is normally not a problem, but there's one exception:
    the parent could have executed a SUID program, and that program could
    have done a "setuid(geteuid())", expecting to protect itself from
    signals sent by the original user.  This feature of clone(2) can be
    used to send an arbitrary signal to such a program.  I've put a
    workaround into my patches, that restricts the allowed signal numbers
    to SIGCHLD, SIGUSR1, SIGUSR2, or no signal, with SIGUSR1 and SIGUSR2
    allowed specifically for LinuxThreads to work.  This also means that
    SUID programs which use LinuxThreads remain unprotected.  A solution
    to this should be developed.  I've proposed one in a comment in the
    patches, and Pavel Kankovsky has offered another one.  Unfortunately,
    both of them have some (different) disadvantages.  This problem isn't
    fixed in 2.2.13pre7, and isn't likely to be any time soon. :-(
    
    (2.2.12) (*)
    We have now reverted to the behavior of chown(2) we had in 2.0: reset
    SUID/SGID bits on ownership change even if done by root.  Until now,
    Linux 2.2 didn't do that for root (and not even for CAP_FSETID, like
    it was supposed to do), which allowed for some races that have been
    discussed on the security-audit list a few months ago.
    
    (2.0.38) (+)
    Linux 2.0's version of process_unauthorized() forgot to check the
    dumpable flag, so it was possible to access memory of a SUID process
    a user has started, via PID re-use.  Linux 2.2 did the right thing,
    and isn't vulnerable.
    
    (2.0.37 with secure-linux-11) (+)
    I don't like it when others fix their vulnerabilities silently, so I
    won't do so myself. :-)  It was possible to bypass some restrictions
    of CONFIG_SECURE_PROC via PID re-use in 2.0.36 and 2.0.37 kernels
    with my patches.  I simply didn't re-check the code closely enough
    when updating the patch for 2.0.36.  Thanks to Pavel Kankovsky for
    noticing this.
    
    (2.0.38) (2.2.12) (+)
    User-space values of the instruction and stack pointers are available
    via /proc, -- for every process in the system, and to everyone.  This
    information should in fact be treated just as private as the address
    space of the processes (such a patch will likely get into 2.2.13pre
    soon).  Imagine a crypto algorithm implementation that does branches
    based on its key bits.  Thanks to Thomas <thomasat_private>, who has
    reported this to me (but underestimated the impact).
    
    One final note: I am still going to fix all 2.0.38 security issues
    that are any serious, in my patches, for a few months more.
    
    Signed,
    Solar Designer
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 15:03:19 PDT