I know strcpy is not secure when dealing with buffers, however in my code i have this
static char buf[HUGE_BUFFER_SIZE + 1];
char servername[200];
int length = 0;
char *out = NULL;
length = strlen(buf);
out = alloca(strlen(servername) + length + 5);
length = strlen(servername);
strcpy(out, servername);
out[length] = ' ';
out[length + 1] = 0;
strcat(out, buf);
If I change strcpy to strlcpy and use a sizeof for arg3, the output is garbled. Is there an easier way than using memcpy (which looks like I might have to do?) Im trying to avoid using insecure functions like strcpy and friends. Is there an easier way to accomplish the above with less copying of functions, and strnlens/alloca?
I’d do it like this:
(barring a copy/paste error, or different libraries on your system and a cross-platform screwup on my part, you should be able to paste this into a file, compile it, and run it, and see “127.0.0.1this is my test buffer!” as the output)
Note that all of the str functions, whether strcpy, strcat, strncpy, or strlcpy, drop a null terminator onto the end of any string they create. The only time you need to manually put on a null terminator is when you are starting a brand new string, as I did with the statement “out[0] = ‘\0′”.
Also, note that I used strnlen and strncat, not strlcat. I cannot tell from the documentation the difference between strlcat and strncat except in what the function returns.
Anyways, you should be able to avoid buffer-overrun security holes just be clearly bounding all of your function calls. strncpy and strncat bound how much data you will copy. strnlen bounds how long the system will search for a ‘\0’.
Edit: my original solution actually had an error that valgrind revealed. I was not initializing either buf or servername. While something else seemed to be magically initializing buf, valgrind reported that calling strcat with servername as the target was causing decisions to be made based on uninitialized data. doh.
Since I’m not sure why I was calling strcat to initialize my variables with string literals, I switched to strcpy. That, of course, is perfectly safe here because I have hard-coded into the application exactly the string I’m copying into the variable.