views:

467

answers:

8

Hi!

I recently finished a university course in C. Therefore I lack experience, of course.

Some universities tend to teach their students secure programming, or at least some elements. There's even a video (taken from here).

Being in C, copying strings, requires - as far as I know - strcpy or string.h functions. How do you use it securely in every-day programming? Do you have some functions, which handle allocation to prevent buffer overflows? There's the CERT secure coding standard for C. It's offering examples and compliant solutions:

int main(int argc, char *argv[]) {
  /* ... */
  char prog_name[128];
  strcpy(prog_name, argv[0]);
  /* ... */
}

And their alternative is:

int main(int argc, char *argv[]) {
  /* ... */
  char *prog_name = (char *)malloc(strlen(argv[0])+1);
  if (prog_name != NULL) {
    strcpy(prog_name, argv[0]);
  }
  else {
    /* Couldn't get the memory - recover */
  }
  /* ... */
}

Taken from here, 2nd example.

But as far as I get it that's just more challenging, more code, more work. Why does no one change the library itself? Or at least why does no one provide a secure alternative library or functions, which handle this in the right way?

Thanks for reading, wishi

A: 

Actually, Microsoft did provide secure alternatives to the CRT functions. Everybody I know hates them though and disables the warning that you shouldn't use the old functions. If you want something secure, maybe you should use C++. And then either STL strings or something like Qt.

Well, or you go to platforms like .NET or Java, which usually doesn't suffer from these problems (your app might crash, but no way to inject code into your app through a buffer overflow).

Edit: With Data Execution Prevention / NX enabled (default for Vista and .NET), this shouldn't be a problem for traditional platforms as well.

OregonGhost
Using C++ does not magically stop all buffer overflows and the problems they cause.
Thomas Owens
Having strdup avaialble doesn't stop buffer overflows either, when people continue to use malloc/strcpy with fixed lengths. C++ offers, but does not enforce alternatives. Code reviews - which you need anyway - can enforce the use of those alternatives.
MSalters
@Thomas: I meant what MSalters wrote. C++ offers many secure alternatives to the plain old CRT functions, and that alone is in my opinion a reason to switch.
OregonGhost
-1 for saying DEP/NX remove the problem... they don't.
Longpoke
@Longpoke: I meant to say that DEP/NX protects you from code injection via buffer overflow, just like managed platforms do anyway. I did not say that DEP/NX prevent buffer overflows in general.
OregonGhost
DEP/NX are mitigation at best. They have been bypassed before, and even when you can't bypass them, there are other things you can do like setting up a call to an arbitrary function on the stack.
Longpoke
+10  A: 

The Posix function for this (available on nearly every system) is strdup(). strcpy() is used if you don't want to allocate new memory and already have a buffer you want to use, but then you better known how big that buffer is and if the string fits in it. If you don't know if the string fits, there is strncpy() that just copies a given number of characters. So you can limit the copied amount to your buffers size.

And besides of that, there are lots of sting libraries that manage string sizes in different ways.

And since you tagged it C++: There is std::string that does all the memory management for you and doesn't give you these problems.

sth
+3  A: 

Use strncpy:

#define BUFSIZE 127
int main(int argc, char *argv[]) {
  /* ... */
  char prog_name[BUFSIZE + 1];
  strncpy(prog_name, argv[0], BUFSIZE);
  progname[BUFSIZE]= '\0';
  /* ... */
}

There are *n* versions for most str* functions.

David Schmitt
I hope I got all my "-1" right, my C was never very fluent.
David Schmitt
Better use BUFSIZE as the length and allocate BUFSiZE + 1 ;-).
Gamecat
good idea. done.
David Schmitt
+1  A: 

the l (strlcpy, strlcat) functions from OpenBSD are usually better than the n functions, they are both faster and easier to use securely, but they are nonstandard. However, they are BSD licensed so you can include a known good implementation in any program so you can be both cross platform and secure.

For Windows, if you don't care about portability, you can use *_s functions.

jbcreix
Better than the *n functions* how?
ceretullis
As described here: http://www.gratisoft.us/todd/papers/strlcpy.htmlThere is still a lot of work to use the 'n functions' effectively.
benno
A: 
int main
(
    int argc, 
    char *argV[]
) 
{
   char prog_name[128];
   if (strlen(argV[0]) < sizeof(prog_name))
   {
       strcpy(prog_name, argV[0]);
   }
   else
   {
       printf("%s is too large for the internal buffer\n", argV[0]);
   }

   return 0;
}
EvilTeach
Pet peeve: ditch the parens, sizeof is an operator and not a function. Parens are used for types, and are part of the argument to sizeof, which is "cast-like" in appearance.
unwind
Thank you for your thoughful comment.
EvilTeach
A: 

Thanks for these helpful answers. ;)

wishi
FYI standard SO procedure if you want to say thanks is to edit your question, not to add another answer. As you can see, some will downvote you for this (it wasn't me).
Graeme Perrow
A: 

Maybe you would find useful reading answers to this question

kliketa
+1  A: 

If I understand correctly, your real question is why the API functions are not made more secure.

One reason reason is that C library is legacy (too late to change it now).

The main reason, however, is that the library is designed to be minimalistic, so that it does the bare minimum and it is the user's responsibility to ensure that it is called correctly. If it was doing any excessive checks, then a price would be paid every time it is called, even if the user can assure for other reasons that no problem is going to occur. This is very very common in many APIs.

That being said, there are enough libraries that provide safer alternatives, they're just not part of the standard library. Also, many people who do higher level stuff work with C++, that has standard class libraries for many of those things.

Uri