Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 67aa144

Browse files
committed
C++: Add some more test cases (moved from the private repo).
1 parent 19718fa commit 67aa144

5 files changed

Lines changed: 306 additions & 0 deletions

File tree

cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/ExposedSystemData.expected

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,16 @@ edges
1212
| tests2.cpp:109:6:109:8 | ptr [post update] | tests2.cpp:109:3:109:4 | c1 [post update] [ptr] |
1313
| tests2.cpp:109:12:109:17 | call to getenv | tests2.cpp:109:6:109:8 | ptr [post update] |
1414
| tests2.cpp:111:14:111:15 | c1 [read] [ptr] | tests2.cpp:111:14:111:19 | (const char *)... |
15+
| tests_sockets.cpp:26:15:26:20 | call to getenv | tests_sockets.cpp:39:19:39:22 | (const void *)... |
16+
| tests_sockets.cpp:26:15:26:20 | call to getenv | tests_sockets.cpp:39:19:39:22 | path |
17+
| tests_sockets.cpp:26:15:26:20 | call to getenv | tests_sockets.cpp:43:20:43:23 | (const void *)... |
18+
| tests_sockets.cpp:26:15:26:20 | call to getenv | tests_sockets.cpp:43:20:43:23 | path |
19+
| tests_sockets.cpp:63:15:63:20 | call to getenv | tests_sockets.cpp:76:19:76:22 | (const void *)... |
20+
| tests_sockets.cpp:63:15:63:20 | call to getenv | tests_sockets.cpp:76:19:76:22 | path |
21+
| tests_sockets.cpp:63:15:63:20 | call to getenv | tests_sockets.cpp:80:20:80:23 | (const void *)... |
22+
| tests_sockets.cpp:63:15:63:20 | call to getenv | tests_sockets.cpp:80:20:80:23 | path |
23+
| tests_sysconf.cpp:36:21:36:27 | pathbuf | tests_sysconf.cpp:39:19:39:25 | (const void *)... |
24+
| tests_sysconf.cpp:36:21:36:27 | pathbuf | tests_sysconf.cpp:39:19:39:25 | pathbuf |
1525
nodes
1626
| tests2.cpp:63:13:63:18 | call to getenv | semmle.label | call to getenv |
1727
| tests2.cpp:63:13:63:18 | call to getenv | semmle.label | call to getenv |
@@ -38,6 +48,19 @@ nodes
3848
| tests2.cpp:109:12:109:17 | call to getenv | semmle.label | call to getenv |
3949
| tests2.cpp:111:14:111:15 | c1 [read] [ptr] | semmle.label | c1 [read] [ptr] |
4050
| tests2.cpp:111:14:111:19 | (const char *)... | semmle.label | (const char *)... |
51+
| tests_sockets.cpp:26:15:26:20 | call to getenv | semmle.label | call to getenv |
52+
| tests_sockets.cpp:39:19:39:22 | (const void *)... | semmle.label | (const void *)... |
53+
| tests_sockets.cpp:39:19:39:22 | path | semmle.label | path |
54+
| tests_sockets.cpp:43:20:43:23 | (const void *)... | semmle.label | (const void *)... |
55+
| tests_sockets.cpp:43:20:43:23 | path | semmle.label | path |
56+
| tests_sockets.cpp:63:15:63:20 | call to getenv | semmle.label | call to getenv |
57+
| tests_sockets.cpp:76:19:76:22 | (const void *)... | semmle.label | (const void *)... |
58+
| tests_sockets.cpp:76:19:76:22 | path | semmle.label | path |
59+
| tests_sockets.cpp:80:20:80:23 | (const void *)... | semmle.label | (const void *)... |
60+
| tests_sockets.cpp:80:20:80:23 | path | semmle.label | path |
61+
| tests_sysconf.cpp:36:21:36:27 | pathbuf | semmle.label | pathbuf |
62+
| tests_sysconf.cpp:39:19:39:25 | (const void *)... | semmle.label | (const void *)... |
63+
| tests_sysconf.cpp:39:19:39:25 | pathbuf | semmle.label | pathbuf |
4164
subpaths
4265
#select
4366
| tests2.cpp:63:13:63:18 | call to getenv | tests2.cpp:63:13:63:18 | call to getenv | tests2.cpp:63:13:63:18 | call to getenv | This operation exposes system data from $@. | tests2.cpp:63:13:63:18 | call to getenv | call to getenv |
@@ -50,3 +73,8 @@ subpaths
5073
| tests2.cpp:93:14:93:17 | str1 | tests2.cpp:91:42:91:45 | str1 | tests2.cpp:93:14:93:17 | str1 | This operation exposes system data from $@. | tests2.cpp:91:42:91:45 | str1 | str1 |
5174
| tests2.cpp:102:14:102:15 | pw | tests2.cpp:101:8:101:15 | call to getpwuid | tests2.cpp:102:14:102:15 | pw | This operation exposes system data from $@. | tests2.cpp:101:8:101:15 | call to getpwuid | call to getpwuid |
5275
| tests2.cpp:111:14:111:19 | (const char *)... | tests2.cpp:109:12:109:17 | call to getenv | tests2.cpp:111:14:111:19 | (const char *)... | This operation exposes system data from $@. | tests2.cpp:109:12:109:17 | call to getenv | call to getenv |
76+
| tests_sockets.cpp:39:19:39:22 | path | tests_sockets.cpp:26:15:26:20 | call to getenv | tests_sockets.cpp:39:19:39:22 | path | This operation exposes system data from $@. | tests_sockets.cpp:26:15:26:20 | call to getenv | call to getenv |
77+
| tests_sockets.cpp:43:20:43:23 | path | tests_sockets.cpp:26:15:26:20 | call to getenv | tests_sockets.cpp:43:20:43:23 | path | This operation exposes system data from $@. | tests_sockets.cpp:26:15:26:20 | call to getenv | call to getenv |
78+
| tests_sockets.cpp:76:19:76:22 | path | tests_sockets.cpp:63:15:63:20 | call to getenv | tests_sockets.cpp:76:19:76:22 | path | This operation exposes system data from $@. | tests_sockets.cpp:63:15:63:20 | call to getenv | call to getenv |
79+
| tests_sockets.cpp:80:20:80:23 | path | tests_sockets.cpp:63:15:63:20 | call to getenv | tests_sockets.cpp:80:20:80:23 | path | This operation exposes system data from $@. | tests_sockets.cpp:63:15:63:20 | call to getenv | call to getenv |
80+
| tests_sysconf.cpp:39:19:39:25 | pathbuf | tests_sysconf.cpp:36:21:36:27 | pathbuf | tests_sysconf.cpp:39:19:39:25 | pathbuf | This operation exposes system data from $@. | tests_sysconf.cpp:36:21:36:27 | pathbuf | pathbuf |
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
// test cases for rule CWE-497
2+
3+
// library functions etc
4+
5+
typedef unsigned long size_t;
6+
typedef struct {} FILE;
7+
FILE *stdout;
8+
9+
int puts(const char *s);
10+
int printf(const char *format, ...);
11+
int sprintf(char *s, const char *format, ...);
12+
int snprintf(char *s, size_t n, const char *format, ...);
13+
size_t strlen(const char *s);
14+
char *getenv(const char *name);
15+
16+
namespace std
17+
{
18+
typedef size_t streamsize;
19+
20+
template<class charT> struct char_traits;
21+
22+
template <class charT, class traits = char_traits<charT> >
23+
class basic_ostream /*: virtual public basic_ios<charT,traits> - not needed for this test */ {
24+
public:
25+
typedef charT char_type;
26+
basic_ostream<charT,traits>& write(const char_type* s, streamsize n);
27+
28+
basic_ostream<charT, traits>& operator<<(int n);
29+
};
30+
template<class charT, class traits> basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, const charT*);
31+
32+
typedef basic_ostream<char> ostream;
33+
34+
extern ostream cout;
35+
extern ostream cerr;
36+
extern ostream clog;
37+
}
38+
extern std::ostream someotherostream;
39+
40+
#define NULL (0)
41+
42+
// test cases
43+
44+
void test1()
45+
{
46+
std::ostream cout_copy = std::cout;
47+
48+
std::cout << getenv("USERPROFILE"); // BAD: outputs USERPROFILE environment variable [NOT DETECTED]
49+
std::cerr << getenv("USERPROFILE"); // BAD: outputs USERPROFILE environment variable [NOT DETECTED]
50+
std::clog << getenv("USERPROFILE"); // BAD: outputs USERPROFILE environment variable [NOT DETECTED]
51+
someotherostream << getenv("USERPROFILE"); // GOOD: not output
52+
cout_copy << getenv("USERPROFILE"); // BAD: outputs USERPROFILE environment variable [NOT DETECTED]
53+
54+
std::cout << getenv("PATH"); // BAD: outputs PATH environment variable [NOT DETECTED]
55+
std::cout.write(getenv("PATH"), strlen(getenv("PATH"))); // BAD: outputs PATH environment variable [NOT DETECTED]
56+
(std::cout << "PATH = ").write(getenv("PATH"), strlen(getenv("PATH"))); // BAD: outputs PATH environment variable [NOT DETECTED]
57+
std::cout.write("PATH = ", 7) << getenv("PATH"); // BAD: outputs PATH environment variable [NOT DETECTED]
58+
}
59+
60+
char *global_path = getenv("PATH");
61+
char *global_other = "Hello, world!";
62+
63+
void test2(bool cond)
64+
{
65+
char *maybe;
66+
67+
maybe = cond ? global_path : global_other;
68+
69+
printf("path = '%s'\n", global_path); // BAD: outputs PATH environment variable [NOT DETECTED]
70+
printf("other = '%s'\n", global_other);
71+
printf("maybe = '%s'\n", maybe); // BAD: may output PATH environment variable [NOT DETECTED]
72+
}
73+
74+
void test3()
75+
{
76+
char *path_string = getenv("PATH");
77+
char buf[4096];
78+
79+
// ...
80+
snprintf(buf, 4096, "invalid path '%s'\n", path_string);
81+
puts(buf); // BAD: outputs PATH environment variable [NOT DETECTED]
82+
}
83+
84+
void myOutputFn(const char *msg)
85+
{
86+
printf("%s", msg);
87+
}
88+
89+
void myOtherFn(const char *msg)
90+
{
91+
}
92+
93+
void test4()
94+
{
95+
myOutputFn(getenv("PATH")); // BAD: outputs the PATH environment variable [NOT DETECTED]
96+
myOtherFn(getenv("PATH")); // GOOD: does not output anything.
97+
}
98+
99+
void myOutputFn2(const char *msg)
100+
{
101+
msg = "";
102+
printf("%s", msg);
103+
}
104+
105+
void myOutputFn3(const char *msg)
106+
{
107+
const char *tmp = msg;
108+
109+
printf("%s", tmp);
110+
}
111+
112+
void myOutputFn4(const char *msg)
113+
{
114+
char buffer[4096];
115+
116+
sprintf(buffer, "log: %s\n", msg);
117+
puts(buffer);
118+
}
119+
120+
void myOutputFn5(const char *msg)
121+
{
122+
printf("%s", msg);
123+
msg = "";
124+
}
125+
126+
void test5()
127+
{
128+
myOutputFn2(getenv("PATH")); // GOOD: myOutputFn2 doesn't actually output the parameter
129+
myOutputFn3(getenv("PATH")); // BAD: outputs the PATH environment variable [NOT DETECTED]
130+
myOutputFn4(getenv("PATH")); // BAD: outputs the PATH environment variable [NOT DETECTED]
131+
myOutputFn5(getenv("PATH")); // BAD: outputs the PATH environment variable [NOT DETECTED]
132+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
2+
int printf(const char *format, ...);
3+
4+
struct passwd {
5+
char *pw_passwd;
6+
char *pw_dir;
7+
// ...
8+
};
9+
10+
struct passwd *getpwnam(const char *name);
11+
12+
void test6(char *username)
13+
{
14+
passwd *pwd;
15+
16+
pwd = getpwnam(username);
17+
18+
printf("pw_passwd = %s\n", pwd->pw_passwd); // BAD [NOT DETECTED]
19+
printf("pw_dir = %s\n", pwd->pw_dir); // BAD [NOT DETECTED]
20+
printf("sizeof(passwd) = %i\n", sizeof(passwd)); // GOOD
21+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
2+
typedef unsigned long size_t;
3+
4+
size_t strlen(const char *s);
5+
char *getenv(const char *name);
6+
7+
#define AF_INET (2)
8+
#define SOCK_STREAM (1)
9+
10+
struct sockaddr {
11+
int sa_family;
12+
13+
// ...
14+
};
15+
16+
int socket(int domain, int type, int protocol);
17+
int connect(int socket, const struct sockaddr *address, size_t address_len);
18+
size_t send(int socket, const void *buffer, size_t length, int flags);
19+
int write(int handle, const void *buffer, size_t length);
20+
21+
void test_sockets1()
22+
{
23+
int sockfd;
24+
sockaddr addr_remote;
25+
char *msg = "Hello, world!";
26+
char *path = getenv("PATH");
27+
28+
// create socket
29+
sockfd = socket(AF_INET, SOCK_STREAM, 0);
30+
if (sockfd < 0) return;
31+
32+
// connect socket to a remote address
33+
addr_remote.sa_family = AF_INET;
34+
// ...
35+
if (connect(sockfd, &addr_remote, sizeof(addr_remote)) != 0) return;
36+
37+
// send something using 'send'
38+
if (send(sockfd, msg, strlen(msg) + 1, 0) < 0) return; // GOOD
39+
if (send(sockfd, path, strlen(path) + 1, 0) < 0) return; // BAD
40+
41+
// send something using 'write'
42+
if (write(sockfd, msg, strlen(msg) + 1) < 0) return; // GOOD
43+
if (write(sockfd, path, strlen(path) + 1) < 0) return; // BAD
44+
45+
// clean up
46+
// ...
47+
}
48+
49+
int mksocket()
50+
{
51+
int fd;
52+
53+
fd = socket(AF_INET, SOCK_STREAM, 0);
54+
55+
return fd;
56+
}
57+
58+
void test_sockets2()
59+
{
60+
int sockfd;
61+
sockaddr addr_remote;
62+
char *msg = "Hello, world!";
63+
char *path = getenv("PATH");
64+
65+
// create socket
66+
sockfd = mksocket();
67+
if (sockfd < 0) return;
68+
69+
// connect socket to a remote address
70+
addr_remote.sa_family = AF_INET;
71+
// ...
72+
if (connect(sockfd, &addr_remote, sizeof(addr_remote)) != 0) return;
73+
74+
// send something using 'send'
75+
if (send(sockfd, msg, strlen(msg) + 1, 0) < 0) return; // GOOD
76+
if (send(sockfd, path, strlen(path) + 1, 0) < 0) return; // BAD
77+
78+
// send something using 'write'
79+
if (write(sockfd, msg, strlen(msg) + 1) < 0) return; // GOOD
80+
if (write(sockfd, path, strlen(path) + 1) < 0) return; // BAD
81+
82+
// clean up
83+
// ...
84+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
2+
typedef unsigned long size_t;
3+
typedef signed long ssize_t;
4+
void *malloc(size_t size);
5+
#define NULL (0)
6+
7+
int printf(const char *format, ...);
8+
size_t strlen(const char *s);
9+
10+
int get_fd();
11+
int write(int handle, const void *buffer, size_t length);
12+
13+
long sysconf(int name);
14+
#define _SC_CHILD_MAX (2)
15+
16+
size_t confstr(int name, char *buffer, size_t length);
17+
#define _CS_PATH (1)
18+
19+
void test_sc_1()
20+
{
21+
int value = sysconf(_SC_CHILD_MAX);
22+
23+
printf("_SC_CHILD_MAX = %i\n", _SC_CHILD_MAX); // GOOD
24+
printf("_SC_CHILD_MAX = %i\n", value); // BAD [NOT DETECTED]
25+
}
26+
27+
void test_sc_2()
28+
{
29+
char *pathbuf;
30+
size_t n;
31+
32+
n = confstr(_CS_PATH, NULL, (size_t)0);
33+
pathbuf = (char *)malloc(n);
34+
if (pathbuf != NULL)
35+
{
36+
confstr(_CS_PATH, pathbuf, n);
37+
38+
printf("path: %s", pathbuf); // BAD [NOT DETECTED]
39+
write(get_fd(), pathbuf, strlen(pathbuf)); // BAD
40+
}
41+
}

0 commit comments

Comments
 (0)