tags:

views:

96

answers:

4

I am new to C and I was wondering if it was possible for a pointer to be overflowed by a vulnerable c function like strcpy(). I have seen it a lot in source code, is it a way to avoid buffer overflows?

+1  A: 

Yes it is. This is in fact the classic cause of buffer overflow vulnerabilities. The only way to avoid overflowing the buffer is to ensure that you don't do anything that can cause the overflow. In the case of strcpy the solution is to use strncpy which includes the size of the buffer into which the string is being copied.

torak
`strncpy` doesn't help much since if there is no room for a terminating null character in the destination then one is not put there (i.e. if the source is longer than the destination size). Some people provide one less than the actual destination size.
dreamlax
`strncpy`'s API makes it really easy to use it wrong, and I've seen it used incorrectly many a time. I have no idea why people are so afraid of calculating a buffer size, allocating some memory, and using the original functions...
Thanatos
@Thanatos: In that case what do you do when you receive a buffer from a user? You can't even call `strlen` on it safely, it may not be NUL terminated.
torak
@torak: When I get a buffer from a user, it is NUL terminated. (after all... I'm the programmer, I wrote the program?) If its not, I know the length in some other form, like an aux `size_t`. If you have a buffer and you don't know the length, you've already messed up somewhere.
Thanatos
@Thantos: Authorship of some software doesn't give you control of its inputs. Sure you can, and should, implement sanitization / validation checking, but that is not the same as controlling user input.
torak
@torak: But if you don't know the buffer size either via a null terminator, or a recorded or implied length, you *cannot safely index that buffer* since you have no idea how long it is. Authorship of the software doesn't control the input, but it does control how the program accepts its inputs, manages memory, etc. Its like you're saying somehow I have ended up with `char *` to memory, but have no idea how much memory. I don't write such software -- if I have a pointer, I know how much memory it points to, or I can call `strlen` or similar.
Thanatos
+1  A: 

Sure, if you don't allocate enough space for a buffer, then you certainly can:

char* ptr = (char*)malloc(3);
strcpy(ptr, "this is very, very bad"); /* ptr only has 3 bytes allocated! */

However, what's really bad is that this code could work without giving you any errors, but it may overwrite some memory somewhere that could cause your program to blow up later, seemingly randomly, and you could have no idea why. Those are the source of hours (sometimes even days) of frustration, which anyone whose spent any significant amount of time writing C will tell you.

That is why with C, you have to be extremely careful with such things, and double, triple, nth degree check your code. After that, check it again.

dcp
A: 

Some other approaches are

#define MAX_LENGTH_NAME 256

foo()
{
char a[MAX_LENGTH_NAME+1]; // You can also use malloc here

strncpy(a,"Foxy",MAX_LENGTH_NAME);

snprintf(a,MAX_LENGTH_NAME,"%s","Foxy");

}

So its good to know the size of allocated memory and then use the calls to avoid buffer overflows. Static analysis of already written code may point out these kinds of mistakes and you can change it too.

Praveen S
The `strncpy()` call still lead to undefined behaviour if MAX_LENGTH_NAME is 4 (or if the source string is 256 characters in length), because the last byte of the `a` array will still be uninitialised.
dreamlax
Either one has to do that if you know the length wont exceed certain number. Otherwise allocate based on need i.e length of source.Ofcourse we can also use function asprintf which takes care of additional byte for the null termination.
Praveen S
`snprintf` ensures that the terminating null character fits inside the provided buffer size, but `strncpy` does not.
dreamlax
Not standard C, but you could use strlcpy. Which ensure that the nul is always included.
robUK