PennMUSH Community

Ticket #7186 (new general discussion)

Opened 2 years ago

Last modified 1 year ago

Linting the use of strncat/snprintf/strncpy functions

Reported by: intrevis Assigned to:
Priority: minor Milestone:
Keywords: Cc:
Visibility: Public

Description

At some point, it may worth it to go through and lint the use of the above functions. I did a quick glance, and here's what I found:

strncat: ident.c: 336-337 In theory, this should be safe, if you can guarantee that the maximum hostname size (NI_MAXHOST, perhaps?). strncat() doesn't guarantee that it will null-terminate strings though, so using it here could be dangerous.

strncpy: There's a ton of these. Since the manpage for strncpy explicitly states that it does not guarantee NULL termination, we need to be extra careful. For example, in set.c, care is taken to set the last element of the buffer to '\0'. However, in sql.c, the same convention is not followed. We could probably prove that in this case, it doesn't matter, but it doesn't hurt to check.

snprintf: A couple of these too. snprintf() is safe on BSD and Linux. On Windows, _snprintf is NOT safe. sprintf_s() is safe on Windows though, and takes the same parameters.

chopstr() is dangerous, depending on what people pass in. If they pass in BUFFER_LEN as lim, that could be bad.

Attachments

sane-snprintf.patch.txt (2.0 kB) - added by Nathan Baum on 02/04/07 11:45:50.
strncpy-fixes.patch.txt (4.9 kB) - added by Nathan Baum on 02/04/07 11:46:03.
hardened-chopstr.patch.txt (0.8 kB) - added by Nathan Baum on 02/04/07 11:46:14.

Change History

(in reply to: ↑ description ) 01/27/07 04:13:52 changed by intrevis

This isn't to say that anyone uses chopstr() dangerously right now. I'm just saying it could be dangerous.

Replying to intrevis:

At some point, it may worth it to go through and lint the use of the above functions. I did a quick glance, and here's what I found: strncat: ident.c: 336-337 In theory, this should be safe, if you can guarantee that the maximum hostname size (NI_MAXHOST, perhaps?). strncat() doesn't guarantee that it will null-terminate strings though, so using it here could be dangerous. strncpy: There's a ton of these. Since the manpage for strncpy explicitly states that it does not guarantee NULL termination, we need to be extra careful. For example, in set.c, care is taken to set the last element of the buffer to '\0'. However, in sql.c, the same convention is not followed. We could probably prove that in this case, it doesn't matter, but it doesn't hurt to check. snprintf: A couple of these too. snprintf() is safe on BSD and Linux. On Windows, _snprintf is NOT safe. sprintf_s() is safe on Windows though, and takes the same parameters. chopstr() is dangerous, depending on what people pass in. If they pass in BUFFER_LEN as lim, that could be bad.

02/04/07 11:45:50 changed by Nathan Baum

  • attachment sane-snprintf.patch.txt added.

02/04/07 11:46:03 changed by Nathan Baum

  • attachment strncpy-fixes.patch.txt added.

02/04/07 11:46:14 changed by Nathan Baum

  • attachment hardened-chopstr.patch.txt added.

02/04/07 11:49:25 changed by Nathan Baum

I think you're wrong about strncat:

POSIX: "A terminating null byte is always appended to the result." Linux: "the result is always terminated with `\0'" MSDN: "The resulting string is terminated with a null character."

I've made some patches:

sane-nprintf -- Has WIN32 systems use snprintf_s and vsnprintf_s. strcpy-fixes -- Fixes instances where strcpy wasn't followed by forcing a terminating NUL. hardened-chopstr -- Makes sure lim >= BUFFER_LEN can't break chopstr.

06/02/07 08:32:26 changed by raevnos

I've added the chopstr patch, and, with some modifications, the vsnprintf_s one -- google suggests that the function is _vsnprintf_s(), for example (Why can't MS just support the standard snprintf()?). A little while ago, I added a mush_strncpy() function that does nul-terminate the copied string, and have been replacing plain strncpy() and strcpy() calls with it whenever there's doubt about how long the string to be copied is.

Possible to-do: Provide implementations of snprintf()/vsnprintf() for really old systems without, or ones with a broken, non-conforming implementation.

Also need to go through and do some of this to 1.8.2, not just 1.8.3.