summaryrefslogtreecommitdiff
path: root/lib/sanitizer_common/sanitizer_common_interceptors_format.inc
diff options
context:
space:
mode:
authorAlexey Samsonov <samsonov@google.com>2014-01-23 14:35:28 +0000
committerAlexey Samsonov <samsonov@google.com>2014-01-23 14:35:28 +0000
commitf13fd60eff704126bbaa1783ec043a5571c3591f (patch)
tree4c00b23d8d7027f5f6adea6fa0c292ed9d438bc6 /lib/sanitizer_common/sanitizer_common_interceptors_format.inc
parentac2152a232e2f5481f785bd523e418a07a09fc19 (diff)
downloadcompiler-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.inc15
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 {