[compiler-rt] r174969 - [sanitizer] More accurate scanf parsing without GNU extensions.
Evgeniy Stepanov
eugeni.stepanov at gmail.com
Tue Feb 12 06:29:35 PST 2013
Author: eugenis
Date: Tue Feb 12 08:29:34 2013
New Revision: 174969
URL: http://llvm.org/viewvc/llvm-project?rev=174969&view=rev
Log:
[sanitizer] More accurate scanf parsing without GNU extensions.
In __isoc99_*scanf we don't have to worry about GNUisms, and can parse
%a accurately.
Patch by Jakub Jelinek.
Modified:
compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors_scanf.inc
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc?rev=174969&r1=174968&r2=174969&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Tue Feb 12 08:29:34 2013
@@ -150,7 +150,7 @@ INTERCEPTOR(int, prctl, int option, unsi
#include "sanitizer_common_interceptors_scanf.inc"
-#define VSCANF_INTERCEPTOR_IMPL(vname, ...) \
+#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...) \
{ \
void *ctx; \
COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \
@@ -158,29 +158,29 @@ INTERCEPTOR(int, prctl, int option, unsi
va_copy(aq, ap); \
int res = REAL(vname)(__VA_ARGS__); \
if (res > 0) \
- scanf_common(ctx, res, format, aq); \
+ scanf_common(ctx, res, allowGnuMalloc, format, aq); \
va_end(aq); \
return res; \
}
INTERCEPTOR(int, vscanf, const char *format, va_list ap)
-VSCANF_INTERCEPTOR_IMPL(vscanf, format, ap)
+VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)
INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)
-VSCANF_INTERCEPTOR_IMPL(vsscanf, str, format, ap)
+VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
-VSCANF_INTERCEPTOR_IMPL(vfscanf, stream, format, ap)
+VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
-VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, format, ap)
+VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,
va_list ap)
-VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, str, format, ap)
+VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
-VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, stream, format, ap)
+VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
#define SCANF_INTERCEPTOR_IMPL(name, vname, ...) \
{ \
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors_scanf.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors_scanf.inc?rev=174969&r1=174968&r2=174969&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors_scanf.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors_scanf.inc Tue Feb 12 08:29:34 2013
@@ -39,7 +39,8 @@ static bool char_is_one_of(char c, const
// returned in dir. This function returns the pointer to the first
// unprocessed character, or 0 in case of error.
// In case of the end-of-string, a pointer to the closing \0 is returned.
-static const char *scanf_parse_next(const char *p, ScanfDirective *dir) {
+static const char *scanf_parse_next(const char *p, bool allowGnuMalloc,
+ ScanfDirective *dir) {
internal_memset(dir, 0, sizeof(*dir));
dir->argIdx = -1;
@@ -121,7 +122,8 @@ static const char *scanf_parse_next(cons
// This is unfortunately ambiguous between old GNU extension
// of %as, %aS and %a[...] and newer POSIX %a followed by
// letters s, S or [.
- if (dir->convSpecifier == 'a' && !dir->lengthModifier[0]) {
+ if (allowGnuMalloc && dir->convSpecifier == 'a' &&
+ !dir->lengthModifier[0]) {
if (*p == 's' || *p == 'S') {
dir->maybeGnuMalloc = true;
++p;
@@ -271,14 +273,14 @@ static int scanf_get_store_size(ScanfDir
// Common part of *scanf interceptors.
// Process format string and va_list, and report all store ranges.
// Stops when "consuming" n_inputs input items.
-static void scanf_common(void *ctx, int n_inputs, const char *format,
- va_list aq) {
+static void scanf_common(void *ctx, int n_inputs, bool allowGnuMalloc,
+ const char *format, va_list aq) {
CHECK_GT(n_inputs, 0);
const char *p = format;
while (*p && n_inputs) {
ScanfDirective dir;
- p = scanf_parse_next(p, &dir);
+ p = scanf_parse_next(p, allowGnuMalloc, &dir);
if (!p)
break;
if (dir.convSpecifier == 0) {
More information about the llvm-commits
mailing list