1 //===-- sanitizer_format_interceptor_test.cc ------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Tests for *scanf interceptors implementation in sanitizer_common. 11 // 12 //===----------------------------------------------------------------------===// 13 #include <algorithm> 14 #include <vector> 15 16 #include "interception/interception.h" 17 #include "sanitizer_test_utils.h" 18 #include "sanitizer_common/sanitizer_libc.h" 19 #include "sanitizer_common/sanitizer_common.h" 20 #include "gtest/gtest.h" 21 22 using namespace __sanitizer; 23 24 #define COMMON_INTERCEPTOR_READ_WRITE_RANGE(ctx, ptr, size) \ 25 do { \ 26 ((std::vector<unsigned> *)ctx)->push_back(size); \ 27 ptr = ptr; \ 28 } while (0) 29 30 #define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \ 31 COMMON_INTERCEPTOR_READ_WRITE_RANGE(ctx, ptr, size) 32 33 #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \ 34 COMMON_INTERCEPTOR_READ_WRITE_RANGE(ctx, ptr, size) 35 36 #define SANITIZER_INTERCEPT_PRINTF 1 37 #include "sanitizer_common/sanitizer_common_interceptors_format.inc" 38 39 static const unsigned I = sizeof(int); 40 static const unsigned L = sizeof(long); 41 static const unsigned LL = sizeof(long long); 42 static const unsigned S = sizeof(short); 43 static const unsigned C = sizeof(char); 44 static const unsigned LC = sizeof(wchar_t); 45 static const unsigned D = sizeof(double); 46 static const unsigned LD = sizeof(long double); 47 static const unsigned F = sizeof(float); 48 static const unsigned P = sizeof(char *); 49 50 static void verifyFormatResults(const char *format, unsigned n, 51 const std::vector<unsigned> &computed_sizes, 52 va_list expected_sizes) { 53 // "+ 1" because of format string 54 ASSERT_EQ(n + 1, 55 computed_sizes.size()) << "Unexpected number of format arguments: '" 56 << format << "'"; 57 for (unsigned i = 0; i < n; ++i) 58 EXPECT_EQ(va_arg(expected_sizes, unsigned), computed_sizes[i + 1]) 59 << "Unexpect write size for argument " << i << ", format string '" 60 << format << "'"; 61 } 62 63 static const char test_buf[] = "Test string."; 64 static const size_t test_buf_size = sizeof(test_buf); 65 66 static const unsigned SCANF_ARGS_MAX = 16; 67 68 static void testScanf3(void *ctx, int result, bool allowGnuMalloc, 69 const char *format, ...) { 70 va_list ap; 71 va_start(ap, format); 72 scanf_common(ctx, result, allowGnuMalloc, format, ap); 73 va_end(ap); 74 } 75 76 static void testScanf2(const char *format, int scanf_result, 77 bool allowGnuMalloc, unsigned n, 78 va_list expected_sizes) { 79 std::vector<unsigned> scanf_sizes; 80 // 16 args should be enough. 81 testScanf3((void *)&scanf_sizes, scanf_result, allowGnuMalloc, format, 82 test_buf, test_buf, test_buf, test_buf, test_buf, test_buf, 83 test_buf, test_buf, test_buf, test_buf, test_buf, test_buf, 84 test_buf, test_buf, test_buf, test_buf); 85 verifyFormatResults(format, n, scanf_sizes, expected_sizes); 86 } 87 88 static void testScanf(const char *format, unsigned n, ...) { 89 va_list ap; 90 va_start(ap, n); 91 testScanf2(format, SCANF_ARGS_MAX, /* allowGnuMalloc */ true, n, ap); 92 va_end(ap); 93 } 94 95 static void testScanfPartial(const char *format, int scanf_result, unsigned n, 96 ...) { 97 va_list ap; 98 va_start(ap, n); 99 testScanf2(format, scanf_result, /* allowGnuMalloc */ true, n, ap); 100 va_end(ap); 101 } 102 103 static void testScanfNoGnuMalloc(const char *format, unsigned n, ...) { 104 va_list ap; 105 va_start(ap, n); 106 testScanf2(format, SCANF_ARGS_MAX, /* allowGnuMalloc */ false, n, ap); 107 va_end(ap); 108 } 109 110 TEST(SanitizerCommonInterceptors, Scanf) { 111 testScanf("%d", 1, I); 112 testScanf("%d%d%d", 3, I, I, I); 113 testScanf("ab%u%dc", 2, I, I); 114 testScanf("%ld", 1, L); 115 testScanf("%llu", 1, LL); 116 testScanf("%qd", 1, LL); 117 testScanf("a %hd%hhx", 2, S, C); 118 testScanf("%c", 1, C); 119 testScanf("%lc", 1, LC); 120 121 testScanf("%%", 0); 122 testScanf("a%%", 0); 123 testScanf("a%%b", 0); 124 testScanf("a%%%%b", 0); 125 testScanf("a%%b%%", 0); 126 testScanf("a%%%%%%b", 0); 127 testScanf("a%%%%%b", 0); 128 testScanf("a%%%%%f", 1, F); 129 testScanf("a%%%lxb", 1, L); 130 testScanf("a%lf%%%lxb", 2, D, L); 131 testScanf("%nf", 1, I); 132 133 testScanf("%10s", 1, 11); 134 testScanf("%10c", 1, 10); 135 testScanf("%10ls", 1, 11 * LC); 136 testScanf("%10lc", 1, 10 * LC); 137 testScanf("%%10s", 0); 138 testScanf("%*10s", 0); 139 testScanf("%*d", 0); 140 141 testScanf("%4d%8f%c", 3, I, F, C); 142 testScanf("%s%d", 2, test_buf_size, I); 143 testScanf("%[abc]", 1, test_buf_size); 144 testScanf("%4[bcdef]", 1, 5); 145 testScanf("%[]]", 1, test_buf_size); 146 testScanf("%8[^]%d0-9-]%c", 2, 9, C); 147 148 testScanf("%*[^:]%n:%d:%1[ ]%n", 4, I, I, 2, I); 149 150 testScanf("%*d%u", 1, I); 151 152 testScanf("%c%d", 2, C, I); 153 testScanf("%A%lf", 2, F, D); 154 155 testScanf("%ms %Lf", 2, P, LD); 156 testScanf("s%Las", 1, LD); 157 testScanf("%ar", 1, F); 158 159 // In the cases with std::min below the format spec can be interpreted as 160 // either floating-something, or (GNU extension) callee-allocated string. 161 // Our conservative implementation reports one of the two possibilities with 162 // the least store range. 163 testScanf("%a[", 0); 164 testScanf("%a[]", 0); 165 testScanf("%a[]]", 1, std::min(F, P)); 166 testScanf("%a[abc]", 1, std::min(F, P)); 167 testScanf("%a[^abc]", 1, std::min(F, P)); 168 testScanf("%a[ab%c] %d", 0); 169 testScanf("%a[^ab%c] %d", 0); 170 testScanf("%as", 1, std::min(F, P)); 171 testScanf("%aS", 1, std::min(F, P)); 172 testScanf("%a13S", 1, std::min(F, P)); 173 testScanf("%alS", 1, std::min(F, P)); 174 175 testScanfNoGnuMalloc("s%Las", 1, LD); 176 testScanfNoGnuMalloc("%ar", 1, F); 177 testScanfNoGnuMalloc("%a[", 1, F); 178 testScanfNoGnuMalloc("%a[]", 1, F); 179 testScanfNoGnuMalloc("%a[]]", 1, F); 180 testScanfNoGnuMalloc("%a[abc]", 1, F); 181 testScanfNoGnuMalloc("%a[^abc]", 1, F); 182 testScanfNoGnuMalloc("%a[ab%c] %d", 3, F, C, I); 183 testScanfNoGnuMalloc("%a[^ab%c] %d", 3, F, C, I); 184 testScanfNoGnuMalloc("%as", 1, F); 185 testScanfNoGnuMalloc("%aS", 1, F); 186 testScanfNoGnuMalloc("%a13S", 1, F); 187 testScanfNoGnuMalloc("%alS", 1, F); 188 189 testScanf("%5$d", 0); 190 testScanf("%md", 0); 191 testScanf("%m10s", 0); 192 193 testScanfPartial("%d%d%d%d //1\n", 1, 1, I); 194 testScanfPartial("%d%d%d%d //2\n", 2, 2, I, I); 195 testScanfPartial("%d%d%d%d //3\n", 3, 3, I, I, I); 196 testScanfPartial("%d%d%d%d //4\n", 4, 4, I, I, I, I); 197 198 testScanfPartial("%d%n%n%d //1\n", 1, 3, I, I, I); 199 testScanfPartial("%d%n%n%d //2\n", 2, 4, I, I, I, I); 200 201 testScanfPartial("%d%n%n%d %s %s", 3, 5, I, I, I, I, test_buf_size); 202 testScanfPartial("%d%n%n%d %s %s", 4, 6, I, I, I, I, test_buf_size, 203 test_buf_size); 204 } 205 206 static void testPrintf3(void *ctx, const char *format, ...) { 207 va_list ap; 208 va_start(ap, format); 209 printf_common(ctx, format, ap); 210 va_end(ap); 211 } 212 213 static void testPrintf2(const char *format, unsigned n, 214 va_list expected_sizes) { 215 std::vector<unsigned> printf_sizes; 216 // 16 args should be enough. 217 testPrintf3((void *)&printf_sizes, format, 218 test_buf, test_buf, test_buf, test_buf, test_buf, test_buf, 219 test_buf, test_buf, test_buf, test_buf, test_buf, test_buf, 220 test_buf, test_buf, test_buf, test_buf); 221 verifyFormatResults(format, n, printf_sizes, expected_sizes); 222 } 223 224 static void testPrintf(const char *format, unsigned n, ...) { 225 va_list ap; 226 va_start(ap, n); 227 testPrintf2(format, n, ap); 228 va_end(ap); 229 } 230 231 TEST(SanitizerCommonInterceptors, Printf) { 232 // Only test functionality which differs from scanf 233 234 // Indexed arguments 235 testPrintf("%5$d", 0); 236 testPrintf("%.*5$d", 0); 237 238 // errno 239 testPrintf("%0-m", 0); 240 241 // Dynamic width 242 testPrintf("%*n", 1, I); 243 testPrintf("%*.10n", 1, I); 244 245 // Precision 246 testPrintf("%10.10n", 1, I); 247 testPrintf("%.3s", 1, 3); 248 testPrintf("%.20s", 1, test_buf_size); 249 250 // Dynamic precision 251 testPrintf("%.*n", 1, I); 252 testPrintf("%10.*n", 1, I); 253 254 // Dynamic precision for strings is not implemented yet. 255 testPrintf("%.*s", 1, 0); 256 257 // Checks for wide-character strings are not implemented yet. 258 testPrintf("%ls", 1, 0); 259 } 260