A very interesting book

C

CBFalconer

Bart said:
.... snip ...

So, why do people complain all the time about the possibility of
buffer overflows in C, but not in other languages?

Because the basic design of C is such as to make automatic machine
checking of possible overflows impracticable to implement. That
was a choice during development.
 
R

Richard Bos

CBFalconer said:
jacob navia wrote:

Of course the minor detail that a fix for most of such errors, in
language form, was well developed 5 or 10 years before C appeared
(and 20+ years before C89) is ignored here. See ISO 7185, and the
successor ISO 10206.

YM ISO 1989, I'm sure.

Richard
 
J

jacob navia

Nick said:
rubbish. Yes gets() is a problem. No one in their right mind
uses gets(). But asctime() *can* be used safely. Just make sure
the buffer is big enough.

No you can't make sure the buffer is big enough. The standard mandates
a 26 byte buffer.
Now can you name any other standard
function that *cannot* be used safely?

strncpy


nonsense. Plenty of C gets written using zero terminated
strings which is perfectly fine.

Sure sure.
you can get the program to do that for you

No


I don't think anyone objects to string libraries (at least
a couple of regulars have their own) the argument was aginst
incorporating a string library into the standard. Actually
I'd be interested. I've used C++ strings and it does make
some things easier.


The library uses operator overloading with counted strings.
 
J

James Kuyper

CBFalconer said:
James Kuyper wrote: ....

Extremely short sighted. Even if limited to readers on c.s.c
(which it was not, since it was cross-posted) ...

That was rather my point; it should not have been cross-posted to
comp.std.c, it should only have been posted to comp.lang.c.
... it is ridiculous to
suggest that readers should maintain total ignorance of anything
written outside of the actual standard. I have no knowledge of the
book in question, but such information is essential to anyone
daring to modify the actual C standard.

I'm not suggesting ignorance, I'm suggesting that there's appropriate
places to discuss various topics. That general topic of buffer overruns
is an important one that many people should be interested in, and should
discuss - but only in the appropriate forum - comp.std.c is not such a
forum.

Discussions of whether and how the standard should be modified to make
it easier to avoid buffer overruns would be entirely on topic in
comp.std.c (and arguably (everything on c.l.c is arguable!) off-topic
for comp.lang.c). I've seen no such discussion so far.
 
G

Giacomo Catenazzi

Nick said:
nonsense. Plenty of C gets written using zero terminated
strings which is perfectly fine.


you can get the program to do that for you


I don't think anyone objects to string libraries (at least
a couple of regulars have their own) the argument was aginst
incorporating a string library into the standard. Actually
I'd be interested. I've used C++ strings and it does make
some things easier.

Such libraries permits new types of attack.
Actual strings forces reading the memory from
beginning, so strings should terminate earlier
(by a "random" 0 character, or a segmentation fault).

On new libraries, the libraries could take advantage
of new fields, and thus it could access the end of
the string, so in kernel or other library space.

OTOH new strings will reduce programmer error, and
thus start of attacks.

Anyway alternate strings libraries already exists,
but it seems that they are not widely used, so
I don't think they are ready to be standardized.

BTW, an alternate string library should really
have a good design, allowing simple plug-in
of i18n, so reducing transition costs.


FYI I found n1173, with some rationale on these goals:
1.1.6 Preserve the null terminated string datatype
1.1.7 Do not require size arguments for unmodified strings
1.1.9 Library based solution


ciao
cate
 
J

James Kuyper

That won't do the job. The right way to use asctime() safely is to make
sure it's argument points at a structure whose contents won't cause a
buffer overrun.
No you can't make sure the buffer is big enough.

You're right about that, but not about this:
... The standard mandates
a 26 byte buffer.

The standard mandates that the actual implementation be equivalent to
specified implementation. Since the consequences of writing past the end
of a buffer are that the behavior is undefined, there is no behavior
that is prohibited to asctime() when called with a pointer to a struct
tm whose contents would cause that buffer to overflow. Which means that
an implementation which used a longer buffer would be just as conforming
as one which did not.

A single counter-example is sufficient to disprove a general assertion
like "strncpy() cannot be used safely". If your assertion were true,
there would have have to be some safety issue with the following code.
Would you care to explain what you think that issue is?

#include <string.h>
#include <stdio.h>

int main(void)
{
char input[] = "This is the input string";
char output[10];

size_t size = (sizeof output - 1 < sizeof input ?
sizeof output - 1 : sizeof input);

strncpy(output, input, size);
output[size] = '\0';
printf("%s\n", output);

return 0;
}

The '-1' and the explicitly forced null termination are needed only if
downstream processing requires that output[] be a null-terminated
string. That is true in the code above, but has not been true in any of
the cases where I've have a reason to use strncpy() recently, which
makes safe usage of strncpy() a lot simpler.

If "input" and "output" were pointers rather than arrays, determine the
correct value for the third argument of strncpy() would be more
complicated, but is still feasible.
 
K

Keith Thompson

jacob navia said:
No you can't make sure the buffer is big enough. The standard mandates
a 26 byte buffer.

Yes, asctime() provides its own static buffer. But you can use
asctime() safely by ensuring that the arguments (or rather, the
members of the struct tm object pointed to by the single argument) are
within safe bounds.

asctime() is a poorly designed and specified function. It can't be
changed *too* much without breaking existing code. It *could* be
tweaked to require implementation-defined but safe behavior for
out-of-bounds arguments, and I would support such a change. But I
suspect that most existing code that uses asctime() uses it with an
argument corresponding to the current time, which will be safe until
the end of the year 9999.

It absolutely is not as dangerous as gets(). gets() cannot be used
safely (unless you have absolute control over what will appear on
stdin, which is not normally possible). asctime() *can* be used
safely with some care, and it usually is. For example, the following
program is safe if it's executed before the year 10,000 (assuming the
time() function doesn't misbehave):

#include <stdio.h>
#include <time.h>
int main(void)
{
time_t now = time(NULL);
fputs(asctime(localtime(&now)), stdout);
return 0;
}

You are mistaken. strncpy() is poorly named, and is difficult to use
safely if you don't understand what it actually does, but it most
certainly can be used safely, if you happen to need the rather odd
data structure that it supports.

Yes, I can write unsafe code using strncpy, but that wasn't the
question. I can write unsafe code without using any library functions
at all.

[...]
The library uses operator overloading with counted strings.

I think that explains the lack of enthusiasm. A proposal for a
library that can be used with C compilers other than yours might have
gotten a better reception.
 
K

Keith Thompson

CBFalconer said:
Extremely short sighted. Even if limited to readers on c.s.c
(which it was not, since it was cross-posted) it is ridiculous to
suggest that readers should maintain total ignorance of anything
written outside of the actual standard. I have no knowledge of the
book in question, but such information is essential to anyone
daring to modify the actual C standard.

Anyone daring to modify the actual C standard should certainly have
sources of information beyond comp.std.c.
 
K

Keith Thompson

YM ISO 1989, I'm sure.

ISO 7185 and ISO 10206 are Pascal; ISO 1989 is Cobol.

I haven't used Pascal in many years, but as I recall it paid a price
for its relative safety.
 
J

jacob navia

Keith said:
Yes, asctime() provides its own static buffer. But you can use
asctime() safely by ensuring that the arguments (or rather, the
members of the struct tm object pointed to by the single argument) are
within safe bounds.

The C standard shows a piece of code that will overflow its static
buffer if used with a year value greater than 8900 (if I remember
correctly)

Similarly, if the month value is greater than 12 it will
show UB.

Obviously, showing such a piece of code is a reminder to the rest
of the world how much the standard cares about buffer overflows.

The discussion in this group confirms this. Look at Mr Thomson:
asctime() is a poorly designed and specified function. It can't be
changed *too* much without breaking existing code.

Absolutely not. I derived the formula for the EXACT size of the buffer
in this discussion group. It is relatively simple. The only thing that
needs to be changed is the "26" in the size of the buffer.

I mailed a correction of asctime to Mr Plauger, probably member of the
comitee. Never an answer.

It *could* be
tweaked to require implementation-defined but safe behavior for
out-of-bounds arguments, and I would support such a change.

Then why you don't support it now and act to get rid of a buffer
overflowing code written in the C standard document?

But I
suspect that most existing code that uses asctime() uses it with an
argument corresponding to the current time, which will be safe until
the end of the year 9999.

No, the end is 8100 since you add 1900
It absolutely is not as dangerous as gets(). gets() cannot be used
safely (unless you have absolute control over what will appear on
stdin, which is not normally possible). asctime() *can* be used
safely with some care, and it usually is. For example, the following
program is safe if it's executed before the year 10,000 (assuming the
time() function doesn't misbehave):

#include <stdio.h>
#include <time.h>
int main(void)
{
time_t now = time(NULL);
fputs(asctime(localtime(&now)), stdout);
return 0;
}


You are mistaken. strncpy() is poorly named, and is difficult to use
safely if you don't understand what it actually does, but it most
certainly can be used safely, if you happen to need the rather odd
data structure that it supports.

After all those "poorly named", "difficult to use", "odd data structure"
couldn't we get RID OF THAT PIECE OF ... ???

Yes, I can write unsafe code using strncpy, but that wasn't the
question. I can write unsafe code without using any library functions
at all.

You misunderstand the whole point. Apparently you do not understand what

ERROR PRONE

means?


Would you drive a car that kills you at the slightest mistake
for years and years?

You CAN drive a car like that if you never make any mistakes
obviously. And after several thousand people have died you
CAN say:

They are just bad drivers. They made mistakes.

[...]
The library uses operator overloading with counted strings.

I think that explains the lack of enthusiasm. A proposal for a
library that can be used with C compilers other than yours might have
gotten a better reception.

You jsut do not want to understand. I presented it as an example
of the direction that C could take, that is why I presented it in
this group.
 
L

lawrence.jones

In comp.std.c Nick Keighley said:
But asctime() *can* be used safely. Just make sure
the buffer is big enough.

Easier said than done, unless you know for sure that all the values in
the struct tm are within their normal ranges and that the value of
tm_year is between -2899 and 8099.
 
C

CBFalconer

jacob said:
Nick Keighley wrote:
.... snip ...


No you can't make sure the buffer is big enough. The standard
mandates a 26 byte buffer.

You don't have control over the buffer. Best to receive it in a:

const char *buff;
...
buff = asctime(...);
From the std:
7.23.3.1 The asctime function

Synopsis
[#1]
#include <time.h>
char *asctime(const struct tm *timeptr);

Description

[#2] The asctime function converts the broken-down time in
the structure pointed to by timeptr into a string in the
form

Sun Sep 16 01:03:52 1973\n\0

using the equivalent of the following algorithm.

char *asctime(const struct tm *timeptr) {
static const char wday_name[7][3] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
static const char mon_name[12][3] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
static char result[26];
^^^^^^
Note this word.
 
C

CBFalconer

Keith said:
.... snip ...

Yes, I can write unsafe code using strncpy, but that wasn't the
question. I can write unsafe code without using any library
functions at all.

And you consider this makes you exceptional? :)
 
J

jacob navia

Easier said than done, unless you know for sure that all the values in
the struct tm are within their normal ranges and that the value of
tm_year is between -2899 and 8099.

Specially because those limits ARE NOT EVEN MENTIONED in the
standards document. They can be inferred by reading the code
and seeing where it would overflow!
 
J

jameskuyper

jacob said:
Keith Thompson wrote: ....

The C standard shows a piece of code that will overflow its static
buffer if used with a year value greater than 8900 (if I remember
correctly)

Similarly, if the month value is greater than 12 it will
show UB.

Obviously, showing such a piece of code is a reminder to the rest
of the world how much the standard cares about buffer overflows.

The standard doesn't care about anything. The C committee should care
about buffer overruns, and does. Doug Gwyn is a committee member, and
one of the people posting to comp.std.c who argues most strenuously
for keeping the standard as it is currently written; yet even he
expressed sympathy (2006-07-05) for the concept of modifying the
standard in the manner Keith Thompson suggested, to deal with this
issue.

....
Then why you don't support it now and act to get rid of a buffer
overflowing code written in the C standard document?

His comment expresses support, right now - why do thing otherwise?
What action are you suggesting that he should do and has not done to
get rid of it? Do you misunderstand the standardization process so
badly that you think that if a given change is desired right now, an
appropriately updated version of the standard will immediatley follow?
The process takes a little longer than that.
No, the end is 8100 since you add 1900

The maximum year is 9999, as Keith said. You're referring to the
maximum safe value of tm_year, which is 8099. 8100 is the first value
after that which is unsafe, which is a different matter.
You misunderstand the whole point. Apparently you do not understand what

ERROR PRONE

means?

How did you reach that conclusion? The question wasn't about functions
that are error prone. The question was "Now can you name any other
standard function that *cannot* be used safely?". Those are two very
different things.
 
K

Keith Thompson

jacob navia said:
The C standard shows a piece of code that will overflow its static
buffer if used with a year value greater than 8900 (if I remember
correctly)

Similarly, if the month value is greater than 12 it will
show UB.

Obviously, showing such a piece of code is a reminder to the rest
of the world how much the standard cares about buffer overflows.

The discussion in this group confirms this. Look at Mr Thomson:

Please have the courtesy to spell my name right. Copy-and-paste it if
you have to.
Absolutely not. I derived the formula for the EXACT size of the buffer
in this discussion group. It is relatively simple. The only thing that
needs to be changed is the "26" in the size of the buffer.

I mailed a correction of asctime to Mr Plauger, probably member of the
comitee. Never an answer.

Sorry to hear that. Without seeing your e-mail, I won't speculate on
why he didn't respond, but I'm sure he gets a lot of e-mail.
Then why you don't support it now and act to get rid of a buffer
overflowing code written in the C standard document?

I just stated my support in a posting to this newsgroup. I'm not a
member of the committee. What else do you expect me to do?

Implementers can already implement asctime() in a way that avoids
buffer overflows; I presume you've done so for lcc-win.

BTW, given the current specification and the existence of code that
depends on it, I'd recommend truncating fields rather than making the
buffer bigger. Code that uses asctime() might reasonably do something
like this:

char buffer[26];
char *result = asctime(/* ... */);
strcpy(buffer, result);

Shifting the buffer overflow from asctime() to the code that uses it
isn't particularly helpful.
No, the end is 8100 since you add 1900

Calling asctime() with timeptr->tm_year == 8100 will cause a buffer
overflow. That corresponds to the year 10000.

As I said, calling asctime() with an argument corresponding to the
current time will be safe until the end of the year 9999. I did *not*
refer to a tm_year value 9999.

But that's a minor point. The point is that asctime(), unlike gets(),
can be used safely. Please don't react to that simple statement as if
I were defending the design of asctime() or opposing any changes in
its specification.
After all those "poorly named", "difficult to use", "odd data structure"
couldn't we get RID OF THAT PIECE OF ... ???

It would break existing code. Some existing code that uses strncpy()
undoubtedly uses it incorrectly. But some of it uses it correctly and
safely. If it's not useful to you, don't use it.

You claimed that strncpy "*cannot* be used safely". It has been
proven by example, that it can. Why are you unwilling to admit your
mistake?
You misunderstand the whole point. Apparently you do not understand what

ERROR PRONE

means?

<sarcasm>Gosh, maybe you could explain it to me. Please use small
words. said:
Would you drive a car that kills you at the slightest mistake
for years and years?

You CAN drive a car like that if you never make any mistakes
obviously. And after several thousand people have died you
CAN say:

They are just bad drivers. They made mistakes.

I *do* drive a car that can kill me at the slightest mistake. If I
turn the steering wheel in the wrong direction or hit the accelerator
at the wrong time, it can veer into oncoming traffic. Even with
airbags and seatbelts, I might not survive a head-on collision at a
relative velocity over 100 mph. Or I could drive off a cliff, or into
a wall. The car isn't smart enough to stop me from doing something
stupid. And yet I and millions of other people continue to drive, and
thousands are killed every year.

Sorry, what was the point of this metaphor?
[...]
I have proposed a string library for C to make those errors more
difficult. The reception was as expected... :-(
I don't think anyone objects to string libraries (at least
a couple of regulars have their own) the argument was aginst
incorporating a string library into the standard. Actually
I'd be interested. I've used C++ strings and it does make
some things easier.
The library uses operator overloading with counted strings.
I think that explains the lack of enthusiasm. A proposal for a
library that can be used with C compilers other than yours might have
gotten a better reception.

You jsut do not want to understand. I presented it as an example
of the direction that C could take, that is why I presented it in
this group.

You presented a string library that depends on adding a major new
feature to the language, one that's highly controversial. You're
surprised that it wasn't greeted with enthusiasm. I'm not. Which one
of us just does not want to understand?
 
J

jacob navia

Dann said:
OK.
Where is the newsgroup where discussions about reparing the most
significant defect in the C language are topical?

The same answer always:

"There are no problems with C. Only with lazy programmers
that do not know how to do their job".

comp.lang.c has nothing to do with the real world.
 
J

jameskuyper

Dann Corbit wrote:
....
Where is the newsgroup where discussions about reparing the most significant
defect in the C language are topical?

Since the C language is defined by the standard, any repair
necessarily takes the form of a change to some future version of the
standard. As I said earlier, referring to comp.std.c:
If the book ... has suggestions for future versions of the C standard, it would also be on
topic to discuss those suggestions.

So far, I've seen nothing to suggest that this book contains any
proposed changes to the C standard. It might, and if it does, I'd be
happy to see them discussed on comp.std.c. However, no aspect of that
book which is not so connected to the C standard would be on-topic.


For example, things that would not be on-topic in c.s.c include:
* Suggestions about how to write your code to avoid buffer overruns
* Design details of utilities for detecting code which might produce
buffer overruns,
* Discussions about compiler features that would help avoid buffer
overruns.

Things that would be on-topic in c.s.c:
* Discussions about whether a given compiler feature to avoid buffer
overruns is allowed for a standard-conforming implementation of C.
* Discussions about whether a compiler extension to avoid buffer
overruns should be standardized.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,072
Latest member
trafficcone

Latest Threads

Top