blob: 2d00f4daa9184af1e61f29ec1a470111d4f9eb89 [file] [log] [blame]
Anna Zaks9f03b622012-01-07 02:33:10 +00001// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.security.taint,experimental.security.ArrayBoundV2 -Wno-format-security -verify %s
Anna Zaks9b0970f2011-11-16 19:58:17 +00002
3int scanf(const char *restrict format, ...);
4int getchar(void);
5
Anna Zaks1fb826a2012-01-12 02:22:34 +00006typedef struct _FILE FILE;
7extern FILE *stdin;
8int fscanf(FILE *restrict stream, const char *restrict format, ...);
9int sprintf(char *str, const char *format, ...);
10void setproctitle(const char *fmt, ...);
11typedef __typeof(sizeof(int)) size_t;
12
13// Define string functions. Use builtin for some of them. They all default to
14// the processing in the taint checker.
15#define strcpy(dest, src) \
16 ((__builtin_object_size(dest, 0) != -1ULL) \
17 ? __builtin___strcpy_chk (dest, src, __builtin_object_size(dest, 1)) \
18 : __inline_strcpy_chk(dest, src))
19
20static char *__inline_strcpy_chk (char *dest, const char *src) {
21 return __builtin___strcpy_chk(dest, src, __builtin_object_size(dest, 1));
22}
23char *stpcpy(char *restrict s1, const char *restrict s2);
24char *strncpy( char * destination, const char * source, size_t num );
Anna Zaks9b0c7492012-01-18 02:45:07 +000025char *strndup(const char *s, size_t n);
Anna Zaks1fb826a2012-01-12 02:22:34 +000026
Anna Zaks9b0970f2011-11-16 19:58:17 +000027#define BUFSIZE 10
28
29int Buffer[BUFSIZE];
Anna Zaks3881c692011-11-28 20:43:40 +000030void bufferScanfDirect(void)
Anna Zaks9b0970f2011-11-16 19:58:17 +000031{
32 int n;
33 scanf("%d", &n);
34 Buffer[n] = 1; // expected-warning {{Out of bound memory access }}
35}
Anna Zaks0d339d02011-11-17 23:07:28 +000036
37void bufferScanfArithmetic1(int x) {
38 int n;
39 scanf("%d", &n);
40 int m = (n - 3);
41 Buffer[m] = 1; // expected-warning {{Out of bound memory access }}
42}
43
44void bufferScanfArithmetic2(int x) {
45 int n;
46 scanf("%d", &n);
Anna Zaks3881c692011-11-28 20:43:40 +000047 int m = 100 / (n + 3) * x;
Anna Zaks0d339d02011-11-17 23:07:28 +000048 Buffer[m] = 1; // expected-warning {{Out of bound memory access }}
49}
Anna Zaks8f4caf52011-11-18 02:26:36 +000050
Anna Zaks3881c692011-11-28 20:43:40 +000051void bufferScanfAssignment(int x) {
52 int n;
53 scanf("%d", &n);
54 int m;
55 if (x > 0) {
56 m = n;
57 Buffer[m] = 1; // expected-warning {{Out of bound memory access }}
58 }
59}
60
Anna Zaks8f4caf52011-11-18 02:26:36 +000061void scanfArg() {
62 int t;
Anna Zakse3d250e2011-12-11 18:43:40 +000063 scanf("%d", t); // expected-warning {{conversion specifies type 'int *' but the argument has type 'int'}}
Anna Zaks8f4caf52011-11-18 02:26:36 +000064}
Anna Zaks3881c692011-11-28 20:43:40 +000065
66void bufferGetchar(int x) {
67 int m = getchar();
68 Buffer[m] = 1; //expected-warning {{Out of bound memory access }}
69}
Anna Zaks9f03b622012-01-07 02:33:10 +000070
Anna Zaks1fb826a2012-01-12 02:22:34 +000071void testUncontrolledFormatString(char **p) {
Anna Zaks9f03b622012-01-07 02:33:10 +000072 char s[80];
73 fscanf(stdin, "%s", s);
74 char buf[128];
75 sprintf(buf,s); // expected-warning {{Uncontrolled Format String}}
76 setproctitle(s, 3); // expected-warning {{Uncontrolled Format String}}
Anna Zaks1fb826a2012-01-12 02:22:34 +000077
78 // Test taint propagation through strcpy and family.
79 char scpy[80];
80 strcpy(scpy, s);
81 sprintf(buf,scpy); // expected-warning {{Uncontrolled Format String}}
82
Anna Zaksb71d1572012-01-13 00:56:55 +000083 stpcpy(*(++p), s); // this generates __inline.
84 setproctitle(*(p), 3); // expected-warning {{Uncontrolled Format String}}
85
Anna Zaks1fb826a2012-01-12 02:22:34 +000086 char spcpy[80];
87 stpcpy(spcpy, s);
88 setproctitle(spcpy, 3); // expected-warning {{Uncontrolled Format String}}
89
Anna Zaks9b0c7492012-01-18 02:45:07 +000090 char *spcpyret;
91 spcpyret = stpcpy(spcpy, s);
92 setproctitle(spcpyret, 3); // expected-warning {{Uncontrolled Format String}}
93
Anna Zaks1fb826a2012-01-12 02:22:34 +000094 char sncpy[80];
95 strncpy(sncpy, s, 20);
96 setproctitle(sncpy, 3); // expected-warning {{Uncontrolled Format String}}
Anna Zaks9b0c7492012-01-18 02:45:07 +000097
98 char *dup;
99 dup = strndup(s, 20);
100 setproctitle(dup, 3); // expected-warning {{Uncontrolled Format String}}
101
Anna Zaks9f03b622012-01-07 02:33:10 +0000102}
Anna Zaks8568ee72012-01-14 02:48:40 +0000103
104int system(const char *command);
105void testTaintSystemCall() {
106 char buffer[156];
107 char addr[128];
108 scanf("%s", addr);
109 system(addr); // expected-warning {{Tainted data passed to a system call}}
Anna Zaks9b0c7492012-01-18 02:45:07 +0000110
111 // Test that spintf transfers taint.
112 sprintf(buffer, "/bin/mail %s < /tmp/email", addr);
113 system(buffer); // expected-warning {{Tainted data passed to a system call}}
114}
115void testTaintSystemCall2() {
116 // Test that snpintf transfers taint.
117 char buffern[156];
118 char addr[128];
119 scanf("%s", addr);
120 __builtin_snprintf(buffern, 10, "/bin/mail %s < /tmp/email", addr);
121 system(buffern); // expected-warning {{Tainted data passed to a system call}}
122}
123void testTaintSystemCall3() {
124 char buffern2[156];
125 int numt;
126 char addr[128];
127 scanf("%s %d", addr, &numt);
128 __builtin_snprintf(buffern2, numt, "/bin/mail %s < /tmp/email", "abcd");
129 system(buffern2); // expected-warning {{Tainted data passed to a system call}}
Anna Zaks8568ee72012-01-14 02:48:40 +0000130}