Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Is it time for secure C ?

Reply
Thread Tools

Is it time for secure C ?

 
 
Roman Ziak
Guest
Posts: n/a
 
      07-07-2004
Hello,

I just downloaded MS Visual Studio 2005 Express Beta. When I tried to
compile existing valid project, I get a lot of warnings like 'sprintf'
has been deprecated, 'strcpy' has been deprecated etc. I opened STDIO.H
and figured that one has to define a macro _CRT_SECURE_NO_DEPRECATE
to stop these warnings.

I started to search internet and found few links, and the following proposal

http://www.open-std.org/jtc1/sc22/wg...docs/n1031.pdf

After looking into Whidbey Beta header files I started liking this. This is
something I have been using already for static and local buffers using
macro with strncpy() and vsnprintf(), only this is better.

Although this feature should be invoked by defining _USE_SECURE_LIBS
and not be used by default, that's easy to fix in CRTDEFS.H.

Anyway, I am just wondering if anybody knows about the status of this
proposal. And also would like to read some opinions.

Roman


 
Reply With Quote
 
 
 
 
jacob navia
Guest
Posts: n/a
 
      07-07-2004
This is very good. I have been arguing in this group against the situation
in C where
unsecure programming is the rule. This means that things can change.

In lcc-win32, after a discussion about C strings in this group, I developed
a secure
string library, that is distributed with the compiler.

The Microsoft proposal goes in this direction, albeit it leaves to the
programmer
the work of always specifying correctly the block size. I posted in
comp.lang.lcc
an article proposing the usage of *bounded* pointers, that would solve the
problem of strings and other related problems.

jacob

http://www.cs.virginia.edu/~lcc-win32


 
Reply With Quote
 
 
 
 
Vijay Kumar R Zanvar
Guest
Posts: n/a
 
      07-07-2004

"jacob navia" <(E-Mail Removed)> wrote in message news:ccg6j4$672$(E-Mail Removed)...
[..]
> the work of always specifying correctly the block size. I posted in
> comp.lang.lcc


There is no such group by this name. ITYM, news:comp.compilers.lcc


 
Reply With Quote
 
jacob navia
Guest
Posts: n/a
 
      07-07-2004
Yes, sorry about the confusion!


 
Reply With Quote
 
Richard Bos
Guest
Posts: n/a
 
      07-07-2004
"jacob navia" <(E-Mail Removed)> wrote:

[ Please, leave _some_ context. ]

> This is very good. I have been arguing in this group against the situation
> in C where unsecure programming is the rule.


It isn't. Insecure programming is the rule anywhere rank amateurs or
poor professionals program in any language; it is not the rule where
real professionals or dedicated amateurs program, in C no more than in
Ada.

> In lcc-win32, after a discussion about C strings in this group, I developed
> a secure string library, that is distributed with the compiler.


Which, of course, is off-topic here.

> The Microsoft proposal goes in this direction,


It is a dreadful solution, but one of the kind which is entirely
expected of those embrace-extend-and-massively-abuse artists.

> I posted in comp.lang.lcc an article proposing the usage of *bounded* pointers,


There is a newsgroup especially for lcc? That's great! That means you
won't have to post off-topic material in comp.lang.c anymore, and we
won't have to bother you with our requests for topicality anymore. Now,
all that remains is for you to post lcc-specific material there, and ISO
C material here...

Richard
 
Reply With Quote
 
Guillaume
Guest
Posts: n/a
 
      07-07-2004
> I just downloaded MS Visual Studio 2005 Express Beta. When I tried to
> compile existing valid project, I get a lot of warnings like 'sprintf'
> has been deprecated, 'strcpy' has been deprecated etc. I opened STDIO.H
> and figured that one has to define a macro _CRT_SECURE_NO_DEPRECATE
> to stop these warnings.


1. And what exactly makes you think that any Microsoft's tantrum is
going to mean anything valid in the C world?

2. Since when Microsoft is a well known authority for secure
programming? There is so much evidence of the opposite,
it's somewhat boggling...

3. So according to them, sprintf, strcpy and the like have
been deprecated? How presumptuous.

4. They seem to keep thinking that software quality is going to be
achieved with software tools for incompetent programmers. I don't
think this is ever going to work.

5. I have heard of Visual Studio 2005, and it sounds like this
new release doesn't give anything more than hypothetical improved
"programming security". Sounds more like marketing than engineering
to me.


"Secure C" in itself doesn't exist any more than a "secure car".
If you can't drive, no amount of so-called technology is going
to change the fact that you're dangerous behind the wheel - except
if you're not actually driving it yourself. Is that where Microsoft
wants the profession to be heading?
 
Reply With Quote
 
Arthur J. O'Dwyer
Guest
Posts: n/a
 
      07-07-2004

On Wed, 7 Jul 2004, Roman Ziak wrote:
>
> I just downloaded MS Visual Studio 2005 Express Beta. When I tried to
> compile existing valid project, I get a lot of warnings like 'sprintf'
> has been deprecated, 'strcpy' has been deprecated etc. I opened STDIO.H
> and figured that one has to define a macro _CRT_SECURE_NO_DEPRECATE
> to stop these warnings.


(This sounds like typical Microsoft behavior. Ick.)


> I started to search internet and found few links, and the following
> proposal
> http://www.open-std.org/jtc1/sc22/wg...docs/n1031.pdf


This is a somewhat interesting proposal, and one I hadn't seen
before (at least, not in such a standardese-specified way). It
doesn't strike me as particularly useful. Read on.


The 'scanf_s' family of functions is slightly broken, from the
implementor's point of view. Consider Example 2 in section 3.2.2.1:

EXAMPLE 2 The call:
#define __USE_SECURE_LIB__
#include <stdio.h>
/* ... */
int n; char s[5];
n = fscanf_s(stdin, "%s", s, sizeof s);
with the input line:
hello
will assign to 'n' the value 0 since a matching failure occurred
because the sequence 'hello\0' requires an array of six characters
to store it. No assignment to 's' occurs.

In other words, the implementation of 'scanf_s' requires a lookahead
buffer of at least N characters, where N is some value specified by the
user at runtime. This is certainly possible (especially with C99 VLAs
at the implementor's disposal), but is the proposed "security" worth
the inconvenience?

(There's also the issue of what happens when the programmer passes
a 'size_t' argument to a variadic function; I forget exactly what is
supposed to happen, but the integer promotions definitely don't help.
Maybe this is a non-issue in this case, though.)

The 'gets_s' function is exactly equivalent to the existing 'fgets'
function, except that it discards the *USEFUL* end-of-line indicator,
which is the only thing that can tell the program that a full line
has indeed been read. 'gets_s' is thus *WORSE* than nothing! (Though
it's not as bad as 'gets'.

The 'rand_s' function would be absolutely a godsend... if the
author had bothered to specify its behavior!


The 'bsearch_s' function is interesting, but of course it doesn't
add any functionality to the library that didn't already exist in C99
(I don't know whether C90 guaranteed that 'key' would always be the
first argument to 'compar'). And it has *nothing* to do with
security, so it's a little silly to attach it as a "rider" onto the
main proposal.

The 'qsort_s' function is no better than the existing 'qsort'; it
guarantees neither O(NlgN) sorting time nor stable sorting. What
it *does* do is add unnecessary complexity; perhaps the 'context'
argument is an alternative to "locales" in C99? I don't know. It's
certainly not any improvement on the existing C99 functions.

And from the security POV, the author completely forgot to address
the major security hole in both functions: they take two 'size_t'
parameters, right next to each other, and I never remember which
is which. The compiler is never smart enough to help, either. So
this is a potential source of major hard-to-find bugs in C programs,
and the proposed "secure" library doesn't even address the issue!


'memcpy_s(foo, n, bar, n)' replaces the existing 'memcpy(foo, bar, n)',
and likewise 'memmove'. Extra verbosity, no security gain. Bad idea.

In practice, 'strncpy_s' now performs exactly the same function as
'memcpy_s'; ironically, the historical extra security of filling the
array out with NUL bytes is removed!

'strlen_s' is interesting, but I hardly think it's useful for its
intended purpose; after all, wasn't the whole point of this string
library proposal so that all strings *would* have well-defined lengths,
thus making the existing 'strlen' perfectly safe?


In conclusion, I think it's pretty ironic that the proposal begins
with the paragraph

Traditionally, the C Library has contained many functions that trust
the programmer to provide output character arrays big enough to hold
the result being produced. Not only do these functions not check that
the arrays are big enough, they frequently lack the information needed
to perform such checks. While it is possible to write safe, robust,
and error-free code using the existing library, the library tends to
promote programming styles that lead to mysterious failures if a
result is too big for the provided array.

when all it does is provide even *more* functions that require "big
enough" character arrays with programmer-specified values, thus promoting
the "mysterious failure" programming style it claims to be trying to
avoid!

> Anyway, I am just wondering if anybody knows about the status of this
> proposal. And also would like to read some opinions.


I hope this was useful to you.

-Arthur
 
Reply With Quote
 
Malcolm
Guest
Posts: n/a
 
      07-07-2004

"Richard Bos" <(E-Mail Removed)> wrote in message
>
> It isn't. Insecure programming is the rule anywhere rank amateurs or
> poor professionals program in any language; it is not the rule where
> real professionals or dedicated amateurs program, in C no more than in
> Ada.
>

C makes it very easy to address memory illegally. This problem can be solved
by using another language, at the cost of some runtime inefficiency and loss
of simplicity.
What no language and no compiler can solve is the logic error. If I am
writing control software for an aircraft, and I accidentally use a sine
rather than a cosine in some vital calculation, it will not be picked up
except through testing, or when the aeroplane crashes.



 
Reply With Quote
 
Jeremy Yallop
Guest
Posts: n/a
 
      07-07-2004
Arthur J. O'Dwyer wrote:
> On Wed, 7 Jul 2004, Roman Ziak wrote:
>> I started to search internet and found few links, and the following
>> proposal
>> http://www.open-std.org/jtc1/sc22/wg...docs/n1031.pdf

[...]
> The 'bsearch_s' function is interesting, but of course it doesn't
> add any functionality to the library that didn't already exist in C99
> (I don't know whether C90 guaranteed that 'key' would always be the
> first argument to 'compar').


It did.

> The 'qsort_s' function is no better than the existing 'qsort'; it
> guarantees neither O(NlgN) sorting time nor stable sorting. What
> it *does* do is add unnecessary complexity; perhaps the 'context'
> argument is an alternative to "locales" in C99? I don't know. It's
> certainly not any improvement on the existing C99 functions.


I agree with much of what you wrote, but I think you've overlooked the
usefulness of the `context' argument. In my experience, a `context'
argument is an essential part of any properly-designed interface
involving a callback function, allowing customization of the behaviour
of the comparison function at runtime. The lack of it is, I think,
the one major defect in the specification of qsort().

An example is perhaps the easiest way to show this: suppose you want
to sort an array of elements of structure type:

struct element {
int id;
char strings[3];
} elements[] = { ... };

Further, you want to allow sorting by a particular member, say
strings[0], strings[1] or strings[2], and to provide the option of
sorting in forward or reverse. One way to do this is to provide two
separate comparison functions for each possibility:

int compare_zero(const void *l, const void *r)
{
const struct element *left = l, *right = r;
return strcmp(left->strings[0], right->strings[0]);
}

int compare_one(const void *l, const void *r)
{
const struct element *left = l, *right = r;
return strcmp(left->strings[1], right->strings[1]);
}

int compare_two(const void *l, const void *r)
{
const struct element *left = l, *right = r;
return strcmp(left->strings[2], right->strings[2]);
}

int compare_r_zero(const void *l, const void *r)
{
const struct element *left = l, *right = r;
return - strcmp(left->strings[0], right->strings[0]);
}

int compare_r_one(const void *l, const void *r)
{
const struct element *left = l, *right = r;
return - strcmp(left->strings[1], right->strings[1]);
}

int compare_r_two(const void *l, const void *r)
{
const struct element *left = l, *right = r;
return - strcmp(left->strings[2], right->strings[2]);
}

The appropriate comparison function can then be selected at runtime by
an if-else ladder, or an array of pointers to the functions, etc.
Duplicating the comparison code in this way is pretty inelegant,
though, besides being a maintenance burden. Obviously, it's desirable
to replace the almost-identical functions above with a single
function, and parameterize the hard-coded indexes and minus operator.

int compare(const void *l, const void *r)
{
const struct element *left = l, *right = r;
return sign * strcmp(left->strings[index], right->strings[index]);
}

The question, of course, is "Where do `sign' and `index' come from?
They could be global variables, but this is undesirable for a number
of reasons: giving up thread safety, re-entrancy, modularity, etc.
The ideal thing would be to pass them as parameters, but qsort()
provides no mechanism for doing this: the signature of the comparison
function is fixed, and only allows two arguments to be passed. Now, I
hope, the purpose of the `context' parameter starts to become clear.
We can pass data of any type through `context', so the single function
becomes easy to write:

struct context
{
int sign;
int index;
};
int compare_ctxt(const void *l, const void *r, void *context)
{
const struct element *left = l, *right = r;
return context->sign * strcmp(left->strings[context->index],
right->strings[context->index]);
}

Having dispensed with the plethora of functions, there's no longer any
need for a runtime selection of comparison function, so the code that
invokes qsort() (or rather, qsort_s()) becomes much simpler as well.
Borrowing some syntax from C99:

qsort_s(elements,
sizeof elements / sizeof elements[0],
sizeof elements[0],
&(struct context){direction, index});

This is essentially the same as the concept of a "closure" in more
functionally-inclined languages, albeit quite a bit more explicit.

Jeremy.
 
Reply With Quote
 
Arthur J. O'Dwyer
Guest
Posts: n/a
 
      07-07-2004

On Wed, 7 Jul 2004, Jeremy Yallop wrote:
>
> Arthur J. O'Dwyer wrote:
> > On Wed, 7 Jul 2004, Roman Ziak wrote:
> >> http://www.open-std.org/jtc1/sc22/wg...docs/n1031.pdf

<snip>
> > The 'qsort_s' function is no better than the existing 'qsort'; it
> > guarantees neither O(NlgN) sorting time nor stable sorting. What
> > it *does* do is add unnecessary complexity; perhaps the 'context'
> > argument is an alternative to "locales" in C99? I don't know. It's
> > certainly not any improvement on the existing C99 functions.

>
> I agree with much of what you wrote, but I think you've overlooked the
> usefulness of the `context' argument. In my experience, a `context'
> argument is an essential part of any properly-designed interface
> involving a callback function, allowing customization of the behaviour
> of the comparison function at runtime. The lack of it is, I think,
> the one major defect in the specification of qsort().


[Snip example: sorting structs by fields 0,1,2, forward and reverse]

> qsort_s(elements,
> sizeof elements / sizeof elements[0],
> sizeof elements[0],
> &(struct context){direction, index});


Yes, I recognized that this was the intended usage, I just didn't
see any good reason to want to do this. You say you've had reason to
do this before? Well, perhaps it is useful, then, just not to me.

I would pessimistically think the effort spent initializing
'direction' and 'index' ("on location," before each and every call
to the "contextual" qsort) would often exceed the amount of effort needed
to write six or seven specialized comparison functions in the first
place.

> This is essentially the same as the concept of a "closure" in more
> functionally-inclined languages, albeit quite a bit more explicit.


Yup.

-Arthur
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Secure your digital information assets with Secure Auditor. SecureWindows with Secure Auditor alannis.albert@googlemail.com Cisco 0 04-14-2008 06:53 AM
Secure your digital information assets with Secure Auditor SecureWindows with Secure Auditor alannis.albert@googlemail.com Cisco 0 04-14-2008 06:52 AM
Is time.time() < time.time() always true? flamesrock Python 8 11-24-2006 06:51 AM
This page contains both secure and non secure items. A.M ASP .Net 5 06-08-2004 05:43 PM



Advertisments