Date: Tue, 25 Apr 2000 02:47:50 +0000 From: Crispin Cowan <crispin@wirex.com> To: Solar Designer <solar@false.com> Subject: Re: libsafe This is a multi-part message in MIME format. --------------B71FC48015AD4E363B53AF15 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Solar Designer wrote: > Hi, > > libsafe has recently been mentioned on Bugtraq and on this list. I'm > surprised by the lack of any follow-ups on Bugtraq. Perry Wagle (principle StackGuard developer, cc'd) was working on his analysis of libsafe (attached). Perry's conclusions are similar to yours: * use StackGuard where you can (i.e. source code available) because it is safer * use Libsafe where you can't (i.e. binaries) * NOTIFY_WITH_EMAIL is probably unsafe, as the attacker may be able to trick it into doing something unsafe. StackGuard goes out of its way to ensure that the canary_death_handler is extremely simple so as to prevent the attacker from victimizing it. My further comment on libsafe: the paper that the authors will be presenting at USENIX in June presents two forms of defense ("library intercept" and binary-rewrite (BRW)) and only the library intercept appears to be embodied in the publicly available libsafe, which is why libsafe only protects against overflows that use particular string library functions. The BRW method is a pseudo-compiler that can transform binaries into "safe" programs by transforming the binary. It copies program onto the heap, inserting checks as it goes. The copy-to-the-heap is to make space for the additional checks. I really like the BRW method, and hope it becomes available. If my understanding is mistaken, and BRW is actually in the distributed libsafe, please correct me. Crispin ----- Crispin Cowan, CTO, WireX Communications, Inc. http://wirex.com Free Hardened Linux Distribution: http://immunix.org JOBS! http://immunix.org/jobs.html --------------B71FC48015AD4E363B53AF15 Content-Type: message/rfc822 Content-Transfer-Encoding: 7bit Content-Disposition: inline Return-Path: <wagle@cse.ogi.edu> Delivered-To: crispin@wirex.com Received: from church.cse.ogi.edu (cse.ogi.edu [129.95.20.2]) by mithra.wirex.com (Postfix) with ESMTP id 2C1EB3EC15 for <crispin@wirex.com>; Mon, 24 Apr 2000 18:56:56 -0700 (PDT) Received: (from wagle@localhost) by church.cse.ogi.edu (8.9.3/8.9.3) id SAA28838; Mon, 24 Apr 2000 18:55:01 -0700 (PDT) Date: Mon, 24 Apr 2000 18:55:01 -0700 (PDT) From: Perry Wagle <wagle@cse.ogi.edu> Message-Id: <200004250155.SAA28838@church.cse.ogi.edu> To: crispin@wirex.com, wagle@cse.ogi.edu Subject: Re: [Fwd: libsafe] X-Mozilla-Status2: 00000000 Lucent Bell Labs has released "libsafe" to help prevent buffer overflow attacks (http://www.newsalert.com/bin/story?StoryId=Cop6aWbKbyteXnZC). Their web page is (http://www.bell-labs.com/org/11356/libsafe.html). I downloaded the source. My assessment is that its a stack parser with front ends for a few of the usual suspects for buffer overflows (strcpy, strcat, getwd, gets, [vf]scanf, realpath, [v]sprintf). The front ends (attempt to) check the bounds of the stack frame that the buffer resides in. Immunix decided years ago not to do stack parsers. GDB (the GNU debugger) can't do it reliably in my experience on Linux/i386, why would we be better? Mathematically, an executing program can parse its own stack because part of the necessary information is encoded in data on the stack, and part is hardcoded in the program instructions. Parsing the stack is probably [undecidably?] hard for an external observer [a particular instance of the compiler might produce instruction streams with decidable stack behavior]. The flaws with LibSafe are (in no particular order): (1) LibSafe assumes that the stack grows downward, and well as other i386'sms. This is a repairable nitpick. (2) LibSafe assumes that saved frame pointers are at the beginning of each stack frame. This isn't always true. Optimizers can decide not to save the frame pointer, and programmers can tell the compiler not to save it. So, unlike StackGuard, LibSafe doesn't necessarily protect each stack frame. (3) Only calls to "strcpy, strcat, getwd, gets, [vf]scanf, realpath, and [v]sprintf" are protected. Statistically, this is probably good coverage, but the whole C paradigm is null terminated strings and no array bounds checks, so its not as complete as StackGuard, since these aren't the only routines that overflow buffers. (4) They don't protect anything before the supposed location of the frame pointer on the stack. In particular, saved registers and adjacent autovars to the buffer. StackGuard is worse, it doesn't even protect the saved frame pointer. Technically, StackGuard could put canaries most anywhere on the stack that it wants; but due to the nature of its "after the fact" detection, it seemed prudent to put canaries as close to the protected data (the return address "transfer of control" hook) as possible. (5) LibSafe doesn't work if the application statically links the lineup of usual suspects (listed above). It works by preloading the stub replacements via ELF dynamic library loading. (6) I think they exagerate the performance hit of StackGuard (moderate?!?!), but that's not too unreasonable of them. I mean, what *would* a objective threshold be? Pluses are: (1) When it works, LibSafe is proactive rather than reactive like StackGuard. Buffer overflows are detected before they occur, rather than afterward like StackGuard. This isn't that big a point, given that StackGuard detects it pretty quickly -- and most importantly before the transfer of control to the injected code. (2) The LibSafe overflow exception handler is more complex (sends email, etc) than my default StackGuard one. Which is more comfortable to do since the buffer overflow is prevented and state is (allegedly) not corrupt. (3) When LibSafe works, it protects the saved frame pointer as well as the return address. StackGuard only protects the return address. Of course, neither protects the saved registers and the other autovars. (4) They don't require recompilation of the application, which beats StackGuard for closed-source applications. (5) Yet again, someone gets mileage out of an idea that I have first, but decide is trivial. 8) 8( They compare the performance to some unknown version of StackGuard, and are faster. Well, sure, they protect less stuff. Finally, according to the article: Linux distributors Red Hat, Inc., Linux-Mandrake, Turobolinux and Debian GNU/Linux are working with Bell Labs to incorporate Lucent Libsafe into their software releases. My conclusion is that I should use LibSafe to protect software that I can't recompile, and StackGuard to protect that which I can. The only advantage to combining the two (that I can see) is for protecting (some of) the saved frame pointers. -- Perry --------------B71FC48015AD4E363B53AF15--