Skip site navigation (1)Skip section navigation (2)
Date:      28 Aug 1996 02:08:07 -0500
From:      Zach Heilig <zach@blizzard.gaffaneys.com>
To:        newton@communica.com.au (Mark Newton)
Cc:        gene@starkhome.cs.sunysb.edu, security@freebsd.org
Subject:   Re: Vulnerability in the Xt library (fwd)
Message-ID:  <87g258j8a0.fsf@freebsd.gaffaneys.com>
In-Reply-To: newton@communica.com.au's message of Wed, 28 Aug 1996 12:34:47 %2B0930 (CST)
References:  <9608280304.AA14763@communica.com.au>

next in thread | previous in thread | raw e-mail | index | archive | help
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.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?87g258j8a0.fsf>