Originally Published: Tuesday, 14 September 1999 Author: Quentin Cregan
Published to: news_enhance_security/Security News Page: 1/1 - [Printable]

Solar Designer releases his latest patches for the kernel.

In a posting to BugTraq today, Solar Designer announced that his patches are now available for 2.2 signed, and that they may now be found at http://www.openwall.com. They're also no longer called Secure Linux... click "more" for the full post.

   Page 1 of 1  

[from BugTraq]


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:


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 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/ directories, and /proc//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 , 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

   Page 1 of 1