From owner-freebsd-security Wed Aug 28 00:07:07 1996 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id AAA07387 for security-outgoing; Wed, 28 Aug 1996 00:07:07 -0700 (PDT) Received: from freebsd.gaffaneys.com (dialup2.gaffaneys.com [134.129.252.21]) by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id AAA07378 for ; Wed, 28 Aug 1996 00:07:03 -0700 (PDT) Received: (from zach@localhost) by freebsd.gaffaneys.com (8.7.5/8.7.3) id CAA04232; Wed, 28 Aug 1996 02:08:08 -0500 (CDT) To: newton@communica.com.au (Mark Newton) Cc: gene@starkhome.cs.sunysb.edu, security@freebsd.org Subject: Re: Vulnerability in the Xt library (fwd) References: <9608280304.AA14763@communica.com.au> From: Zach Heilig Date: 28 Aug 1996 02:08:07 -0500 In-Reply-To: newton@communica.com.au's message of Wed, 28 Aug 1996 12:34:47 +0930 (CST) Message-ID: <87g258j8a0.fsf@freebsd.gaffaneys.com> Lines: 83 X-Mailer: Gnus v5.3/Emacs 19.34 Sender: owner-security@freebsd.org X-Loop: FreeBSD.org Precedence: bulk newton@communica.com.au (Mark Newton) writes: > Zach Heilig wrote: > > What we need is a lint-like utility (better > > than gcc) that can warn when it finds code like: > > { > > int buf[somesize]; > > > > strcpy(buf, argv[1]); > > } > > which is dangerous in all programs, it's just less dangerous than in > > setuid ones. > Ah, you mean like the strcpy(pathbuf, home) in tgetent() in termcap.c? Yeah, like that :-). > Really, strcpy isn't all such a program would need to look for. > There are many C library routines which perform no bounds checking > (sprintf(), gets(), strcpy() to name a few) and, even worse, there > are countless home-grown memory to memory copy routines which have > been written in ignorance of the possible consequences of poor range > checking and the assumption that if a buffer overflows the program > will crash and it's the stupid user's own fault. Essentially, your > rebadged "lint" would end up attempting to be a program which tests > the "correctness" of code, and if you can write one of them then I > suspect you'll end up richer than Bill Gates :-) Actually, you can get away a bit cheaper than that. The compiler could simply complain if a block of memory were passed to a function without first checking its length. There are ways to subvert this method, but a utility like that should catch most such errors. If I can find my notes, I've come up with a way to do range checking, without stepping on the programmers toes too badly (though it would have a noticeable impact on performance). The basic idea is to keep a table of all the blocks of memory in a program (the beginning and ending addresses), and check to make sure that all pointers are within one of these blocks whenever they are changed (pointers are usually changed less often than they are dereferenced). This method may be even more expensive than you might think, as there would be several different blocks to test against every time a pointer is changed. You would merge blocks that were adjacent, but consider the local variable blocks on the stack. You really shouldn't include the return addresses in the valid pointer list, so you have at least as many blocks as there are function calls on the stack. The list of active blocks would have to be kept up to date somehow as well. I suppose if you kept the list of blocks in a mostly balanced tree (or even a heap), verifying each pointer would take an average of (log2 n) tests, as would inserting or removing a block from the list (where n == number of memory blocks). The major disadvantage to this method is the high up front cost of not only implementing it, but also testing for and fixing every program that allows user input to overrun a buffer. > When gcc started printing "This program uses gets(), which is > probably unsafe" the first time a program called gets(), users > yelled and screamed their complaints for months. Regardless, I > believe the best way to deal with errors caused by buffer overflows > in standard C-library routines is going to be to insert similar > warning messages in those programs and make sure that programmers > know that their programs will be ugly if they use 'em. It would be silly to blindly print an error the first time each of the "unsafe" memory copy routines are called (simply because there are safe ways to call them). gets() is an entirely different beast as the programmer doesn't have control over the amount of data it tries to read. I don't have any extra disk space at the moment (looking to buy a 2gig SCSI drive, but won't be able to for a few months), or I'd experiment with some of my suggestions above. -- Zach Heilig (zach@blizzard.gaffaneys.com) | ALL unsolicited commercial email Support bacteria -- it's the | is unwelcome. I avoid dealing only culture some people have! | with companies that email ads.