Unsafe Functions In C And Their Safer Replacements: Strings Part II

Subscribe To Our Feed | Follow Us On Twitter | Get Updates on Email

Last time, we advised you to use ditch the unsafe functions like strcpy and strcat, and use their safer replacements (strlcpy, strlcat) instead. However, there is a small problem with this that you might discover that your compiler (especially gcc) does not have these functions in their implementation of the c library (libc). Why is this so? Read this thread about the original patch that was submitted to add these functions to libc. Essentially, it was rejected on the basis that these functions hide problems instead of solving them and would actually lead to hard to detect bugs that creep in because of unsolicited truncation caused by these functions. A sample implementation of strlcpy looks like this:

#include <sys/types.h>
#include <string.h>
 
/*
 * Copy src to string dst of size siz.  At most siz-1 characters
 * will be copied.  Always NUL terminates (unless siz == 0).
 * Returns strlen(src); if retval >= siz, truncation occurred.
 */
size_t
strlcpy(char *dst, const char *src, size_t siz)
{
	char *d = dst;
	const char *s = src;
	size_t n = siz;
 
	/* Copy as many bytes as will fit */
	if (n != 0) {
		while (--n != 0) {
			if ((*d++ = *s++) == '\0')
				break;
		}
	}
 
	/* Not enough room in dst, add NUL and traverse rest of src */
	if (n == 0) {
		if (siz != 0)
			*d = '\0';		/* NUL-terminate dst */
		while (*s++)
			;
	}
 
	return(s - src - 1);	/* count does not include NUL */
}

Now, there are supporters for both the sides. Solaris and BSD accepted these functions while GNU/Linux refuses to do so till date. The stand that I’d like to take here is that this is at least a step towards the right direction because a truncation bug is much better than an attacker taking over the control of your network just by pushing out a long string onto the stack. However, we could indeed augment the implementation above to communicate back to the caller somehow that truncation occurred. Whichever side you choose, be aware that these problems are very real and don’t just keep on using the older unsafe versions (Even in words of Ulrich Drepper, the opposer of strlcpy: “ The users of these functions[strcpy, strcat] should be severly punished”).

© Safer Code | Unsafe Functions In C And Their Safer Replacements: Strings Part II

Liked this post? Get FREE Updates
Subscribe to RSS feed

Or
Enter Your E-mail ID below

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • StumbleUpon
  • Reddit
  • Print this article!

Related posts

Tags: , , , , , , , ,

8 Comments

  • CdeMills says:

    I agree with the criticisms. To me, a ’string’ should really be something opaque instead of a vector of chars. Strings have properties : they can contains standard ASCII characters or use some encoding or be in wide, multi-bytes characters; their storage can be static, local or resulting from a ‘malloc’ call; and so on. Each item introduces specific issues and pitfalls. Your approach is targeted some issues, based on a few assumptions. If the basic assumptions are not satisfied, behaviour is unspecified.

  • DoctorPepper says:

    What about the strncpy and strncat functions that have been in gcc for quite some time now? They have similar function declarations to the strlcpy and strlcat functions you specified:

    char *strncpy(char *dest, const char *src, size_t n);
    char *strncat(char *dest, const char *src, size_t n);

    Granted, they don’t return the number of bytes copied in a size_t, but they will only copy ‘n’ number of bytes.

  • Maglama says:

    Why don’t we just fully depreciate the unsafe functions? Seriously.

    We could move the historical functions to an , allowing old code to be trivially recompiled if we REALLY don’t want to fix it. Everyone else can use heap storage calculated to fit.

  • Maglama says:

    * EDIT that’s supposed to read “We could move the historical functions to an {less-than}unsafe_c.h{greater-than} but the blog stripped it as HTML-like

  • Dummy00001 says:

    > Solaris and BSD accepted these functions while GNU/Linux refuses to do so till date.

    Little of Googling never hurts. And definitely might have helped to resolve your confusion and avoid silly remark. GNU refused the function for two very simple reasons: (1) there is no stable interfaces/not a POSIX and (2) redundant.

    As was pointed many many times, strlcpy() is 100% redundant, as the same effect can be achieved by snprintf(dest,dest_capacity,”%s”,src).

    What’s more, snprintf() has very important extra bonus: snprintf(dest,dest_capacity,”%.*s”,src_len,src) which allows to work also on non-zero terminated input.

  • DoctorPepper says:

    Never mind, I answered my own question. The strlcpy and strlcat functions are supposed to be safer versions of strncpy and strncat as well as strcpy and strcat.

    Man, don’t you hate it when you reply too early in the morning?

  • bug1 says:

    Programmers should use dmalloc (or another memory checker, maybe valgrind) to check against memory leaks and fencepost problems (exceeding the end of allocated memory), that should highlight most cases of “unsafe” string use (not format attacks).

    Introducing functions that allow programmers to remain ignorant of how their code works might be convenient in the short term, but in the long term the best way to write safe code is understand the language.

    C’s strength is that its low level, its not one of these dumbed down flash in the pan convenience languages.

  • mcoon says:

    See the C++ STL string template object.

    #include ;
    #include ;

    using namespace std;

    int main(int argc, char *argv[]){
    string s(“This is a basic string.”);
    cout << s << endl;
    }

Leave a Reply