By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,874 Members | 1,027 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,874 IT Pros & Developers. It's quick & easy.

Buffer overflow protection

P: n/a
If we want our programs to be protected against buffer overflows, must we
check the size of the various containers explicitly?

E.g.

#include <iostream>
#include <string>
int main()
{
using namespace std;

string s;

while(cin>>s)
;

// ...
}
should become:
#include <iostream>
#include <string>
#include <cctype>
int main()
{
using namespace std;

string s;

while(cin && s.size()<s.max_size())
{
char c;

cin>>c;

if(isspace(c))
continue;

s.push_back(c);
}

// ...
}


Ioannis Vranos
Jul 22 '05 #1
Share this Question
Share on Google+
13 Replies


P: n/a
"Ioannis Vranos" <iv*@guesswh.at.emails.ru> wrote in message
news:c5***********@ulysses.noc.ntua.gr...
If we want our programs to be protected against buffer overflows, must we
check the size of the various containers explicitly?

E.g.

#include <iostream>
#include <string>
int main()
{
using namespace std;
string s, temp;
while(cin>>temp)
s+=temp;
// ...
}
should become:
#include <iostream>
#include <string>
#include <cctype>
int main()
{
using namespace std;

string s;

while(cin && s.size()<s.max_size())
{
char c;

cin>>c;

if(isspace(c))
continue;

s.push_back(c);
}

// ...
}


Ioannis Vranos


Jul 22 '05 #2

P: n/a
I'm puzzled. Is it even *possible* for s.size() to have a value greater
than s.max_size()? That would seem to violate the concept of "max",
wouldn't it? So, shouldn't the streaming operator prevent s.size() from
ever exceeding s.max_size() in the first place, making any such check on
your part redundant?

I know that checking for buffer overruns is important when filling arrays,
but I would think one of the advantages of using a string class and
streaming operators is to protect against such things.

But for filling arrays, I'd agree on your design, where you add one
character at a time. It's silly to try to see if you've *already* overrun
memory.

-Howard
Jul 22 '05 #3

P: n/a
On Tue, 13 Apr 2004 14:59:35 +0300 in comp.lang.c++, "Ioannis Vranos"
<iv*@guesswh.at.emails.ru> wrote,
If we want our programs to be protected against buffer overflows, must we
check the size of the various containers explicitly?
You need to ensure that the sizes are checked.
How explicit it is, is another matter.
string s;

while(cin>>s)


Here std::string and its operator>> do the checking.
So, it does not need to be explicit.

Jul 22 '05 #4

P: n/a
Howard wrote:
I'm puzzled. Is it even *possible* for s.size() to have a value greater
than s.max_size()? That would seem to violate the concept of "max",
wouldn't it?
I believe so. I was unable to find exact details, but I'm fairly sure
that attempting to exceed a container's max_size will fail for one
reason or another. I suspect it will fail due to memory exhaustion
before you get to that point, and if that doesn't occur it will probably
throw an exception. The standard definitely says that an exception will
be thrown in a few cases (like calling reserve() for a vector where the
new capacity is too large, if I recall correctly).
So, shouldn't the streaming operator prevent s.size() from
ever exceeding s.max_size() in the first place, making any such check on
your part redundant?


I think the container (or string) itself will prevent it.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Jul 22 '05 #5

P: n/a
Ioannis Vranos wrote:
"Ioannis Vranos" <iv*@guesswh.at.emails.ru> wrote in message
news:c5***********@ulysses.noc.ntua.gr...
If we want our programs to be protected against buffer overflows, must we
check the size of the various containers explicitly?

E.g.

#include <iostream>
#include <string>
int main()
{
using namespace std;


string s, temp;
while(cin>>temp)
s+=temp;

// ...
}


The library is responsible for managing the buffers and preventing their
overflowing. I generally assume memory exhaustion will occur before
anything else. If max_size() is reached first, I'm not 100% sure what
should happen. My guess is that an exception will be thrown, either
length_error or bad_alloc. In effect, exceeding max_size() means
exhausting the memory of the allocator I think, so bad_alloc might be
appropriate, though I suppose I should check the standard and see how
allocators are supposed to handle running out of memory.

From a security standpoint, if we assume that an overflow of this sort
could exist, it seems likely that an attack exploiting such an overflow
would have much less chance of succeeding than a traditional
fixed-buffer-length overflow attack. max_size() is probably up around 2
or 4 billion. That's a hell of a lot of data to dump into the program.
If it were a remote attack, it would take quite a while to transfer all
that (over 3 minutes on a 10 Mbps connection?), and I imagine a IDS
(which I know nothing about) would have a very good chance of detecting
that.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Jul 22 '05 #6

P: n/a
"Kevin Goodsell" <us*********************@neverbox.com> wrote in message
news:Oy*****************@newsread2.news.pas.earthl ink.net...

The library is responsible for managing the buffers and preventing their
overflowing. I generally assume memory exhaustion will occur before
anything else.

This can't happen on all modern systems using virtual memory (swap) file. If
one has 10 GB swap file my guess is that max_size() can be reached. I am too
bored to check the standard but if noone provides an answer i shall be
forced to do so, since i can't live for long with such a question.

If max_size() is reached first, I'm not 100% sure what
should happen. My guess is that an exception will be thrown, either
length_error or bad_alloc. In effect, exceeding max_size() means
exhausting the memory of the allocator I think, so bad_alloc might be
appropriate, though I suppose I should check the standard and see how
allocators are supposed to handle running out of memory.

From a security standpoint, if we assume that an overflow of this sort
could exist, it seems likely that an attack exploiting such an overflow
would have much less chance of succeeding than a traditional
fixed-buffer-length overflow attack. max_size() is probably up around 2
or 4 billion. That's a hell of a lot of data to dump into the program.
If it were a remote attack, it would take quite a while to transfer all
that (over 3 minutes on a 10 Mbps connection?), and I imagine a IDS
(which I know nothing about) would have a very good chance of detecting
that.

Buffer overflow attacks happen all the time. However i am not checking about
protection against attacks here. This is a general reliability question. If
there is no such a check implicitly in standard library containers, the
whole scenario will defeat the abstraction mechanism of the standard library
and i do not think this can happen anyway. In 15 minutes or so i 'll check
the standard and drop a message here.


Ioannis Vranos

Jul 22 '05 #7

P: n/a
Ioannis Vranos wrote:
"Kevin Goodsell" <us*********************@neverbox.com> wrote in message
news:Oy*****************@newsread2.news.pas.earthl ink.net...
The library is responsible for managing the buffers and preventing their
overflowing. I generally assume memory exhaustion will occur before
anything else.


This can't happen on all modern systems using virtual memory (swap) file. If
one has 10 GB swap file my guess is that max_size() can be reached. I am too
bored to check the standard but if noone provides an answer i shall be
forced to do so, since i can't live for long with such a question.


I found this in the unofficial list of C++2003 changes:

Insert subclause 21.3, paragraph 4a:

4a For any string operation, if as a result of the operation,
size() would exceed max_size() then the operation throws
length_error.
Strangely, I couldn't find anything similar for other containers.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Jul 22 '05 #8

P: n/a
Kevin Goodsell wrote:
Ioannis Vranos wrote:
"Kevin Goodsell" <us*********************@neverbox.com> wrote in message
news:Oy*****************@newsread2.news.pas.earthl ink.net...
The library is responsible for managing the buffers and preventing their
overflowing. I generally assume memory exhaustion will occur before
anything else.



This can't happen on all modern systems using virtual memory (swap)
file. If
one has 10 GB swap file my guess is that max_size() can be reached. I
am too
bored to check the standard but if noone provides an answer i shall be
forced to do so, since i can't live for long with such a question.

I found this in the unofficial list of C++2003 changes:

Insert subclause 21.3, paragraph 4a:

4a For any string operation, if as a result of the operation,
size() would exceed max_size() then the operation throws
length_error.
Strangely, I couldn't find anything similar for other containers.


This document, by the way, came from Stroustrup's web page if I recall
correctly. If it's not there, then maybe it was Koenig's page.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Jul 22 '05 #9

P: n/a
"Kevin Goodsell" <us*********************@neverbox.com> wrote in message
news:u9*****************@newsread2.news.pas.earthl ink.net...
Ioannis Vranos wrote:
"Kevin Goodsell" <us*********************@neverbox.com> wrote in message
news:Oy*****************@newsread2.news.pas.earthl ink.net...
The library is responsible for managing the buffers and preventing their
overflowing. I generally assume memory exhaustion will occur before
anything else.


This can't happen on all modern systems using virtual memory (swap) file. If one has 10 GB swap file my guess is that max_size() can be reached. I am too bored to check the standard but if noone provides an answer i shall be
forced to do so, since i can't live for long with such a question.


I found this in the unofficial list of C++2003 changes:

Insert subclause 21.3, paragraph 4a:

4a For any string operation, if as a result of the operation,
size() would exceed max_size() then the operation throws
length_error.

Can you provide the URL please? And what is C++2003? I assume C++0x as it
had so far?


Regards,

Ioannis Vranos

Jul 22 '05 #10

P: n/a
Ioannis Vranos wrote:
"Kevin Goodsell" <us*********************@neverbox.com> wrote in message
news:u9*****************@newsread2.news.pas.earthl ink.net...
Ioannis Vranos wrote:

"Kevin Goodsell" <us*********************@neverbox.com> wrote in message
news:Oy*****************@newsread2.news.pas.ear thlink.net...
The library is responsible for managing the buffers and preventing their
overflowing. I generally assume memory exhaustion will occur before
anything else.

This can't happen on all modern systems using virtual memory (swap)
file. If
one has 10 GB swap file my guess is that max_size() can be reached. I am
too
bored to check the standard but if noone provides an answer i shall be
forced to do so, since i can't live for long with such a question.


I found this in the unofficial list of C++2003 changes:

Insert subclause 21.3, paragraph 4a:

4a For any string operation, if as a result of the operation,
size() would exceed max_size() then the operation throws
length_error.


Can you provide the URL please? And what is C++2003? I assume C++0x as it
had so far?


I think this is it:

http://www.acceleratedcpp.com/author.../revisions.pdf

C++2003 is an official update to the language that includes corrections
and clarifications, but no new features.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Jul 22 '05 #11

P: n/a
"Ioannis Vranos" <iv*@guesswh.at.emails.ru> wrote in message
news:c5**********@ulysses.noc.ntua.gr...

In 15 minutes or so i 'll check the standard and drop a message here.

From the C++98 standard:

<stdexcept>

19.1.4 Class length_error

namespace std {
class length_error : public logic_error {
public:
explicit length_error(const string& what_arg);
};
}

1 The class length_error defines the type of objects thrown as exceptions to
report an attempt to produce
an object whose length exceeds its maximum allowable size.
length_error(const string& what_arg);

2 Effects: Constructs an object of class length_error.

3 Postcondition: strcmp(what(), what_arg.c_str()) == 0.
....
21.3 Template class basic_string

3 In all cases, size() <= capacity().

4 The functions described in this clause can report two kinds of errors,
each associated with a distinct exception:
- a length error is associated with exceptions of type length_error
(19.1.4);
- an outofrange
error is associated with exceptions of type out_of_range (19.1.5).
[Elsewhere it mentions length error check in the constructors: "Throws:
length_error if n == npos". And in many other places. ]

....

vector throws it too: "Throws: length_error if n > max_size()."

basic_string (including string of course), and vector are the only standard
library containers that throw std::length_error exception.
Naturally i should not expect any such checks from classes of the kind
valarray. For classes like std::bitset i shall check some other time...


Regards,

Ioannis Vranos

Jul 22 '05 #12

P: n/a
"Ioannis Vranos" <iv*@guesswh.at.emails.ru> wrote in message
news:c5***********@ulysses.noc.ntua.gr...

Provided the length_error exception the reliability of the code can be
ensured:
#include <iostream>
#include <string>
#include <stdexcept>
int main()
{
using namespace std;

string s, temp;

try
{
while(cin>>temp)
s+=temp;
}

catch(length_error)
{
// ...
}

// ...
}
or

#include <iostream>
#include <string>
#include <stdexcept>
int main() try
{
using namespace std;

string s, temp;

while(cin>>temp)
s+=temp;

// ...
}

catch(std::length_error)
{
// ...
}


Ioannis Vranos

Jul 22 '05 #13

P: n/a
On Tue, 13 Apr 2004 23:20:09 +0300, "Ioannis Vranos"
<iv*@guesswh.at.emails.ru> wrote:
"Kevin Goodsell" <us*********************@neverbox.com> wrote in message
news:Oy*****************@newsread2.news.pas.earth link.net...

The library is responsible for managing the buffers and preventing their
overflowing. I generally assume memory exhaustion will occur before
anything else.

This can't happen on all modern systems using virtual memory (swap) file. If
one has 10 GB swap file my guess is that max_size() can be reached. I am too
bored to check the standard but if noone provides an answer i shall be
forced to do so, since i can't live for long with such a question.


On a 32 bit system, you generally only have about 2GB of virtual
memory to play with - hitting this limit with modern software is a
real possibility. The size of the swap file and physical memory have
no bearing on this - it's an addressing problem that is solved only by
moving to 64-bit architecture, or coming up with another arcane
segmented pointer architecture like DOS's near and far pointers.

Tom
--
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Jul 22 '05 #14

This discussion thread is closed

Replies have been disabled for this discussion.