1cdc3a89d5de90b2299c56f4a46c3de590c5184d1Ted Kremenek// RUN: %clang_cc1 -Wno-array-bounds -analyze -analyzer-checker=core,alpha.security.ArrayBoundV2 -verify %s 2c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek 3c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// Tests doing an out-of-bounds access after the end of an array using: 4c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer index 5c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer size for buffer 6c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test1(int x) { 7c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek int buf[100]; 8c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek buf[100] = 1; // expected-warning{{Out of bound memory access}} 9c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek} 10c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek 11c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test1_ok(int x) { 12c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek int buf[100]; 13c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek buf[99] = 1; // no-warning 14c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek} 15c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek 1615a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenekconst char test1_strings_underrun(int x) { 1715a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek const char *mystr = "mary had a little lamb"; 1815a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek return mystr[-1]; // expected-warning{{Out of bound memory access}} 1915a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek} 2015a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek 2115a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenekconst char test1_strings_overrun(int x) { 2215a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek const char *mystr = "mary had a little lamb"; 2315a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek return mystr[1000]; // expected-warning{{Out of bound memory access}} 2415a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek} 2515a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek 2615a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenekconst char test1_strings_ok(int x) { 2715a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek const char *mystr = "mary had a little lamb"; 2815a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek return mystr[5]; // no-warning 2915a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek} 3015a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek 31c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// Tests doing an out-of-bounds access after the end of an array using: 32c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - indirect pointer to buffer 33c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer index 34c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer size for buffer 35c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test1_ptr(int x) { 36c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek int buf[100]; 37c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek int *p = buf; 38c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek p[101] = 1; // expected-warning{{Out of bound memory access}} 39c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek} 40c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek 41c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test1_ptr_ok(int x) { 42c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek int buf[100]; 43c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek int *p = buf; 4415a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek p[99] = 1; // no-warning 45c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek} 46c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek 47c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// Tests doing an out-of-bounds access before the start of an array using: 48c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - indirect pointer to buffer, manipulated using simple pointer arithmetic 49c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer index 50c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer size for buffer 51c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test1_ptr_arith(int x) { 52c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek int buf[100]; 53c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek int *p = buf; 54c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek p = p + 100; 55a6b0b96e5376cd9cf182a3e240e0537feed43cdeTed Kremenek p[0] = 1; // expected-warning{{Out of bound memory access}} 56c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek} 57c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek 58c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test1_ptr_arith_ok(int x) { 59c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek int buf[100]; 60c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek int *p = buf; 61c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek p = p + 99; 62c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek p[0] = 1; // no-warning 63c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek} 64c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek 65c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test1_ptr_arith_bad(int x) { 66c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek int buf[100]; 67c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek int *p = buf; 68c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek p = p + 99; 69a6b0b96e5376cd9cf182a3e240e0537feed43cdeTed Kremenek p[1] = 1; // expected-warning{{Out of bound memory access}} 70c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek} 71c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek 72c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test1_ptr_arith_ok2(int x) { 73c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek int buf[100]; 74c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek int *p = buf; 7515a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek p = p + 99; 76a6b0b96e5376cd9cf182a3e240e0537feed43cdeTed Kremenek p[-1] = 1; // no-warning 77c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek} 78c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek 79c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// Tests doing an out-of-bounds access before the start of an array using: 80c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer index 81c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer size for buffer 82c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test2(int x) { 83c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek int buf[100]; 84c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek buf[-1] = 1; // expected-warning{{Out of bound memory access}} 85c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek} 86c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek 87c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// Tests doing an out-of-bounds access before the start of an array using: 88c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - indirect pointer to buffer 89c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer index 90c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer size for buffer 91c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test2_ptr(int x) { 92c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek int buf[100]; 93c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek int *p = buf; 94c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek p[-1] = 1; // expected-warning{{Out of bound memory access}} 95c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek} 96c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek 97c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// Tests doing an out-of-bounds access before the start of an array using: 98c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - indirect pointer to buffer, manipulated using simple pointer arithmetic 99c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer index 100c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer size for buffer 101c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test2_ptr_arith(int x) { 102c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek int buf[100]; 103c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek int *p = buf; 104c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek --p; 105882998923889a2fcce9b49696506c499e22cf38fTed Kremenek p[0] = 1; // expected-warning {{Out of bound memory access (accessed memory precedes memory block)}} 106c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek} 107c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek 108c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// Tests doing an out-of-bounds access before the start of a multi-dimensional 109c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// array using: 110c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer indices 111c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer sizes for the array 112c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test2_multi(int x) { 113c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek int buf[100][100]; 114c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek buf[0][-1] = 1; // expected-warning{{Out of bound memory access}} 115c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek} 116c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek 117c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// Tests doing an out-of-bounds access before the start of a multi-dimensional 118c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// array using: 119c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer indices 120c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer sizes for the array 121c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test2_multi_b(int x) { 122c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek int buf[100][100]; 123c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek buf[-1][0] = 1; // expected-warning{{Out of bound memory access}} 124c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek} 125c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek 126c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test2_multi_ok(int x) { 127c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek int buf[100][100]; 128c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek buf[0][0] = 1; // no-warning 129c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek} 130c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek 1311d8db493f86761df9470254a2ad572fc6abf1bf6Jordy Rose// *** FIXME *** 1321d8db493f86761df9470254a2ad572fc6abf1bf6Jordy Rose// We don't get a warning here yet because our symbolic constraint solving 1331d8db493f86761df9470254a2ad572fc6abf1bf6Jordy Rose// doesn't handle: (symbol * constant) < constant 134c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test3(int x) { 135c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek int buf[100]; 136c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek if (x < 0) 1371d8db493f86761df9470254a2ad572fc6abf1bf6Jordy Rose buf[x] = 1; 138c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek} 139c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek 140c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// *** FIXME *** 141c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// We don't get a warning here yet because our symbolic constraint solving 142c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// doesn't handle: (symbol * constant) < constant 143c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test4(int x) { 144c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek int buf[100]; 145c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek if (x > 99) 146c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek buf[x] = 1; 147c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek} 14882cfc6849204b07e80f8ac71e33247f7df760032Ted Kremenek 14982cfc6849204b07e80f8ac71e33247f7df760032Ted Kremenek// Don't warn when indexing below the start of a symbolic region's whose 15082cfc6849204b07e80f8ac71e33247f7df760032Ted Kremenek// base extent we don't know. 15182cfc6849204b07e80f8ac71e33247f7df760032Ted Kremenekint *get_symbolic(); 15282cfc6849204b07e80f8ac71e33247f7df760032Ted Kremenekvoid test_index_below_symboloc() { 15382cfc6849204b07e80f8ac71e33247f7df760032Ted Kremenek int *buf = get_symbolic(); 15482cfc6849204b07e80f8ac71e33247f7df760032Ted Kremenek buf[-1] = 0; // no-warning; 15582cfc6849204b07e80f8ac71e33247f7df760032Ted Kremenek} 15682cfc6849204b07e80f8ac71e33247f7df760032Ted Kremenek 157