Re: New Microsoft Bug Problems Blamed On Globalization

From: Alun Jones (alun@texis.com)
Date: 02/18/02


From: alun@texis.com (Alun Jones)
Date: Mon, 18 Feb 2002 21:12:58 GMT

In article <a4rcdl$l38$1@nntp.itservices.ubc.ca>, unruh@physics.ubc.ca (Bill
Unruh) wrote:
>In <1014040510.2621.0.nnrp-12.3e31ffea@news.demon.co.uk> "Ken Hagan"
> <K.Hagan@thermoteknix.co.uk> writes:
>
>]Lest this go unchallenged, I would point out that it, and all the
>]people quoted in it, are talking utter baloney. Buffer overruns
>]are not prevented by guessing how much space you might need. (Quite
>]the contrary.) Instead, they are prevented by measuring how much
>]space you actually need and ensuring that you allocate that much.
>
>No. No matter how much buffer you allocate it can always be overrun by an
> attacker. The
>question is how you handle overruns. Do you allow anything to write beyond the
> end of the
>buffer? If you do your code is a disaster., no matter how big a buffer you
> allocated.
>This is absolutely attrocious software engineering.

Huh? That's a non-sequitur. It may be true on it's own, but it doesn't
follow from what Ken wrote. There are definitely two ways to prevent buffer
overrun attacks:
1. Allocate at least as much memory as you're going to use.
2. Use at most as much memory as you've allocated.

Ken's talking about doing method 1, and you're saying "no, you have to do
method 2".

Let's give a quick example of method 1:

char *mystrdup(const char *input)
{
  char *retval=new char[strlen(input)+1],*ptr=retval;
  while (*input) { *ptr++=*input++; }
  *ptr=0;
  return retval;
}

And, for comparison, here's method 2:

char *mystrdup(const char *input)
{
  char *retval=new char[256];
  for (int i=0; i<255 && input[i]; i++)
    retval[i]=input[i];
  retval[i]=0;
  return retval;
}

The former method will duplicate the string no matter how long it is, and the
latter will duplicate strings of up to 255 characters in length, truncating
after that.

Both avoid buffer overruns (barring any stupid mistakes I've made in typing
them in here), and both have their uses. Method 1 has the problem that an
attacker _might_ use an overlong string to sap resources, which are still
finite. Method 2 has the problem that you have to guess what's the biggest
string your users will want to use in your software, and if you're not careful
you can end up with other issues; for instance, if you use 256 characters for
your command _and_ parameters buffer, and the create command has less
characters than the delete command, then you can create files that can't be
deleted. [Yes, I've seen this problem in others' code]

Neither is, by itself, the sole solution; generally one or other needs to be
chosen, but each will prevent a buffer overrun.

Alun.
~~~~

[Note that answers to questions in newsgroups are not generally
invitations to contact me personally for help in the future.]

-- 
Texas Imperial Software   | Try WFTPD, the Windows FTP Server. Find us at
1602 Harvest Moon Place   | http://www.wftpd.com or email alun@texis.com
Cedar Park TX 78613-1419  | VISA/MC accepted.  NT-based sites, be sure to
Fax/Voice +1(512)258-9858 | read details of WFTPD Pro for NT.



Relevant Pages

  • Re: Why crash ?
    ... Yes, but naively, I would assume that the optimal buffer size ... depended on a certain number of characters, ... small string optimization is that the std::string object has a certain ... If you allocate dynamic storage, the string object has to store ...
    (microsoft.public.vc.language)
  • Re: Why crash ?
    ... Yes, but naively, I would assume that the optimal buffer size ... depended on a certain number of characters, ... small string optimization is that the std::string object has a certain ... If you allocate dynamic storage, the string object has to store ...
    (microsoft.public.vc.language)
  • Re: writing alibrary funtion ssprintf()
    ... length of the string and then again malloc(not exactly malloc ....there ... Snprintf will return the size of the buffer required for printing the whole string, so you can always adjust the default size upwards to match that number, and keep it that way in subsequent calls. ... You can thus take uio.uio_resid and use it to allocate the string's buffer, before flushing the buffer to it. ...
    (comp.lang.c)
  • Re: How to take in a string of any size?
    ... >>The idea is that if the string becomes as large as the buffer, ... >>the buffer size is probably a good bet. ... > memory than realloc() can allocate - and there is no check to be ...
    (comp.lang.c)
  • Re: Buffer over-run vulnerabilities
    ... More commonly (via stack buffer overruns) the inserted "data" contains ... execute is tricky and specific to each exploit, ...
    (comp.os.linux)

Loading