1 /* Verify that the analyzer correctly purges state when it sees a call to 2 an unknown function. */ 3 4 #include <stdlib.h> 5 6 /* Verify fix for false-positive when checking for CVE-2005-1689. */ 7 8 typedef struct _krb5_data { 9 char *data; 10 } krb5_data; 11 12 extern void krb5_read_message(krb5_data *buf); 13 14 void test_1(krb5_data inbuf)15test_1 (krb5_data inbuf) 16 { 17 free(inbuf.data); 18 krb5_read_message(&inbuf); 19 free(inbuf.data); /* { dg-bogus "double-'free'" } */ 20 } 21 22 /* Verify that __pure__ functions are treated as not having side-effects. */ 23 24 extern int called_by_test_1a (void *) 25 __attribute__ ((__pure__)); test_1a(krb5_data inbuf)26void test_1a (krb5_data inbuf) 27 { 28 free (inbuf.data); 29 called_by_test_1a (&inbuf); 30 free (inbuf.data); /* { dg-warning "double-'free'" } */ 31 } 32 33 /* Verify that global pointers can be affected by an unknown function. */ 34 35 void *global_ptr; 36 extern void unknown_side_effects (void); 37 test_2(void)38void test_2 (void) 39 { 40 free (global_ptr); 41 unknown_side_effects (); 42 free (global_ptr); 43 } 44 45 extern void called_by_test_3 (void *); 46 test_3a(void)47void test_3a (void) 48 { 49 void *ptr = malloc (1024); 50 called_by_test_3 (ptr); 51 } /* { dg-bogus "leak" } */ 52 test_3b(void)53void test_3b (void) 54 { 55 krb5_data k; 56 k.data = malloc (1024); 57 called_by_test_3 (&k); 58 } /* { dg-bogus "leak" } */ 59 60 /* Verify that we traverse the graph of regions that are reachable from 61 the call. */ 62 63 struct foo 64 { 65 struct foo *next; 66 int *ptr; 67 }; 68 69 /* First, without a call to an unknown function. */ 70 test_4a(void)71void test_4a (void) 72 { 73 struct foo node_a; 74 struct foo node_b; 75 node_a.next = &node_b; 76 node_b.ptr = malloc (sizeof (int)); 77 global_ptr = &node_a; 78 *node_b.ptr = 42; /* { dg-warning "possibly-NULL" "possibly-NULL" } */ 79 /* { dg-warning "leak" "leak" { target *-*-* } .-1 } */ 80 /* FIXME: the above leak report is correct, but is reported at the wrong 81 location. */ 82 } /* { dg-warning "leak" } */ 83 84 /* With a call to an unknown function. */ 85 test_4b(void)86void test_4b (void) 87 { 88 struct foo node_a; 89 struct foo node_b; 90 node_a.next = &node_b; 91 node_b.ptr = malloc (sizeof (int)); 92 global_ptr = &node_a; 93 unknown_side_effects (); /* everything potentially visible through global_ptr. */ 94 *node_b.ptr = 42; /* { dg-bogus "possibly-NULL" } */ 95 } /* { dg-bogus "leak" } */ 96 97 extern void called_by_test_5 (const char *); test_5(void)98void test_5 (void) 99 { 100 called_by_test_5 ("???"); 101 } 102 103 extern void called_by_test_6 (const struct foo *); test_6(void)104void test_6 (void) 105 { 106 struct foo node; 107 node.next = NULL; 108 node.ptr = malloc (sizeof (int)); 109 110 /* This is a const ptr, but struct foo's ptr is non-const, 111 so we ought to assume it could be written to. */ 112 called_by_test_6 (&node); 113 } /* { dg-bogus "leak" } */ 114 115 /* TODO: things reachable from "outside" i.e. by params to caller to entrypoint. */ 116