Firewall Wizards mailing list archives

Re: Buffer Overruns


From: Joseph S D Yao <jsdy () cospo osis gov>
Date: Wed, 29 Dec 1999 09:34:14 -0500

On Wed, Dec 29, 1999 at 10:32:55AM +0000, Crispin Cowan wrote:
I really have questions on several levels:

  1. What are these stronger typing features?  What kinds of programming
     errors can C++ catch that C won't?

The two have blurred in my mind.  I would have to defer on this one.

  2. Can those type checks really be said to add security value to a
     language that still supports pointer arithmetic?  I.e. it may catch
     some bugs, but others go straight through, i.e. when people don't use
     the features.  "Strong typing" usually means that using the type
     checking features is mandatory.

The strong typing is mandatory.  I guess that, to some degree, C++ helps
good people not to make mistakes.  But it allows cheap hackers to get
around things if they want to.  Very American attitude embodied there.
You get everything you need to improve or hang yourself.  Your choice.

Yes, pointer arithmetic and lack of bounds checking.  (*sigh*)  This is
for backwards compatibility, of course.  When I was teaching C++, I
would tell my students that any time they found something that was hard
to explain in the language, it was almost certainly because of backwards
compatibility with C.  But it IS harder to make a "bad" pointer.

  3. What about all those yummy virtual function pointers lying around in
     heap space?  This makes it *much* easier to find a buffer to overflow
     to corrupt an adjacent code pointer.  Here's a straw man example.
     Pardon the crummy syntax, it's been a while :-)
          class shape {
              virtual int    rotate(int degrees);    // rotate the shape
              string    name;        // name of this shape object
          }
     If I can overflow the "name" string, I stomp right on the "rotate"
     virtual function, which is a pointer to code, with the pointer stored
     in heap space right next to the buffer.  This is the *ideal*
     situation for a buffer overflow attack.

On the one hand, I believe that this is an implementation issue rather
than a language issue per se.  OTOH, I know of no implementation that
does this otherwise.  Is this really more of a problem than trying to
overflow a stack variable into the stack return frame?  Both require
knowledge of the implementation architecture and an instance of blind
copying to exploit.  Both require either implicit bounds checking [e.g.
StackGuard, thank you very much! ;-)] or explicit size checking to
prevent.

If "shape" is properly implemented, then the data is all "private", and
the only way to put something into "name" is through an interface
function that is a member of "shape".  This is itself much more secure
than C, eh?  IF IT'S USED, then this will PREVENT any sort of buffer
overflow in this whole data type [class]!  IF.

class shape {
  private:
        string name;
  public:
        boolean set_name(char *str)
        {
                if (str == (char *) NULL)
                        return(False);
                if (strlen(str) >= name.buffer_length)
                        return(False);
                (void) name.copyin(str);
                return(True);
        };
        boolean set_name (string n);
        // etc.
};

And next, I know, you are cringing at the type casts.  A tool, as I have
said of other things, to be used for good or ...  eeevil.  Eh?  ;-)

-- 
Joe Yao                         jsdy () cospo osis gov - Joseph S. D. Yao
COSPO/OSIS Computer Support                                     EMT-B
-----------------------------------------------------------------------
This message is not an official statement of COSPO policies.



Current thread: