14f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov//===-- sanitizer_scanf_interceptor_test.cc -------------------------------===// 24f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov// 34f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov// The LLVM Compiler Infrastructure 44f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov// 54f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov// This file is distributed under the University of Illinois Open Source 64f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov// License. See LICENSE.TXT for details. 74f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov// 84f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov//===----------------------------------------------------------------------===// 94f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov// 104f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov// Tests for *scanf interceptors implementation in sanitizer_common. 114f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov// 124f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov//===----------------------------------------------------------------------===// 13996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#include <vector> 14996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov 15996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#include "interception/interception.h" 16996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#include "sanitizer_test_utils.h" 17996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#include "sanitizer_common/sanitizer_libc.h" 18996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#include "gtest/gtest.h" 19996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov 20996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanovusing namespace __sanitizer; 21996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov 2244be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \ 23996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov ((std::vector<unsigned> *)ctx)->push_back(size) 24996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov 254f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov#include "sanitizer_common/sanitizer_common_interceptors_scanf.inc" 26996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov 270527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanovstatic const char scanf_buf[] = "Test string."; 280527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanovstatic size_t scanf_buf_size = sizeof(scanf_buf); 290527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanovstatic const unsigned SCANF_ARGS_MAX = 16; 300527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov 31f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanovstatic void testScanf3(void *ctx, int result, bool allowGnuMalloc, 32f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov const char *format, ...) { 33996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov va_list ap; 34996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov va_start(ap, format); 35f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov scanf_common(ctx, result, allowGnuMalloc, format, ap); 36996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov va_end(ap); 37996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov} 38996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov 39f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanovstatic void testScanf2(const char *format, int scanf_result, 40f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov bool allowGnuMalloc, unsigned n, 4144be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov va_list expected_sizes) { 42996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov std::vector<unsigned> scanf_sizes; 43996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov // 16 args should be enough. 44f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov testScanf3((void *)&scanf_sizes, scanf_result, allowGnuMalloc, format, 4544be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov scanf_buf, scanf_buf, scanf_buf, scanf_buf, scanf_buf, scanf_buf, 4644be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov scanf_buf, scanf_buf, scanf_buf, scanf_buf, scanf_buf, scanf_buf, 47f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov scanf_buf, scanf_buf, scanf_buf, scanf_buf); 4844be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov ASSERT_EQ(n, scanf_sizes.size()) << "Unexpected number of format arguments: '" 4944be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov << format << "'"; 50996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov for (unsigned i = 0; i < n; ++i) 5144be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov EXPECT_EQ(va_arg(expected_sizes, unsigned), scanf_sizes[i]) 5244be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov << "Unexpect write size for argument " << i << ", format string '" 5344be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov << format << "'"; 540527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov} 550527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov 560527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanovstatic void testScanf(const char *format, unsigned n, ...) { 570527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov va_list ap; 580527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov va_start(ap, n); 59f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov testScanf2(format, SCANF_ARGS_MAX, /* allowGnuMalloc */ true, n, ap); 600527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov va_end(ap); 610527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov} 620527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov 6344be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanovstatic void testScanfPartial(const char *format, int scanf_result, unsigned n, 6444be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov ...) { 650527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov va_list ap; 660527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov va_start(ap, n); 67f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov testScanf2(format, scanf_result, /* allowGnuMalloc */ true, n, ap); 68f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov va_end(ap); 69f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov} 70f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov 71f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanovstatic void testScanfNoGnuMalloc(const char *format, unsigned n, ...) { 72f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov va_list ap; 73f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov va_start(ap, n); 74f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov testScanf2(format, SCANF_ARGS_MAX, /* allowGnuMalloc */ false, n, ap); 75996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov va_end(ap); 76996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov} 77996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov 78996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy StepanovTEST(SanitizerCommonInterceptors, Scanf) { 7944be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov const unsigned I = sizeof(int); // NOLINT 8044be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov const unsigned L = sizeof(long); // NOLINT 8144be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov const unsigned LL = sizeof(long long); // NOLINT 8244be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov const unsigned S = sizeof(short); // NOLINT 8344be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov const unsigned C = sizeof(char); // NOLINT 8444be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov const unsigned D = sizeof(double); // NOLINT 8544be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov const unsigned LD = sizeof(long double); // NOLINT 8644be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov const unsigned F = sizeof(float); // NOLINT 8744be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov const unsigned P = sizeof(char *); // NOLINT 88996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov 89996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov testScanf("%d", 1, I); 90996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov testScanf("%d%d%d", 3, I, I, I); 91996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov testScanf("ab%u%dc", 2, I, I); 92996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov testScanf("%ld", 1, L); 93996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov testScanf("%llu", 1, LL); 94996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov testScanf("a %hd%hhx", 2, S, C); 956503100c43c8951f436698b47362cdc8c2ec0a69Alexey Samsonov testScanf("%c", 1, C); 96996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov 97996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov testScanf("%%", 0); 98996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov testScanf("a%%", 0); 99996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov testScanf("a%%b", 0); 100996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov testScanf("a%%%%b", 0); 101996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov testScanf("a%%b%%", 0); 102996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov testScanf("a%%%%%%b", 0); 103996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov testScanf("a%%%%%b", 0); 104996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov testScanf("a%%%%%f", 1, F); 105996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov testScanf("a%%%lxb", 1, L); 106996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov testScanf("a%lf%%%lxb", 2, D, L); 107996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov testScanf("%nf", 1, I); 108996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov 109996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov testScanf("%10s", 1, 11); 1106503100c43c8951f436698b47362cdc8c2ec0a69Alexey Samsonov testScanf("%10c", 1, 10); 111996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov testScanf("%%10s", 0); 112996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov testScanf("%*10s", 0); 113996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov testScanf("%*d", 0); 1146503100c43c8951f436698b47362cdc8c2ec0a69Alexey Samsonov 1156503100c43c8951f436698b47362cdc8c2ec0a69Alexey Samsonov testScanf("%4d%8f%c", 3, I, F, C); 116c36c168f8f482f35f200fea57dd88a888bf062fbEvgeniy Stepanov testScanf("%s%d", 2, scanf_buf_size, I); 117c36c168f8f482f35f200fea57dd88a888bf062fbEvgeniy Stepanov testScanf("%[abc]", 1, scanf_buf_size); 1183c2999e340a57a663f1b507006becfc49b368473Alexey Samsonov testScanf("%4[bcdef]", 1, 5); 119c36c168f8f482f35f200fea57dd88a888bf062fbEvgeniy Stepanov testScanf("%[]]", 1, scanf_buf_size); 1203c2999e340a57a663f1b507006becfc49b368473Alexey Samsonov testScanf("%8[^]%d0-9-]%c", 2, 9, C); 1213c2999e340a57a663f1b507006becfc49b368473Alexey Samsonov 1223c2999e340a57a663f1b507006becfc49b368473Alexey Samsonov testScanf("%*[^:]%n:%d:%1[ ]%n", 4, I, I, 2, I); 123c36c168f8f482f35f200fea57dd88a888bf062fbEvgeniy Stepanov 124c36c168f8f482f35f200fea57dd88a888bf062fbEvgeniy Stepanov testScanf("%*d%u", 1, I); 125c36c168f8f482f35f200fea57dd88a888bf062fbEvgeniy Stepanov 1264f06d0ba90aae87a21f3a7d75db985a01b8fb6d2Evgeniy Stepanov testScanf("%c%d", 2, C, I); 1274f06d0ba90aae87a21f3a7d75db985a01b8fb6d2Evgeniy Stepanov testScanf("%A%lf", 2, F, D); 1284f06d0ba90aae87a21f3a7d75db985a01b8fb6d2Evgeniy Stepanov 1290e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov testScanf("%ms %Lf", 2, P, LD); 1300e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov testScanf("s%Las", 1, LD); 1310e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov testScanf("%ar", 1, F); 1320e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov 1330e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov // In the cases with std::min below the format spec can be interpreted as 1340e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov // either floating-something, or (GNU extension) callee-allocated string. 1350e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov // Our conservative implementation reports one of the two possibilities with 1360e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov // the least store range. 137c36c168f8f482f35f200fea57dd88a888bf062fbEvgeniy Stepanov testScanf("%a[", 0); 1380e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov testScanf("%a[]", 0); 1390e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov testScanf("%a[]]", 1, std::min(F, P)); 1400e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov testScanf("%a[abc]", 1, std::min(F, P)); 1410e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov testScanf("%a[^abc]", 1, std::min(F, P)); 1420e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov testScanf("%a[ab%c] %d", 0); 1430e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov testScanf("%a[^ab%c] %d", 0); 1440e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov testScanf("%as", 1, std::min(F, P)); 1450e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov testScanf("%aS", 1, std::min(F, P)); 1460e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov testScanf("%a13S", 1, std::min(F, P)); 1470e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov testScanf("%alS", 1, std::min(F, P)); 148c36c168f8f482f35f200fea57dd88a888bf062fbEvgeniy Stepanov 149f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov testScanfNoGnuMalloc("s%Las", 1, LD); 150f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov testScanfNoGnuMalloc("%ar", 1, F); 151f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov testScanfNoGnuMalloc("%a[", 1, F); 152f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov testScanfNoGnuMalloc("%a[]", 1, F); 153f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov testScanfNoGnuMalloc("%a[]]", 1, F); 154f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov testScanfNoGnuMalloc("%a[abc]", 1, F); 155f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov testScanfNoGnuMalloc("%a[^abc]", 1, F); 156f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov testScanfNoGnuMalloc("%a[ab%c] %d", 3, F, C, I); 157f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov testScanfNoGnuMalloc("%a[^ab%c] %d", 3, F, C, I); 158f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov testScanfNoGnuMalloc("%as", 1, F); 159f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov testScanfNoGnuMalloc("%aS", 1, F); 160f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov testScanfNoGnuMalloc("%a13S", 1, F); 161f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov testScanfNoGnuMalloc("%alS", 1, F); 162f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov 163c36c168f8f482f35f200fea57dd88a888bf062fbEvgeniy Stepanov testScanf("%5$d", 0); 164c36c168f8f482f35f200fea57dd88a888bf062fbEvgeniy Stepanov testScanf("%md", 0); 165c36c168f8f482f35f200fea57dd88a888bf062fbEvgeniy Stepanov testScanf("%m10s", 0); 1660527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov 1670527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov testScanfPartial("%d%d%d%d //1\n", 1, 1, I); 1680527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov testScanfPartial("%d%d%d%d //2\n", 2, 2, I, I); 1690527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov testScanfPartial("%d%d%d%d //3\n", 3, 3, I, I, I); 1700527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov testScanfPartial("%d%d%d%d //4\n", 4, 4, I, I, I, I); 1710527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov 1720527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov testScanfPartial("%d%n%n%d //1\n", 1, 1, I); 1730527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov testScanfPartial("%d%n%n%d //2\n", 2, 4, I, I, I, I); 1740527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov 1750527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov testScanfPartial("%d%n%n%d %s %s", 3, 5, I, I, I, I, scanf_buf_size); 17644be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov testScanfPartial("%d%n%n%d %s %s", 4, 6, I, I, I, I, scanf_buf_size, 17744be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov scanf_buf_size); 178996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov} 179