blob: 0f8996674c8e0615f96cd7a4423d3e96d8455d29 [file] [log] [blame]
// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.security.taint,experimental.security.ArrayBoundV2 -Wno-format-security -verify %s
int scanf(const char *restrict format, ...);
int getchar(void);
typedef struct _FILE FILE;
extern FILE *stdin;
int fscanf(FILE *restrict stream, const char *restrict format, ...);
int sprintf(char *str, const char *format, ...);
void setproctitle(const char *fmt, ...);
typedef __typeof(sizeof(int)) size_t;
// Define string functions. Use builtin for some of them. They all default to
// the processing in the taint checker.
#define strcpy(dest, src) \
((__builtin_object_size(dest, 0) != -1ULL) \
? __builtin___strcpy_chk (dest, src, __builtin_object_size(dest, 1)) \
: __inline_strcpy_chk(dest, src))
static char *__inline_strcpy_chk (char *dest, const char *src) {
return __builtin___strcpy_chk(dest, src, __builtin_object_size(dest, 1));
}
char *stpcpy(char *restrict s1, const char *restrict s2);
char *strncpy( char * destination, const char * source, size_t num );
#define BUFSIZE 10
int Buffer[BUFSIZE];
void bufferScanfDirect(void)
{
int n;
scanf("%d", &n);
Buffer[n] = 1; // expected-warning {{Out of bound memory access }}
}
void bufferScanfArithmetic1(int x) {
int n;
scanf("%d", &n);
int m = (n - 3);
Buffer[m] = 1; // expected-warning {{Out of bound memory access }}
}
void bufferScanfArithmetic2(int x) {
int n;
scanf("%d", &n);
int m = 100 / (n + 3) * x;
Buffer[m] = 1; // expected-warning {{Out of bound memory access }}
}
void bufferScanfAssignment(int x) {
int n;
scanf("%d", &n);
int m;
if (x > 0) {
m = n;
Buffer[m] = 1; // expected-warning {{Out of bound memory access }}
}
}
void scanfArg() {
int t;
scanf("%d", t); // expected-warning {{conversion specifies type 'int *' but the argument has type 'int'}}
}
void bufferGetchar(int x) {
int m = getchar();
Buffer[m] = 1; //expected-warning {{Out of bound memory access }}
}
void testUncontrolledFormatString(char **p) {
char s[80];
fscanf(stdin, "%s", s);
char buf[128];
sprintf(buf,s); // expected-warning {{Uncontrolled Format String}}
setproctitle(s, 3); // expected-warning {{Uncontrolled Format String}}
// Test taint propagation through strcpy and family.
char scpy[80];
strcpy(scpy, s);
sprintf(buf,scpy); // expected-warning {{Uncontrolled Format String}}
stpcpy(*(++p), s); // this generates __inline.
setproctitle(*(p), 3); // expected-warning {{Uncontrolled Format String}}
char spcpy[80];
stpcpy(spcpy, s);
setproctitle(spcpy, 3); // expected-warning {{Uncontrolled Format String}}
char sncpy[80];
strncpy(sncpy, s, 20);
setproctitle(sncpy, 3); // expected-warning {{Uncontrolled Format String}}
}
int system(const char *command);
void testTaintSystemCall() {
char buffer[156];
char addr[128];
scanf("%s", addr);
system(addr); // expected-warning {{Tainted data passed to a system call}}
}