security goals re strcpy/strcat/sprintf (Re: "Secure coding" audit checkers and Kerberos)
Nicolas Williams
Nicolas.Williams at sun.com
Wed Oct 15 22:58:00 EDT 2008
On Wed, Oct 15, 2008 at 08:06:32PM -0400, Tom Yu wrote:
> I acknowledge that the "unsafe" string functions can be used safely
> and that "safe" string functions can be used unsafely. Regardless, I
> think there is a meaningful difference between these "safe" and
> "unsafe" functions. It is easier to determine whether a particular
> use of "safe" function is actually safe than it is to determine
> whether a particular use of an "unsafe" function is safe, particularly
> if the pieces of compensating length checking code, etc. are
> replicated everywhere the "unsafe" function is used. The
> vulnerabilities resulting from unsafe uses of the "safe" functions,
> which could be truncation-related problems, are less severe than those
> vulnerabilities resulting from unsafe uses of the "unsafe" functions,
> which are more likely to be buffer overflow type problems.
I very much agree with the above.
> strlcpy/strlcat are not standard, and I recall reading allegations
> that their behavior is not very consistent across implementations.
They are quite common now though. I'll look at the alleged difference
between Solaris' and BSD' strlcat().
> memcpy is standard, but using it with null-terminated strings requires
> additional calls to strlen and such, which can further complicate
> automatic or manual inspection.
I agree. It's not worth going there (unless avoiding locale issues is
important; see below).
> Known issues with the printf family on Solaris include some
> "interesting" interpretations of the precision field for %s
> specifiers, such as counting "column width" rather than bytes. This
> can make dealing with gss_buffer_t and other such explicit-length
> string-like data structures problematic, depending on the current
> locale. Nico or other Sun folks, any thoughts on this?
You use a precision field for %s? Where? In any case, the manpage for
Solaris' snprintf() says:
"
If the conversion specifier is s, a standard-
conforming application (see standards(5)) inter-
prets the field width as the minimum number of
bytes to be printed; an application that is not
standard-conforming interprets the field width as
the minimum number of columns of screen display.
For an application that is not standard-conforming,
%10s means if the converted value has a screen
width of 7 columns, 3 spaces would be padded on the
right.
"
and
"
If the conversion specifier is s or S, a standard-
conforming application (see standards(5)) inter-
prets the precision as the maximum number of bytes
to be written; an application that is not
standard-conforming interprets the precision as the
maximum number of columns of screen display. For an
application that is not standard-conforming, %.5s
would print only the portion of the string that
would display in 5 screen columns. Only complete
characters are written.
"
The key here is "standard-conforming application." Figuring out exactly
what that means requires looking at standards(5), and maybe some source.
Looking at standards(5) I see nothing that clarifies this.
I'll file a manpage bug -- the specific standard that applies really
should be documented in the *printf() manpage.
So looking at source I see:
/*
* sec_display only needed if width
* is specified (ie, "%<width>s")
* Solaris behavior counts <width> in
* screen column width. (If XPG4
* behavior,
* <width> is counted in bytes.)
*/
and:
} else if (__xpg4 == 0 && MB_CUR_MAX > 1) {
...
} else {
/*
* XPG4 behavior - count
* precision as bytes.
* We don't use strlen() because
* the given char string may not
* be null-terminated.
*/
and:
* __xpg4 == 0 by default. The xpg4 cc driver will add an object
* file that contains int __xpg4 = 1". The symbol interposition
* provided by the linker will allow libc to find that symbol
* instead.
In other words, compile and link using the XPG4 or XPG6 options and
you'll get the standard byte-counting, rather than column-counting
behavior.
I'm not sure what this means for _libraries_, however. I'm not sure
whether libraries can have their own __xpg4 interposer that is local to
their link map group. I'll inquire and let you know. Having this
behavior selected by the application could certainly cause problems.
> Also, I suggest that we refine the description of our supported
> platforms to include some qualifiers like "includes an implementation
> of snprintf that is conforming or that is non-conforming in one of a
> small number of well-characterized ways".
+1
Nico
--
More information about the krbdev
mailing list