diff options
author | Alexey Samsonov <samsonov@google.com> | 2014-01-23 14:35:28 +0000 |
---|---|---|
committer | Alexey Samsonov <samsonov@google.com> | 2014-01-23 14:35:28 +0000 |
commit | f13fd60eff704126bbaa1783ec043a5571c3591f (patch) | |
tree | 4c00b23d8d7027f5f6adea6fa0c292ed9d438bc6 /lib/sanitizer_common/sanitizer_common_interceptors_format.inc | |
parent | ac2152a232e2f5481f785bd523e418a07a09fc19 (diff) | |
download | compiler-rt-f13fd60eff704126bbaa1783ec043a5571c3591f.tar.gz |
[Sanitizer] Fix false positive in printf interceptors: properly handle precision for %s
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@199895 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/sanitizer_common/sanitizer_common_interceptors_format.inc')
-rw-r--r-- | lib/sanitizer_common/sanitizer_common_interceptors_format.inc | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/lib/sanitizer_common/sanitizer_common_interceptors_format.inc b/lib/sanitizer_common/sanitizer_common_interceptors_format.inc index 1940deeef..40ebef2b1 100644 --- a/lib/sanitizer_common/sanitizer_common_interceptors_format.inc +++ b/lib/sanitizer_common/sanitizer_common_interceptors_format.inc @@ -381,7 +381,8 @@ static const char *maybe_parse_number_or_star(const char *p, int *out, // Parse printf format string. Same as scanf_parse_next. static const char *printf_parse_next(const char *p, PrintfDirective *dir) { internal_memset(dir, 0, sizeof(*dir)); - dir->argIdx = dir->precisionIdx = -1; + dir->argIdx = -1; + dir->precisionIdx = -1; while (*p) { if (*p != '%') { @@ -526,7 +527,17 @@ static void printf_common(void *ctx, const char *format, va_list aq) { continue; } else if (size == FSS_STRLEN) { if (void *argp = va_arg(aq, void *)) { - size = internal_strlen((const char *)argp) + 1; + if (dir.starredPrecision) { + // FIXME: properly support starred precision for strings. + size = 0; + } else if (dir.fieldPrecision > 0) { + // Won't read more than "precision" symbols. + size = internal_strnlen((const char *)argp, dir.fieldPrecision); + if (size < dir.fieldPrecision) size++; + } else { + // Whole string will be accessed. + size = internal_strlen((const char *)argp) + 1; + } COMMON_INTERCEPTOR_READ_RANGE(ctx, argp, size); } } else { |