This is an archive of the discontinued LLVM Phabricator instance.

Add new interceptors: strlcpy(3) and strlcat(3)
ClosedPublic

Authored by krytarowski on Jan 15 2018, 4:29 AM.

Details

Summary

NetBSD ships with strlcpy(3) and strlcat(3), a safe
replacement of strcpy(3) and strcat(3).

Hide both functions under SANITIZER_INTERCEPT_STRLCPY.

Sponsored by <The NetBSD Foundation>

Diff Detail

Event Timeline

krytarowski created this revision.Jan 15 2018, 4:29 AM

tests?

lib/sanitizer_common/sanitizer_common_interceptors.inc
6514

probably similar as above, but we need to "write" only appended part or we will hide bugs from msan if the beginning of the dst was not initialized.

  • add tests
  • correct strlcat(3)
krytarowski marked an inline comment as done.Jan 20 2018, 9:57 AM
vitalybuka added inline comments.Jan 23 2018, 2:53 PM
lib/sanitizer_common/sanitizer_common_interceptors.inc
6639

maybe just?
INTERCEPTOR(SIZE_T, strlcpy, char *dst, char *src, SIZE_T size) {

WRAP(strncpy)(dst, src, size);

}

krytarowski added inline comments.Jan 23 2018, 3:00 PM
lib/sanitizer_common/sanitizer_common_interceptors.inc
6639

But, these functions differ in behavior. strncpy(3) does not terminate a string always with a NUL-character.

vitalybuka added inline comments.Jan 23 2018, 4:09 PM
lib/sanitizer_common/sanitizer_common_interceptors.inc
6639

Right, I've already forgot from the last review.

6642

from doc

Also note that strlcpy() and strlcat() only operate on true ``C'' strings.

so we need COMMON_INTERCEPTOR_READ_STRING to enable strict_string_checks

len can't be len > size, so

if len < size
  we need to read len + 1
if len == size
  we need to read len  or size

this probably should be
COMMON_INTERCEPTOR_READ_STRING(ctx, src, MIN(REAL(strnlen)(src, size), size - 1) + 1)

6645

COMMON_INTERCEPTOR_COPY_STRING should be used here, so msan can track origins

6655

same as above, plus I guess we should use
copy_size = size - strlen(dst)
COMMON_INTERCEPTOR_READ_STRING(ctx, src, MIN(REAL(strnlen)(src, copy_size), copy_size - 1) + 1)

6664

Maybe better still user REAL(strlcat)()?
If not, I guess you can just remove src check and just WRAP(strlcpy)() here

6665

COMMON_INTERCEPTOR_COPY_STRING should be used here, so msan can track origins

  • use COMMON_INTERCEPTOR_COPY_STRING().
  • use COMMON_INTERCEPTOR_READ_STRING()

Should be done.

lib/sanitizer_common/sanitizer_common_interceptors.inc
6642

"len can't be len > size, so" I don't see this enforced in the specification of the function.

vitalybuka added inline comments.Feb 1 2018, 2:10 PM
lib/sanitizer_common/sanitizer_common_interceptors.inc
6642

from man strnlen:

The strnlen() function returns the number of characters in the string pointed to by s, excluding the terminating null byte ('\0'), but at most maxlen.

6744

can you remove if (src) branch? it's should be checked by WRAP(strlcpy)

krytarowski added inline comments.Feb 1 2018, 2:24 PM
lib/sanitizer_common/sanitizer_common_interceptors.inc
6642

I've misunderstood the proposal. I will go for it.

Is there a macro for MIN() or should I define one?

vitalybuka added inline comments.Feb 1 2018, 2:30 PM
lib/sanitizer_common/sanitizer_common_interceptors.inc
6642

It's actually Min().
It's defined compiler-rt/lib/sanitizer_common/sanitizer_common.h and already used in this file. E.g. INTERCEPTOR(SIZE_T, strnlen

vitalybuka added inline comments.Feb 1 2018, 3:04 PM
lib/sanitizer_common/sanitizer_common_interceptors.inc
6734

also please put strnlen() into macro:
COMMON_INTERCEPTOR_READ_STRING(ctx, src, ... strnlen() ... )
in this case macro expansion will avoid addition strnlen in case of strict string check.

Apply comments from review.

krytarowski added inline comments.Feb 1 2018, 3:12 PM
lib/sanitizer_common/sanitizer_common_interceptors.inc
6734

I will do it.

Apply comments from review.
git-clang-format over tests.

vitalybuka accepted this revision.Feb 1 2018, 3:30 PM
This revision is now accepted and ready to land.Feb 1 2018, 3:30 PM
krytarowski marked 15 inline comments as done.Feb 1 2018, 3:32 PM
This revision was automatically updated to reflect the committed changes.