473,385 Members | 1,645 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

A very interesting book

Buffer overflows are a fact of life, and, more specifically, a fact of
C.

All is not lost however. In the book

"Value Range Analysis of C programs" Axel Simon tries to establish a
theoretical framework for analyzing C programs. In contrast to other
books where the actual technical difficulties are "abstracted away",
this books tries to analyze real C programs taking into account
pointers, stack frames, etc.

It has just arrived today, I was waiting for it since several weeks.

http://www.di.ens.fr/~simona/book.html
--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Jul 22 '08
126 4247
In comp.std.c Nick Keighley <ni******************@hotmail.comwrote:
>
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.
--
Larry Jones

I kind of resent the manufacturer's implicit assumption
that this would amuse me. -- Calvin
Jul 23 '08 #51
jacob navia wrote:
Nick Keighley wrote:
.... snip ...
>
>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.
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.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Jul 23 '08 #52
Keith Thompson wrote:
>
.... 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? :-)

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Jul 23 '08 #53
la************@siemens.com wrote:
In comp.std.c Nick Keighley <ni******************@hotmail.comwrote:
>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.
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!
--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Jul 23 '08 #54
jacob navia wrote:
Keith Thompson wrote:
....
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 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.

....
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?
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.
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
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.
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?
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.
Jul 23 '08 #55
jacob navia <ja***@nospam.comwrites:
Keith Thompson wrote:
>jacob navia <ja***@nospam.comwrites:
>>Nick Keighley wrote:
On 23 Jul, 10:36, jacob navia <ja...@nospam.comwrote:
Bart van Ingen Schenau wrote:
>So, why do people complain all the time about the possibility of
>buffer overflows in C, but not in other languages?
>>
Because functions like gets() asctime() and other standard
functions (still in C99 standard even if gets() got deprecated)
make buffer overflows almost MANDATORY.
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.
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:
Please have the courtesy to spell my name right. Copy-and-paste it if
you have to.
>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.
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.
>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?
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.
>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
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.
>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;
}
>>>Now can you name any other standard
function that *cannot* be used safely?
strncpy
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 ... ???
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?
>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?
<sarcasm>Gosh, maybe you could explain it to me. Please use small
words.</sarcasm>
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?

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 23 '08 #56
CBFalconer <cb********@yahoo.comwrites:
Keith Thompson wrote:
>>
... 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? :-)
No, that's not what makes me exceptional. 8-)}

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 23 '08 #57
"James Kuyper" <ja*********@verizon.netwrote in message
news:7pDhk.322$X2.5@trnddc03...
Dann Corbit wrote:
>"James Kuyper" <ja*********@verizon.netwrote in message
...
>>reason. This group is very specifically for discussions about the C
standard, not about how to use the language defined by that standard.
...
>This:
"Value Range Analysis of C programs" Axel Simon tries to establish a
theoretical framework for analyzing C programs.

Sounds like it would be interesting to compiler vendors and language
designers to me.

While many on-topic discussions in comp.std.c are "interesting to compiler
vendors and language designers", the simple fact that an issue is
"interesting to compiler vendors and language designers" does not make it
on-topic for comp.std.c, not even if it's specifically about C. It has to
be about the C standard to be on-topic.
OK.
Where is the newsgroup where discussions about reparing the most significant
defect in the C language are topical?
** Posted from http://www.teranews.com **
Jul 23 '08 #58
Dann Corbit wrote:
"James Kuyper" <ja*********@verizon.netwrote in message
news:7pDhk.322$X2.5@trnddc03...
>Dann Corbit wrote:
>>"James Kuyper" <ja*********@verizon.netwrote in message
...
>>>reason. This group is very specifically for discussions about the C
standard, not about how to use the language defined by that standard.
...
>>This:
"Value Range Analysis of C programs" Axel Simon tries to establish a
theoretical framework for analyzing C programs.

Sounds like it would be interesting to compiler vendors and language
designers to me.

While many on-topic discussions in comp.std.c are "interesting to
compiler vendors and language designers", the simple fact that an
issue is "interesting to compiler vendors and language designers" does
not make it on-topic for comp.std.c, not even if it's specifically
about C. It has to be about the C standard to be on-topic.

OK.
Where is the newsgroup where discussions about reparing the most
significant defect in the C language are topical?
** Posted from http://www.teranews.com **
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.
--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Jul 23 '08 #59
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.
Jul 23 '08 #60
"Dann Corbit" <dc*****@connx.comwrites:
"James Kuyper" <ja*********@verizon.netwrote in message
news:7pDhk.322$X2.5@trnddc03...
>Dann Corbit wrote:
>>"James Kuyper" <ja*********@verizon.netwrote in message
...
>>>reason. This group is very specifically for discussions about the
C standard, not about how to use the language defined by that
standard.
...
>>This:
"Value Range Analysis of C programs" Axel Simon tries to establish
a theoretical framework for analyzing C programs.

Sounds like it would be interesting to compiler vendors and
language designers to me.

While many on-topic discussions in comp.std.c are "interesting to
compiler vendors and language designers", the simple fact that an
issue is "interesting to compiler vendors and language designers"
does not make it on-topic for comp.std.c, not even if it's
specifically about C. It has to be about the C standard to be
on-topic.

OK.
Where is the newsgroup where discussions about reparing the most
significant defect in the C language are topical?
comp.std.c.

Is that what we're discussing? Are there proposals for changes to the
next version of the standard?

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 23 '08 #61
jacob navia wrote:
Dann Corbit wrote:
....
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.
Interesting prediction. Does it bother you that there's essentially no
similarity between your predicted answer and the two answers that he's
actually received to that question?
Jul 23 '08 #62
Dann Corbit wrote:
"Mark McIntyre" <ma**********@TROUSERSspamcop.netwrote in message
news:0R*******************@en-nntp-06.am2.easynews.com...
>Richard Heathfield wrote:
>>Walter Roberson said:

In article <g6**********@aioe.org>, jacob navia <ja***@nospam.org>
wrote:
Buffer overflows are a fact of life, and, more specifically, a fact of
C.
If buffer overflows are indeed, as you claim, "a fact of C", then
no amount of theoretical analysis will allow you to eliminate them
in any actual C program.

On the other hand:

int main(void) { return 0; }

is a C program that has no possibility of buffer overflow.

Your point might have been more pointy if you'd written a program
that actually used a buffer.

Ah but his point was exactly that.

By what magic do the two of you know that no buffer is involved?
You misunderstand my comment as suggesting I was siding one way or the
other.
Here is the disassembly for the provided program on a C compiler:
Fascinating but I suspect irrelevant. What the compiler or runtime does
prior to starting the main routine is entirely a QOI issue. I should
imagine all sorts of arrays get created, name of programme, copy of
cmdline arguments, copy of environment, stuff associated with stdin etc.
So what? Is any of this compulsorily written in C? It could be in
assembler, pascal or web (the knuth one) for all it matters.

--
Mark McIntyre

CLC FAQ <http://c-faq.com/>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>
Jul 23 '08 #63
Dann Corbit wrote:
"Richard Heathfield" <rj*@see.sig.invalidwrote in message
The point discussed was in connection with vulnerabilities in connection
with the C programming language.
If a C program calls library functions, uses inline assembly or whatever
and performs buffer movements then that is salient to the discussion of
vulnerabilities and buffer overflow.
Just to remind you: library functions need not be written in C.

So what you're saying is - its the fault of hte C programming language
if someone writes a library function in another language, and that
library function contains a buffer overflow.

Hm?
To say: "I don't see any buffer use." when examining a fragment of C
code does not mean that buffer overruns will not happen because of using
a C compiler.
This is true, but axiomatic and useless. Exactly the same can be said
about any feature or bug that you cannot see in the code sample on display.
I think that this is a very important subject that
directly focuses on the chief criticism of the C language.
It is an important subject, but one won't help discussion of it by
accidentally blaming the C language for stuff which is in fact nothing
to do with it.

--
Mark McIntyre

CLC FAQ <http://c-faq.com/>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>
Jul 23 '08 #64
Dann Corbit wrote:
C is not more dangerous than (for instance) C++ in this regard. But it
is more dangerous than (for instance) Ada.
This is where your argument falls down. Remember that library functions
need not be written in the same language as the compiler is compiling.

Seems to me you're saying that
- the C runtime environment's startup code may call library functions
- those library functions might contain a buffer overflow
- therefore C is unsafe.

Is it not the case that
- the Ada runtime environment's startup code may call library functions
- those library functions might contain a buffer overflow
- therefore Ada is exactly as unsafe as C.

Unless you're asserting that no Ada compiler has libraries and the
startup code never calls any functions?

--
Mark McIntyre

CLC FAQ <http://c-faq.com/>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>
Jul 23 '08 #65
Friedrich wrote:
Bart van Ingen Schenau <Ba********************@ict.nlwrites:
>So, why do people complain all the time about the possibility of
buffer overflows in C, but not in other languages?
because that kind of errors plagues C programs mostly?
Perhaps thats because more programmes have been written in C than any
other language?
And C is easier to learn (and therefore has more novice programmers)?

By the way, we are potentially now into the "safety by obscurity" model
here which as any fule no is spurious. Plan-9 is safe because only
experts use it...

--
Mark McIntyre

CLC FAQ <http://c-faq.com/>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>
Jul 23 '08 #66
ja*********@verizon.net wrote:
jacob navia wrote:
Oh, god - has Navia hijacked this thread for one of his crusades?

Please people, do us all a favour and ignore him.
Jul 23 '08 #67
Dann Corbit said:
"Richard Heathfield" <rj*@see.sig.invalidwrote in message
news:2r******************************@bt.com...
<snip>
>If you *can't* overrun a buffer in a given language, then that language
isn't as powerful as it could be and, some would say, as it ought to be.

Let's suppose that instead of creating a language that can't overun a
buffer, we create a way to detect these flaws with 100% accuracy. Now we
have the best of both worlds.
If we can do this statically, or dynamically during testing, I'd agree.
Or suppose we create a super efficient way
to prevent them (e.g. CPU hardware instructions)
Then that becomes an artifact of the hardware rather than the language, and
you still have the problem when running on other hardware, hardware that
has not been blessed with this super-efficient prevention mechanism.
or suppose that a very clever
method is created to perform highly efficient software checks. All of
these ideas are worth considering.
Yes. My own favourite would be dynamic analysis during testing. (Static
analysis smacks too much of the Halting Problem.) That is, something you
can turn on or off at your leisure.
>Safety restrictions, no matter how praiseworthy they may be on their own
merits, nevertheless represent a diminution of freedom and power.

That freedom and power has resulted in literally billions of dollars of
damage.
Freedom is expensive. In the second world war, the Allies had the freedom
and power to fight the Third Reich. It cost millions of lives and a great
many millions of LCUs, and many people involved in that fight were given
the freedom and power to make costly mistakes. Without that freedom and
power, they could not have done what needed to be done.

Yes, freedom is expensive. But it is still necessary.

The cost is not less than if Grand Coulee dam had broken wide
open and destroyed all property downsteam in the state of Washington.
Given that Redmond is downstream of that dam, this issue might not be as
simple as at first appears.
A problem of that magnitude deserves some thought.
It's an ill wind that blows nobody any good. :-)
>
>>It's a fundamental defect inherent in its design.

No, it's a fundamental risk inherent in the provision of power - i.e.
that the power might be misused, either through accident or design.

Sometimes, the designer of a power tool will notice that for a few cents
he can put a guard on the tool and make it 100 times safer without any
real cost in effectiveness.
Very true.
Can this metaphor be applied to the C language?
I don't know but I think we should think about it.
I don't know either, and it's certainly worth discussing.
>If you want Ada, you know where to find it.

Every tool has its use, including Ada.
Yes, my point exactly. Ada, C, 4GLs, even Basic - everything has its place.
To criticise C for the ways in which it differs from other languages is
just silly. The differences are there, they're real, and for some people
they don't matter a jot. For those for whom those differences do matter,
well, that's what those other languages are for.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jul 23 '08 #68
In comp.std.c jacob navia <ja***@nospam.comwrote:
la************@siemens.com wrote:
In comp.std.c Nick Keighley <ni******************@hotmail.comwrote:
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.

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!
The normal ranges of the struct tm members are mentioned quite
prominently in 7.23.1p4 where they're specified. I would have thought
it fairly obvious that passing out of range values to any function that
doesn't explicitly document that it allows them is a bad idea and likely
to result in undefined behavior. The only one that needs to be inferred
is the range for tm_year.
--
Larry Jones

Wow, how existential can you get? -- Hobbes
Jul 23 '08 #69
"Richard Heathfield" <rj*@see.sig.invalidwrote in message
news:xr******************************@bt.com...
[snip]
>The cost is not less than if Grand Coulee dam had broken wide
open and destroyed all property downsteam in the state of Washington.

Given that Redmond is downstream of that dam, this issue might not be as
simple as at first appears.
Protected by the Cascade mountains, I am afraid.

** Posted from http://www.teranews.com **
Jul 23 '08 #70
Richard Heathfield <rj*@see.sig.invalidwrites:
[followups set to comp.lang.c]
[followups overridden for now, since what I have to say is relevant to
comp.std.c]
Dann Corbit said:
[...]
>I am surprised that you don't see any connection between buffer overruns
and the C language.

I am surprised that you don't see any connection between buffer overruns
and programming languages in general.

If you *can't* overrun a buffer in a given language, then that language
isn't as powerful as it could be and, some would say, as it ought to be.
Safety restrictions, no matter how praiseworthy they may be on their own
merits, nevertheless represent a diminution of freedom and power.
>It's a fundamental defect inherent in its design.

No, it's a fundamental risk inherent in the provision of power - i.e. that
the power might be misused, either through accident or design.

If you want Ada, you know where to find it.
Ada is as powerful as C. It doesn't forbid unsafe actions, it merely
requires you to specify them explicitly in most cases. For example,
to interpret an integer as a pointer (something C allows with a simple
cast), you have to instantiate Unchecked_Conversion and then call the
instance. (Strictly speaking, the C cast performs a type conversion,
not a reinterpretation, but it's implemented as a reinterpretation in
every implementation I've seen.)

It would be nice if C could achieve similar safety in normal use,
while still allowing unsafe constructs that are sometimes necessary in
practice, without changing the language so radically that most
existing code would be broken. I'm skeptical that this is possible,
but I'd be interested in seeing any concrete proposals.

If you want C with Ada-like safety (say, because you really like curly
braces), I think your best bet is to invent a new language.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 23 '08 #71
la************@siemens.com writes:
In comp.std.c jacob navia <ja***@nospam.comwrote:
>la************@siemens.com wrote:
In comp.std.c Nick Keighley <ni******************@hotmail.comwrote:
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.

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!

The normal ranges of the struct tm members are mentioned quite
prominently in 7.23.1p4 where they're specified. I would have thought
it fairly obvious that passing out of range values to any function that
doesn't explicitly document that it allows them is a bad idea and likely
to result in undefined behavior. The only one that needs to be inferred
is the range for tm_year.
Yes, but calling asctime() with tm_hour==99 and all other members in
their normal ranges *doesn't* invoke undefined behavior, because the
implementation is required to use an algorithm equivalent to the
sample code presented in the standard.

I understand why the definition of asctime() was presented using
sample code, unlike every other function in the standard; it's much
easier to describe it that way than it would be in English. But a
consequence of that decision is that the behavior in the edge cases
can be a bit odd.

(Yes, sample implementations are provided for rand() and srand(), but
an actual implementation isn't required to be equivalent to the
samples.)

In my opinion:

(1) The standard committee should re-open DR 217
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_217.htmand
fix the definition of asctime() so that (a) it remains compatible
with the current definition, and (b) undefined behavior does not
occur for any argument that's a valid pointer to a struct tm;

(2) Implementations should implement asctime() in a way that doesn't
cause an internal buffer overflow, even though the standard
doesn't currently require this (I think this is most safely done
*without* making the buffer bigger); and

(3) Users should either use asctime() very carefully, or should avoid
it in favor of the more versatile strftime().

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 23 '08 #72
Richard Heathfield <rj*@see.sig.invalidwrites:
[followups set to comp.lang.c]
[followups overridden for now, since what I have to say is relevant to
comp.std.c]
Dann Corbit said:
[...]
>I am surprised that you don't see any connection between buffer overruns
and the C language.

I am surprised that you don't see any connection between buffer overruns
and programming languages in general.

If you *can't* overrun a buffer in a given language, then that language
isn't as powerful as it could be and, some would say, as it ought to be.
Safety restrictions, no matter how praiseworthy they may be on their own
merits, nevertheless represent a diminution of freedom and power.
>It's a fundamental defect inherent in its design.

No, it's a fundamental risk inherent in the provision of power - i.e. that
the power might be misused, either through accident or design.

If you want Ada, you know where to find it.
Ada is as powerful as C. It doesn't forbid unsafe actions, it merely
requires you to specify them explicitly in most cases. For example,
to interpret an integer as a pointer (something C allows with a simple
cast), you have to instantiate Unchecked_Conversion and then call the
instance. (Strictly speaking, the C cast performs a type conversion,
not a reinterpretation, but it's implemented as a reinterpretation in
every implementation I've seen.)

It would be nice if C could achieve similar safety in normal use,
while still allowing unsafe constructs that are sometimes necessary in
practice, without changing the language so radically that most
existing code would be broken. I'm skeptical that this is possible,
but I'd be interested in seeing any concrete proposals.

If you want C with Ada-like safety (say, because you really like curly
braces), I think your best bet is to invent a new language.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 23 '08 #73
Mark McIntyre <ma**********@TROUSERSspamcop.netwrites:
ja*********@verizon.net wrote:
>jacob navia wrote:

Oh, god - has Navia hijacked this thread for one of his crusades?
No, he *started* this thread (cross-posted to comp.std.c and
comp.lang.c).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 23 '08 #74
Keith Thompson wrote:
....
(1) The standard committee should re-open DR 217
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_217.htmand
fix the definition of asctime() so that (a) it remains compatible
with the current definition, and (b) undefined behavior does not
occur for any argument that's a valid pointer to a struct tm;
I think that this should be modifed to "a valid pointer to a struct
tm, none of whose members contain a trap representation". For most
implementations, that won't make any difference. However, for
implementations where 'int' has trap representations, ensuring defined
behavior when that condition is not met would be very burdensome.
Jul 23 '08 #75
Followups directed to comp.std.c, since we're now focusing on standard
issues.

ja*********@verizon.net writes:
Keith Thompson wrote:
...
>(1) The standard committee should re-open DR 217
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_217.htmand
fix the definition of asctime() so that (a) it remains compatible
with the current definition, and (b) undefined behavior does not
occur for any argument that's a valid pointer to a struct tm;

I think that this should be modifed to "a valid pointer to a struct
tm, none of whose members contain a trap representation". For most
implementations, that won't make any difference. However, for
implementations where 'int' has trap representations, ensuring defined
behavior when that condition is not met would be very burdensome.
Agreed, good catch.

And saying that "undefined behavior does not occur", as I suggested
above, is hardly sufficient.

Given that the argument is a valid pointer to [see above], I suggest
either:

(a) For any member values for which the behavior of the currently
specified algorithm is undefined, the buffer after asctime()
returns must contain a valid (null-terminated) string; or

(b) If all the member values are within their normal ranges, the
behavior is as currently specified. Otherwise, the buffer after
asctime() returns must contain a valid (null-terminated) string.

The difference is that (b) could change the behavior of code that
depends on the current definition *and* that calls asctime() with
member values outside their normal ranges. The question is whether
this is a problem. I think approach (b) is cleaner, but it could
break some code (that arguably deserves to be broken anyway).

Rather than just "valid", we might want to insist that strlen()
applied to the result returns 25, and that all characters in the
string are printable (see isprint()) except for a mandatory trailing
'\n'. Or it might not be worth being that specific.

And we need to define the "normal range" for tm_year, and specify that
we don't care about the value of tm_isdst.

I think it would also be worth mentioning in a footnote that asctime()
is a legacy function (and perhaps even deprecated), and strftime() is
recommended as a more flexible alternative.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 24 '08 #76
Dann Corbit wrote:
"James Kuyper" <ja*********@verizon.netwrote:
.... snip ...
>
>While many on-topic discussions in comp.std.c are "interesting to
compiler vendors and language designers", the simple fact that an
issue is "interesting to compiler vendors and language designers"
does not make it on-topic for comp.std.c, not even if it's
specifically about C. It has to be about the C standard to be
on-topic.

Where is the newsgroup where discussions about reparing the most
significant defect in the C language are topical?
That would be comp.std.c. Not c.l.c.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Jul 24 '08 #77
jacob navia wrote:
la************@siemens.com wrote:
>Nick Keighley <ni******************@hotmail.comwrote:
>>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.

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!
Pure unmitigated nonsense. The limits are clearly set out in the
description of "struct tm". You would do well to take some time
off and spend it reading the existing standard. As a poor
substitute you could follow my recent postings in c.l.c.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Jul 24 '08 #78
Dann Corbit wrote:
"Richard Heathfield" <rj*@see.sig.invalidwrote
>Dann Corbit wrote:

[snip]
>>The cost is not less than if Grand Coulee dam had broken wide
open and destroyed all property downsteam in the state of
Washington.

Given that Redmond is downstream of that dam, this issue might
not be as simple as at first appears.

Protected by the Cascade mountains, I am afraid.
Surely the combined thought processes of all c.l.c readers can
overcome that minor difficulty? WARNING: It might require taxes.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Jul 24 '08 #79
Keith Thompson wrote:
>
.... snip ...
>
If you want C with Ada-like safety (say, because you really like
curly braces), I think your best bet is to invent a new language.
Or an old one. Try ISO10206.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Jul 24 '08 #80
On Wed, 23 Jul 2008 22:16:21 -0400, CBFalconer wrote:
jacob navia wrote:
>la************@siemens.com wrote:
>>Nick Keighley <ni******************@hotmail.comwrote:
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.

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!

Pure unmitigated nonsense. The limits are clearly set out in the
description of "struct tm".
Please explain how

"int tm_year; // years since 1900"

specifies that tm_year must be between -2899 and 8099. If you can't, but
you do agree that such a limit exists when calling asctime, then obviously
the limits are not clearly set out in the description of "struct tm".
Jul 24 '08 #81
CBFalconer <cb********@yahoo.comwrites:
Keith Thompson wrote:
>>
... snip ...
>>
If you want C with Ada-like safety (say, because you really like
curly braces), I think your best bet is to invent a new language.

Or an old one. Try ISO10206.
ISO 10206 is Extended Pascal. First, it would have been polite to
mention that fact; second, it hardly qualifies as "C with Ada-like
safety".

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 24 '08 #82
On 23 Jul, 15:11, Giacomo Catenazzi <c...@cateee.netwrote:
Nick Keighleywrote:
On 23 Jul, 10:36, jacob navia <ja...@nospam.comwrote:
Zero terminated strings, where there are no bounds checking make it
almost impossible to avoid errors
nonsense. Plenty of C gets written using zero terminated
strings which is perfectly fine.
since it requires from the programmer
never to forget the lengths of buffers!
you can get the program to do that for you
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.

Such libraries permits new types of attack.
I'm assuming the string libraries are based on something like

struct __string
{
size_t __size;
char *__buffer;
};

I don't agree there are new forms of attack. There are old forms of
attack such as corrupting the internal data structures with pointers.
These are probably forms of Undefined Behaviour anyway. They can't
be fixed without severe limits on pointer arithmatic.

I submit that a secure string library *could* be written.
It might not be easy but it could be done. This Design by
Contract.
Actual strings forces reading the memory from
beginning, so strings should terminate earlier
(by a "random" 0 character, or a segmentation fault).
I don't understand the above.
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.
again. I don't understand
OTOH new strings will reduce programmer error, and
thus start of attacks.
yes
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.
maybe
BTW, an alternate string library should really
have a good design, allowing simple plug-in
of i18n, so reducing transition costs.
maybe
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
interesting
--
Nick Keighley

"I wish to God these calculations had been accomplished by steam."
--C. Babbage
Jul 24 '08 #83
Nick Keighley wrote:
On 23 Jul, 15:11, Giacomo Catenazzi <c...@cateee.netwrote:
>Nick Keighleywrote:
>>On 23 Jul, 10:36, jacob navia <ja...@nospam.comwrote:
>>>Zero terminated strings, where there are no bounds checking make it
almost impossible to avoid errors
nonsense. Plenty of C gets written using zero terminated
strings which is perfectly fine.
since it requires from the programmer
never to forget the lengths of buffers!
you can get the program to do that for you
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.
Such libraries permits new types of attack.

I'm assuming the string libraries are based on something like

struct __string
{
size_t __size;
char *__buffer;
};

I don't agree there are new forms of attack. There are old forms of
attack such as corrupting the internal data structures with pointers.
These are probably forms of Undefined Behaviour anyway. They can't
be fixed without severe limits on pointer arithmatic.

I submit that a secure string library *could* be written.
It might not be easy but it could be done. This Design by
Contract.
I agree, secure string library could be written.
I pointed on possible problems on the size based strings.
Which was the part you did not understand (sorry for my
bad English). So I try again.

On C-string, library should all read memory from start to the end.

On Unix, the stack, code, heap, libraries and kernel are in different
memory region.

So a bad c-string will segfault before to change region,
which limits some attacks (or probably at a zero memory
which is found before region change).

With size-based-string, an implementation COULD skip
checking memory ranges and thus allowing easily to access
other memory regions.

Note: in c-string the same attack could be done by changing
the string pointer, so the problem is mainly on starting
an attack, and using only the string data
(removing terminating zero or changing size)
Combining the two method (reading all the memory (or
checking regions/allocation ranges), checking also the
size) would improve security, but the few libraries
I've see, use size also for efficient string maipulation,
without further checking.

ciao
cate
Jul 24 '08 #84
Keith Thompson wrote:
CBFalconer <cb********@yahoo.comwrites:
.... snip ...
>
> [#3] The asctime function returns a pointer to the string.

All of which guarantees no overflows for any legitimate value,
provided only that the year does not exceed 9999, or become
negative. Note that there is no buffer for the user to create.
This is intimately connected with the use of the word 'static'.
[...]

That's correct as far as it goes (though as Harald pointed out,
the value of 9999 can only be derived by studying the code of
the sample implementation). But the "normal ranges" for the
members of struct tm are a *subset* of the values that yield
well-defined behavior for asctime. For example, this rather
bizarre program:
Well, to me that is just normal C behaviour, because the language
doesn't have the ability to define sub-ranges (a la Pascal) for
acceptance. Of course the behaviour you quoted, of compensating
for out-of-range values, is rather hard.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.

Jul 24 '08 #85
In comp.std.c Keith Thompson <ks***@mib.orgwrote:
>
Note also that the struct tm object pointed to by the argument to
mktime is explicitly allowed to have members whose values are outside
their normal ranges. The same permission applies to asctime() simply
because no restriction is given, other than the implicit restriction
to values that don't cause undefined behavior.
I would argue exactly the opposite -- that the explicit permission in mktime
implies that such permission is *not* granted otherwise.
--
Larry Jones

These findings suggest a logical course of action. -- Calvin
Jul 24 '08 #86
la************@siemens.com writes:
In comp.std.c Keith Thompson <ks***@mib.orgwrote:
>Note also that the struct tm object pointed to by the argument to
mktime is explicitly allowed to have members whose values are outside
their normal ranges. The same permission applies to asctime() simply
because no restriction is given, other than the implicit restriction
to values that don't cause undefined behavior.

I would argue exactly the opposite -- that the explicit permission in mktime
implies that such permission is *not* granted otherwise.
I disagree, but I might be willing to be convinced.

An asctime() algorithm equivalent to the one in the standard (which
is what the standard requires) exhibits well-defined behavior with,
for example, time_ptr->tm_day == 32. I see no permission for the
implementation to do anything other than what that code specifies.

The only argument I can see that the behavior might be undefined
is 7.1.4p1:

If an argument to a function has an invalid value (such as a
value outside the domain of the function, or [snip]) or [snip],
the behavior is undefined.

(The snipped text doesn't apply in this case.)

But 7.23.1p4 defines the "normal ranges" for the members of struct
tm. You'd have to assume that anything outside the "normal range"
is an "invalid value" -- but normality and validity are not the
same thing.

Note that the standard does explicitly state that the characters
stored by strftime() are undefined if any members have values outside
the normal range, and this is listed under "Unspecified behavior"
in J.1 (which is non-normative). This doesn't tell us anything
definitive, but it is suggestive.

I think the term "normal ranges" refers, not to the ranges of
values the members are *permitted* to have, but to the ranges of
values that will be set by localtime() and gmtime() -- though it
would have been nice if that had been stated explicitly.

None of the other uses of the word "normal" in the standard are
useful for resolving this.

Now I think that it would have made more sense for the standard
to say that the behavior of calling asctime() with values outside
the "normal ranges" is undefined (as it does for strftime()).
But since the authors of the standard chose to define the behavior of
asctime() by presenting an explicit implementation in C source code,
I think we're stuck with the behavior of that code (except that an
implementation can do what it likes in cases where the behavior of
the sample code is undefined).

I think the real problem is that the standard fails to define
what it means by "normal range".

But feel free to convince me that anything outside the "normal range"
is an "invalid value".

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 24 '08 #87
<la************@siemens.comwrote in message
news:dg************@jones.homeip.net...
In comp.std.c Keith Thompson <ks***@mib.orgwrote:
>>
Note also that the struct tm object pointed to by the argument to
mktime is explicitly allowed to have members whose values are outside
their normal ranges. The same permission applies to asctime() simply
because no restriction is given, other than the implicit restriction
to values that don't cause undefined behavior.

I would argue exactly the opposite -- that the explicit permission in
mktime
implies that such permission is *not* granted otherwise.
No, the explicit permission is necessary because without it, the behaviour
of mktime() would be undefined by omission when the values are outside of
their "normal" ranges. To avoid undefined behaviour when the values do not
represent a valid date and time, the text needs to explain how such values
are interpreted, and mentioning that they're allowed is a reasonable
introduction to such an explanation. Given that that's a sufficient
justification for the explicit permission being there, there's no reason to
assume that its purpose might *also* be to imply that values outside of
their "normal" ranges are forbidden everywhere else.

(Unfortunately, even though the explicit perrmision makes it clear that the
standard wants to avoid undefined behaviour, I don't feel that it's doing a
very good job of defining the behaviour. What exactly does it mean that the
components of the structure "are set to represent the specified calendar
time, but with their values forced to the ranges indicated above"? What
date is "specified" by setting tm_mon to 12 and tm_mday to 50 -- is it
supposed to be obvious that it's referring to 19 February of the following
year? Or are the values "forced" into their "normal" ranges *before* being
interpreted as specifying a calendar time, and therefore my example really
specifies the 31th of December?)

Anyway, no such issue exists for asctime(). Its behaviour is defined
without depending on whether the values in the structure represent a valid
calendar time or not.

Jul 24 '08 #88
Mark McIntyre <ma**********@TROUSERSspamcop.netwrites:
Friedrich wrote:
>Bart van Ingen Schenau <Ba********************@ict.nlwrites:
>>So, why do people complain all the time about the possibility of
buffer overflows in C, but not in other languages?
>because that kind of errors plagues C programs mostly?

Perhaps thats because more programmes have been written in C than any
other language?
And C is easier to learn (and therefore has more novice
programmers)?
Well C is not especially hard to learn but applying it is. But I would
dare to day that most "scripting" languages are easier to learn. And I
can not convince myself that e.g Smalltalk is harder than C.
>
By the way, we are potentially now into the "safety by obscurity"
model here which as any fule no is spurious. Plan-9 is safe because
only experts use it...
Well some arguments here a more than strange. Some wrote every
language is equally unsafe because there might be a buffer
overrun. Howerver AFAIKT I just remember one recent problem with
buffer overruns in a certain Interpreter (written in C). I can not
remember having read about it let's say in Ocaml, Haskell or even
FreePascal. I can not see how one can deny that not doing bounds
checking can be safer than the other way. I can also not see why the
standard shouldn't be checking and just on occasion you have something
like
#pragma unsafe or the like to play your "nasty" tricks.

If that all wouldn't be a problem than this hardly would be worth a
discussion. But those bugs do exist and they do mainly exist in C and
C++. So I do see more as a specific language problem than a general
problem.

And strange enough there is a flourishing industry for that all kinds
of tools for handling this problem. Just let's name few, dmalloc,
libfence, valgrind, splint and tons of others. So that is a very
strong indicator for this kind of weakness for me.
Regards
Friedrich

--
Please remove just-for-news- to reply via e-mail.
Jul 25 '08 #89
Friedrich wrote:
>
.... snip ...
>
Well some arguments here a more than strange. Some wrote every
language is equally unsafe because there might be a buffer
overrun. Howerver AFAIKT I just remember one recent problem with
buffer overruns in a certain Interpreter (written in C). I can
not remember having read about it let's say in Ocaml, Haskell or
even FreePascal. I can not see how one can deny that not doing
bounds checking can be safer than the other way. I can also not
see why the standard shouldn't be checking and just on occasion
you have something like
#pragma unsafe or the like to play your "nasty" tricks.
C can't have run-time checking without horrendous loss of
efficiency (basically it would require interpretation) because of
the unrestricted use of pointers. There is no destinction between
a pointer to a char, and a pointer to an array of 10,000 chars.
One may be created from the other at any time. In addition
malloced storage is not distinguished in any way (except some usage
aspects) from any other storage. All this requires that every
pointer carry with it information of max and min indices allowable
for use.

There are programming advantages to this freedom, but they have to
be used with care. Most often the care is missing.

To have safe code, all you have to do is switch languages. Pascal
and Ada are much safer. No language is completely safe. Good C
requires first class programmers. Most often it doesn't get them.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Jul 25 '08 #90
CBFalconer wrote:
Friedrich wrote:
... snip ...
>Well some arguments here a more than strange. Some wrote every
language is equally unsafe because there might be a buffer
overrun. Howerver AFAIKT I just remember one recent problem with
buffer overruns in a certain Interpreter (written in C). I can
not remember having read about it let's say in Ocaml, Haskell or
even FreePascal. I can not see how one can deny that not doing
bounds checking can be safer than the other way. I can also not
see why the standard shouldn't be checking and just on occasion
you have something like
#pragma unsafe or the like to play your "nasty" tricks.

C can't have run-time checking without horrendous loss of
efficiency (basically it would require interpretation) because of
the unrestricted use of pointers.

This is plainly not true. Each access to an array would
have two reads from memory + two integers comparisons
to do. Progress in hardware make such tests completely
transparent. And nobody is saying they should be anything
more than optional.

There is no destinction between
a pointer to a char, and a pointer to an array of 10,000 chars.
One may be created from the other at any time.
???? What is this???
In addition
malloced storage is not distinguished in any way (except some usage
aspects) from any other storage. All this requires that every
pointer carry with it information of max and min indices allowable
for use.
This is called "fat" pointers. Yes, they carry size information
and what is wrong with that?
There are programming advantages to this freedom, but they have to
be used with care. Most often the care is missing.

To have safe code, all you have to do is switch languages. Pascal
and Ada are much safer. No language is completely safe. Good C
requires first class programmers. Most often it doesn't get them.
This is the old elitist argument much in vogue here in comp.lang.c

"We are geniuses, the others are just bad/lazy programmers".

They concept of "error prone" tool doesn't get into their minds

--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Jul 25 '08 #91
On Wed, 23 Jul 2008 09:55:33 +0000, Richard Heathfield posted:
Willem said:
>Richard Heathfield wrote:
) [followups set to comp.lang.c]
)
) jacob navia said:
)
)Ron Ford wrote:
)<snip>
)>>
)>I'm somewhat of a non-believer here. There is no calculus to decide.
)>>
)>
)Well, mathematics doesn't need beliefs.
)
) It needs a few. They are called axioms.

A mathematician doesn't need to believe in the correctness his axioms.

Fair point - they're more sort of meta-beliefs, aren't they? IF we believe
THESE things, then THOSE are the consequences...
That is how the crab argues with Achilles. A lot of folks think that the
strength of C is its blinding speed; they aren't wrong, but logicians have
their say.

The most unsatisfying axioms I ever read were in Analysis I or Calculus IV.
The ultimate one assumed that the last century in mathematics didn't
happen.
--
We must be willing to pay a price for freedom. 4
H. L. Mencken
Jul 25 '08 #92
jacob navia wrote:
Bart van Ingen Schenau wrote:
>So, why do people complain all the time about the possibility of
buffer overflows in C, but not in other languages?

Bart v Ingen Schenau

Because functions like gets() asctime() and other standard
functions (still in C99 standard even if gets() got deprecated)
make buffer overflows almost MANDATORY.
I don't think anyone these days ever uses gets().
Zero terminated strings, where there are no bounds checking make it
almost impossible to avoid errors since it requires from the
programmer never to forget the lengths of buffers!
IME it's a lot more bookkeeping, but I wouldn't say that it is "almost
impossible". The size of each and every object must be known at some
point in a program, and that information need only be carefully and
logically preserved and used each time the object is accessed.
I have proposed a string library for C to make those errors more
difficult. The reception was as expected... :-(
When did you propose this? If you had made operator overloading an
integral part of this proposal, then not many would've been every
enthusiastic since operator overloading is not supported by nearly all
the C compilers out there.

OTOH a counted strings interface based on the existing infrastructure of
C like BStrlib would not be an unwelcome addition to C1x, IMHO.

Jul 25 '08 #93
jacob navia wrote:
Keith Thompson wrote:
>jacob navia <ja***@nospam.comwrites:
>>Nick Keighley wrote:
On 23 Jul, 10:36, jacob navia <ja...@nospam.comwrote:
Bart van Ingen Schenau wrote:
>So, why do people complain all the time about the possibility of
>buffer overflows in C, but not in other languages?
>>
Because functions like gets() asctime() and other standard
functions (still in C99 standard even if gets() got deprecated)
make buffer overflows almost MANDATORY.
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.

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:
By your logic we could say that the Standard allows potential buffer
overruns with memcpy, memmove, strcpy, strcat, fread, fgets and so.

I think you may be happier with a language other than C.
>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?
Let me turn the tables and ask you jacob that as an outspoken
implementor (and critic) of ISO C, why not arrange for your lcc-win to
emit a diagnostic for any use of asctime (and perhaps of other
functions that you deem as unsafe)? As far as I can see my recent copy
your compiler emits no helpful warnings upon the usage of "dangerous"
functions like gets and asctime and others. Gcc for example emits a
diagnostic for gets and tmpnam among others. It is not as good as
remedy at the source, but it's nonetheless helpful.

It would be good to see you judging yourself with the same high
standards with which you judge others.

<snip>

Jul 25 '08 #94
CBFalconer <cb********@yahoo.comwrites:
Friedrich wrote:
>>
... snip ...
>>
Well some arguments here a more than strange. Some wrote every
language is equally unsafe because there might be a buffer
overrun. Howerver AFAIKT I just remember one recent problem with
buffer overruns in a certain Interpreter (written in C). I can
not remember having read about it let's say in Ocaml, Haskell or
even FreePascal. I can not see how one can deny that not doing
bounds checking can be safer than the other way. I can also not
see why the standard shouldn't be checking and just on occasion
you have something like
#pragma unsafe or the like to play your "nasty" tricks.

C can't have run-time checking without horrendous loss of
efficiency (basically it would require interpretation)
Basically I think that is not true whatsoever. It needs run time
checks. Many of which can be very, very efficient depending on the HW
and compiler involved.
Jul 25 '08 #95
CBFalconer <cb********@yahoo.comwrote:
Friedrich wrote:
Well some arguments here a more than strange. Some wrote every
language is equally unsafe because there might be a buffer
overrun. Howerver AFAIKT I just remember one recent problem with
buffer overruns in a certain Interpreter (written in C). I can
not remember having read about it let's say in Ocaml, Haskell or
even FreePascal. I can not see how one can deny that not doing
bounds checking can be safer than the other way. I can also not
see why the standard shouldn't be checking and just on occasion
you have something like
#pragma unsafe or the like to play your "nasty" tricks.

C can't have run-time checking without horrendous loss of
efficiency (basically it would require interpretation) because of
the unrestricted use of pointers. There is no destinction between
a pointer to a char, and a pointer to an array of 10,000 chars.
Oh, bollocks. C certainly allows fat pointers. The only thing you need
to keep is:
- base pointer to block;
- size of block, in bytes;
- offset of pointer in block, in bytes;
- type of pointer.

_Nothing_ in that requires interpretation. It does add overhead, that's
true, and that is a very valid reason for most C implementation not to
use fat pointers. However, bounds-checking compilers are not only
allowed but do, IIRC, in fact exist. Such an implementation is, of
course, slower; but not "horrendously" so.
To have safe code, all you have to do is switch languages.
Or brains.

Richard
Jul 25 '08 #96
Keith Thompson <ks***@mib.orgwrote:
Richard Heathfield <rj*@see.sig.invalidwrites:
If you want Ada, you know where to find it.

Ada is as powerful as C. It doesn't forbid unsafe actions, it merely
requires you to specify them explicitly in most cases. For example,
to interpret an integer as a pointer (something C allows with a simple
cast), you have to instantiate Unchecked_Conversion and then call the
instance. (Strictly speaking, the C cast performs a type conversion,
not a reinterpretation, but it's implemented as a reinterpretation in
every implementation I've seen.)
In other words, Ada requires a special construct to be applied to
interpret an integer as a pointer; C, by contrast, requires a special
construct to be applied to interpret an integer as a pointer. Apart from
the size of the construct, I see no difference.

Richard
Jul 25 '08 #97
CBFalconer <cb********@yahoo.comwrote:
Keith Thompson wrote:
If you want C with Ada-like safety (say, because you really like
curly braces), I think your best bet is to invent a new language.

Or an old one. Try ISO10206.
No; Keith was looking for Ada with a C-like syntax, while what you
suggest is Algol with a BASIC-like syntax.

Richard
Jul 25 '08 #98
rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
Keith Thompson <ks***@mib.orgwrote:
>Richard Heathfield <rj*@see.sig.invalidwrites:
If you want Ada, you know where to find it.

Ada is as powerful as C. It doesn't forbid unsafe actions, it merely
requires you to specify them explicitly in most cases. For example,
to interpret an integer as a pointer (something C allows with a simple
cast), you have to instantiate Unchecked_Conversion and then call the
instance. (Strictly speaking, the C cast performs a type conversion,
not a reinterpretation, but it's implemented as a reinterpretation in
every implementation I've seen.)

In other words, Ada requires a special construct to be applied to
interpret an integer as a pointer; C, by contrast, requires a special
construct to be applied to interpret an integer as a pointer. Apart from
the size of the construct, I see no difference.
The difference is that the "special construct" in C, a cast doesn't
stand out. It's the same construct used to for perfectly safe type
conversions, such as a conversion from int to long.

There *should* be few casts in well-written C code, but unfortunately
that's not the case in real-world code. So to some small extent,
perhaps the difference is more in how C is used than in how it's
designed -- though there are still plenty of ways to do dangerous
things in C without trying very hard.

I can see this turning into a language war, so perhaps we should drop
this sub-thread.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 25 '08 #99
In article <g6**********@aioe.org>, jacob navia <ja***@nospam.orgwrote:
>CBFalconer wrote:
>C can't have run-time checking without horrendous loss of
efficiency (basically it would require interpretation) because of
the unrestricted use of pointers.
>This is plainly not true. Each access to an array would
have two reads from memory + two integers comparisons
to do. Progress in hardware make such tests completely
transparent.
"Progress in hardware" ?? Sounds to me like the old VAX scheme,
where a "pointer" was really a reference to a memory descriptor.

If I recall my history correctly, the people who implemented
the official C for VAX/VMS really tried to adhere to that
architecture, but eventually had to get an operating system
modification to allow the compiled programs to use plain addresses
rather than descriptors.

As best I recall, their plans to use descriptors fell down because of
type punning. For one thing, every malloc'd byte must be accessible
under the definition of malloc, but "objects" get carved up out of
malloc'd space: do you follow the semantics that the bytes are all
accessible because they are part of the malloc'd object, or do you
follow the semantics that the bytes before/after an sub-object
are inaccessible because C says accessing outside of objects is
undefined behaviour? If you have a plain int (for example) and you
pass its address to a subroutine, then *(ptr+1) should trigger
bounds exception processing, but if the space for the int was
part of a malloc'd area then you are really talking about an array
of int's and *(ptr+1) must work [if you stay within the area.]

Even without dynamic memory, it is common (especially in older
C routines that were written to take on mathematical processing
subplanting FORTRAN), to pass in a 1D array but then to use it
internally as a 2D array. Bounds checking based upon the
1D descriptor from when the memory area was created needs to be
flexible enough to handle that kind of type punning, without C
having the semantics to convey to lower level routines how big
something should be. If you do a 1D to 2D punning and then
you pass to a lower routine the address of the first row, intending
only to denote the row, the lower level routine doesn't have
a way to know that an access outside the row but still within
the block should be caught -- as far as the lower level routine
is concerned, you might have wanted to type-pun back to the
entire 1D array. And indeed, I have encountered C code that did
flip back and forth between 1D and 2D at different call depths
(e.g., you might have done a 2D matrix operation and then want
to take the absolute value of all of the elements; taking the
absolute value row-by-row would be less efficient than taking
the absolute element of the entire block as a 1D vector.)

There are languages in which arrays or array slices are "first
class objects", for which hardware bounds checking makes perfect sense.
Unfortunately, C isn't one of those languages, and people *do*
take advantage of the type laxity in real programs; changing the rules
now would have serious issues with backwards compatability.
--
"Beauty, like all other qualities presented to human experience,
is relative; and the definition of it becomes unmeaning and
useless in proportion to its abstractness." -- Walter Pater
Jul 25 '08 #100

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

15
by: Nick Coghlan | last post by:
Thought some folks here might find this one interesting. No great revelations, just a fairly sensible piece on writing readable code :) The whole article:...
16
by: makko | last post by:
Hello, anyone know how to writre a program that take a commandline formula and prints the calculated result? example; $program 1+(2x3(3/2))-8 reagrds; Makkko
3
by: Alvin Bruney [MVP] | last post by:
I have two managed windows applications A and B. Both have their own config files. Application A invokes application B thru process start. However, since B runs in A's context, B starts up and...
2
by: natG | last post by:
On a 3 column table, the PK consists of all 3 columns. I have queries on the first two columns, as well as on the last two columns. (Select * where column3=x and column2=y.) I was hoping that...
40
by: nufuhsus | last post by:
Hello all, First let me appologise if this has been answered but I could not find an acurate answer to this interesting problem. If the following is true: C:\Python25\rg.py>python Python...
12
by: Mike | last post by:
Hi I am wonderinf if there are interesting examples to learn C. Or any good idea? Mike
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.