Skip to content

Commit b625041

Browse files
committed
update auto-detect
1 parent 24bb7b2 commit b625041

9 files changed

+144
-54
lines changed

codeql-script/auto_detect.py

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,108 @@ def if_big(database_path):
8181
else:
8282
return False
8383

84+
# ql_code: orig parameter-value-check.ql
85+
# target_api: api used
86+
# target_index: api parameter index.
87+
def gen_parameter_check_ql(ql_code, target_api, target_index)
88+
{
89+
target_api_str = 'fc.getTarget().hasName("' + target_api + '")'
90+
target_index_str = 'result = fc.getArgument(' + str(target_index) + ')'
91+
ql_code = ql_code.replace('fc.getTarget().hasName("SSL_CTX_set_options")', target_api_str)
92+
ql_code = ql_code.replace('result = fc.getArgument(0) ', target_index_str)
93+
return ql_code
94+
}
95+
96+
def gen_missing_free_ql(ql_code, target_api, target_index, free_list)
97+
{
98+
ql_code = ql_code.replace('Target_Malloc', target_api)
99+
ql_code = ql_code.replace('Target_INDEX', target_index)
100+
free_str = 'fc.getTarget().hasName("free")'
101+
for free_api in free_list:
102+
free_str = free_str + '\nor fc.getTarget().hasName("' + free_api + '")'
103+
104+
ql_code = ql_code.replace('fc.getTarget().hasName("free")', free_str)
105+
return ql_code
106+
}
107+
108+
def gen_missing_malloc_ql(ql_code, target_api, target_index, malloc_dict_list)
109+
{
110+
ql_code = ql_code.replace('Target_Free', target_api)
111+
ql_code = ql_code.replace('Target_INDEX', target_index)
112+
malloc_str = '(fc.getTarget().hasName("malloc_with_parameter") and e = fc)'
113+
malloc_str2 = 'fc.getTarget().hasName("malloc")'
114+
for malloc_item in malloc_dict_list:
115+
malloc_api = malloc_item['api']
116+
malloc_index = malloc_item['index']
117+
118+
malloc_str = malloc_str + '\n or (fc.getTarget().hasName("' + malloc_api + '") and e = fc.getArgument(' + str(malloc_index) + '))'
119+
malloc_str2 = malloc_str2 + '\n or fc.getTarget().hasName("' + malloc_api + '")'
120+
ql_code = ql_code.replace('(fc.getTarget().hasName("malloc_with_parameter") and e = fc)', malloc_str)
121+
ql_code = ql_code.replace('fc.getTarget().hasName("malloc")', malloc_str2)
122+
ql_code = ql_code.replace('malloc_with_parameter', 'malloc')
123+
return ql_code
124+
}
125+
126+
def gen_double_free_ql(ql_code, target_api, target_index, malloc_dict_list)
127+
{
128+
ql_code = ql_code.replace('Target_Free', target_api)
129+
ql_code = ql_code.replace('Target_INDEX', target_index)
130+
malloc_str = '(fc.getTarget().hasName("malloc_with_parameter") and e = fc)'
131+
malloc_str2 = 'fc.getTarget().hasName("malloc")'
132+
for malloc_item in malloc_dict_list:
133+
malloc_api = malloc_item['api']
134+
malloc_index = malloc_item['index']
135+
136+
malloc_str = malloc_str + '\n or (fc.getTarget().hasName("' + malloc_api + '") and e = fc.getArgument(' + str(malloc_index) + '))'
137+
malloc_str2 = malloc_str2 + '\n or fc.getTarget().hasName("' + malloc_api + '")'
138+
ql_code = ql_code.replace('(fc.getTarget().hasName("malloc_with_parameter") and e = fc)', malloc_str)
139+
ql_code = ql_code.replace('fc.getTarget().hasName("malloc")', malloc_str2)
140+
ql_code = ql_code.replace('malloc_with_parameter', 'malloc')
141+
return ql_code
142+
}
143+
144+
def gen_uaf_ql(ql_code, target_api, target_index, malloc_dict_list, free_list)
145+
{
146+
ql_code = ql_code.replace('Target_API', target_api)
147+
ql_code = ql_code.replace('Target_INDEX', target_index)
148+
malloc_str = '(fc.getTarget().hasName("malloc_with_parameter") and e = fc)'
149+
malloc_str2 = 'fc.getTarget().hasName("malloc")'
150+
for malloc_item in malloc_dict_list:
151+
malloc_api = malloc_item['api']
152+
malloc_index = malloc_item['index']
153+
154+
malloc_str = malloc_str + '\n or (fc.getTarget().hasName("' + malloc_api + '") and e = fc.getArgument(' + str(malloc_index) + '))'
155+
malloc_str2 = malloc_str2 + '\n or fc.getTarget().hasName("' + malloc_api + '")'
156+
ql_code = ql_code.replace('(fc.getTarget().hasName("malloc_with_parameter") and e = fc)', malloc_str)
157+
ql_code = ql_code.replace('fc.getTarget().hasName("malloc")', malloc_str2)
158+
ql_code = ql_code.replace('malloc_with_parameter', 'malloc')
159+
160+
free_str = 'fc.getTarget().hasName("free")'
161+
for free_api in free_list:
162+
free_str = free_str + '\n or fc.getTarget().hasName("' + free_api + '")'
163+
ql_code = ql_code.replace('fc.getTarget().hasName("free")', free_str)
164+
return ql_code
165+
166+
}
167+
168+
def gen_uninitialize_ql(ql_code, target_api, target_index, initialize_dict_list)
169+
{
170+
ql_code = ql_code.replace('Target_API', target_api)
171+
ql_code = ql_code.replace('Target_INDEX', target_index)
172+
malloc_str = '(fc.getTarget().hasName("initialize_expr") and e = fc.getArgument(0))'
173+
malloc_str2 = 'fc.getTarget().hasName("initialize")'
174+
for malloc_item in initialize_dict_list:
175+
malloc_api = malloc_item['api']
176+
malloc_index = malloc_item['index']
177+
178+
malloc_str = malloc_str + '\n or (fc.getTarget().hasName("' + malloc_api + '") and e = fc.getArgument(' + str(malloc_index) + '))'
179+
malloc_str2 = malloc_str2 + '\n or fc.getTarget().hasName("' + malloc_api + '")'
180+
ql_code = ql_code.replace('(fc.getTarget().hasName("initialize_expr") and e = fc.getArgument(0))', malloc_str)
181+
ql_code = ql_code.replace('fc.getTarget().hasName("initialize")', malloc_str2)
182+
return ql_code
183+
184+
}
185+
84186
def gen_ql_code(ql_dir, big_flag, database):
85187
ql_path = ql_dir + '/'
86188
ql_name = database['malloc_api'] + '-' + database['free_api'] + '.ql'
@@ -210,6 +312,8 @@ def sort_by_size(database_list, database_dir):
210312
# exit(1)
211313
return out_list
212314

315+
316+
213317
if __name__ == '__main__':
214318
# in_list = 'list'
215319
# #in Ubuntu 18.04(vmware)

codeql-script/auto_find.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,8 @@ def get_api_list(in_path, lib):
136136
output_path = out_dir + '/findres'
137137
filter_list = []
138138
api_path = api_dir + '/'
139-
# libs = ['openssl', 'libpcap', 'libxml2', 'sqlite3']
140-
libs = ['libpcap']
139+
libs = ['openssl', 'libpcap', 'libxml2', 'sqlite3']
140+
# libs = ['libpcap']
141141
# libs = ['ffmpeg', 'ldap', 'libpcap','libexpat','libmysql','libgnutls', 'libevent', 'zlib','libzip', 'libdbus']
142142
# if not os.path.exists(output_dir):
143143
# os.mkdir(output_dir)

codeql-script/auto_gen_ql.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import os
2+
import json

ql-code/double-free.ql

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,7 @@ Expr getMallocExpr(FunctionCall fc)
2121
result = e
2222
and
2323
(
24-
(fc.getTarget().hasName("malloc") and e = fc)
25-
or
26-
(fc.getTarget().hasName("initialize_api") and e = fc.getArgument(0))
24+
(fc.getTarget().hasName("malloc_with_parameter") and e = fc)
2725
// TODO-addMallocHere
2826
)
2927
)
@@ -32,27 +30,26 @@ Expr getMallocExpr(FunctionCall fc)
3230
Expr getFreeExpr(FunctionCall fc)
3331
{
3432

35-
result = fc.getArgument(0)
33+
result = fc.getArgument(Target_INDEX)
3634
and
3735
(
38-
fc.getTarget().hasName("free")
39-
or
40-
fc.getTarget().hasName("target")
36+
fc.getTarget().hasName("Target_Free")
37+
// or
38+
// fc.getTarget().hasName("target")
4139
// TODO-addFreeHere
4240
)
4341
}
4442
predicate isSourceFC(FunctionCall fc)
4543
{
46-
fc.getTarget().hasName("initialize_api")
47-
or
44+
4845
fc.getTarget().hasName("malloc")
4946
}
5047

5148
predicate isSinkFC(FunctionCall fc)
5249
{
53-
fc.getTarget().hasName("free")
54-
or
55-
fc.getTarget().hasName("target")
50+
fc.getTarget().hasName("Target_Free")
51+
// or
52+
// fc.getTarget().hasName("target")
5653
}
5754
DataFlow::Node getSinkNode(FunctionCall fc)
5855
{

ql-code/free-missing-malloc.ql

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Expr getMallocExpr(FunctionCall fc)
2121
result = e
2222
and
2323
(
24-
(fc.getTarget().hasName("malloc") and e = fc)
24+
(fc.getTarget().hasName("malloc_with_parameter") and e = fc)
2525
// or
2626
// (fc.getTarget().hasName("new_malloc") and e = fc.getArgument(0))
2727
// TODO-addMallocHere
@@ -32,10 +32,10 @@ Expr getMallocExpr(FunctionCall fc)
3232
Expr getFreeExpr(FunctionCall fc)
3333
{
3434

35-
result = fc.getArgument(0)
35+
result = fc.getArgument(Target_INDEX)
3636
and
3737
(
38-
fc.getTarget().hasName("free")
38+
fc.getTarget().hasName("Target_Free")
3939
// or
4040
// fc.getTarget().hasName("new_free")
4141
// TODO-addFreeHere
@@ -50,7 +50,7 @@ Expr getFreeExpr(FunctionCall fc)
5050

5151
predicate isSinkFC(FunctionCall fc)
5252
{
53-
fc.getTarget().hasName("free")
53+
fc.getTarget().hasName("Target_Free")
5454
// or
5555
// fc.getTarget().hasName("new_free")
5656
}

ql-code/malloc-missing-free.ql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Expr getMallocExpr(FunctionCall fc)
2121
result = e
2222
and
2323
(
24-
(fc.getTarget().hasName("malloc") and e = fc)
24+
(fc.getTarget().hasName("Target_Malloc") and e = fc.getArgument(Target_INDEX))
2525
// or
2626
// (fc.getTarget().hasName("new_malloc") and e = fc.getArgument(0))
2727
// TODO-addMallocHere
@@ -55,7 +55,7 @@ Expr getFreeExpr(FunctionCall fc)
5555
{
5656
// fc.getTarget().hasName("new_malloc")
5757
// or
58-
fc.getTarget().hasName("malloc")
58+
fc.getTarget().hasName("Target_Malloc")
5959
}
6060

6161
predicate isSinkFC(FunctionCall fc)

ql-code/parameter-value-check.ql

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,18 @@ import semmle.code.cpp.security.Security
1515
import semmle.code.cpp.controlflow.Guards
1616
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
1717

18+
string target_api = "SSL_CTX_set_options"
19+
int target_index = 0
1820

1921
Expr getSinkExpr(FunctionCall fc)
2022
{
21-
result = fc.getArgument(0)
23+
result = fc.getArgument(target_index)
2224
}
2325

2426
predicate isSinkFC(FunctionCall fc)
2527
{
26-
fc.getTarget().hasName("SSL_CTX_set_options")
28+
29+
fc.getTarget().hasName(target_api)
2730
}
2831
DataFlow::Node getSinkNode(FunctionCall fc)
2932
{
@@ -48,27 +51,9 @@ class ParameterConfiguration extends DataFlow::Configuration {
4851
}
4952
}
5053

54+
55+
5156
// if every path after target exists node
52-
BasicBlock getLeakBBAfter(ControlFlowNode target) {
53-
not exists(ControlFlowNode node |
54-
node = getAfterNode()
55-
and
56-
target.getASuccessor*() = node
57-
and not
58-
exists(BasicBlock bb |
59-
not bb.getANode() = node
60-
and bb = target.getASuccessor*()
61-
and exists(ExitBasicBlock exit |
62-
bb.getASuccessor*() = exit)
63-
and target.getASuccessor*() = bb
64-
and not bb.getAPredecessor*() = node.getBasicBlock()
65-
and not bb.getASuccessor*() = node.getBasicBlock()
66-
and result = bb
67-
)
68-
)
69-
70-
71-
}
7257

7358
Expr getCheckExpr(FunctionCall fc)
7459
{

ql-code/uninitialize.ql

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,19 @@
2222
result = e
2323
and
2424
(
25-
(fc.getTarget().hasName("strlen") and e = fc.getArgument(0))
26-
or
27-
(fc.getTarget().hasName("test_init") and e = fc.getArgument(0))
25+
(fc.getTarget().hasName("initialize_expr") and e = fc.getArgument(0))
26+
// or
27+
// (fc.getTarget().hasName("test_init") and e = fc.getArgument(0))
2828
// TODO-addMallocHere
2929
)
3030
)
3131
}
3232

3333
predicate isSourceFC(FunctionCall fc)
3434
{
35-
fc.getTarget().hasName("test_init")
36-
or
37-
fc.getTarget().hasName("strlen")
35+
fc.getTarget().hasName("initialize")
36+
// or
37+
// fc.getTarget().hasName("strlen")
3838
}
3939

4040
DataFlow::Node getSourceNode(FunctionCall fc)
@@ -46,12 +46,14 @@
4646

4747
Expr getSinkExpr(FunctionCall fc)
4848
{
49-
result = fc.getArgument(0)
49+
isSinkFC(fc)
50+
and
51+
result = fc.getArgument(Target_INDEX)
5052
}
5153

5254
predicate isSinkFC(FunctionCall fc)
5355
{
54-
fc.getTarget().hasName("target")
56+
fc.getTarget().hasName("Target_API")
5557
}
5658
DataFlow::Node getSinkNode(FunctionCall fc)
5759
{

ql-code/use-after-free.ql

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Expr getMallocExpr(FunctionCall fc)
2121
result = e
2222
and
2323
(
24-
(fc.getTarget().hasName("malloc") and e = fc)
24+
(fc.getTarget().hasName("malloc_parameter") and e = fc)
2525
// or
2626
// (fc.getTarget().hasName("new_malloc") and e = fc.getArgument(0))
2727
// TODO-addMallocHere
@@ -41,11 +41,11 @@ FunctionCall getFreeClass()
4141
Expr getFreeExpr(FunctionCall fc)
4242
{
4343

44-
result = fc.getArgument(0)
44+
result = fc.getArgument(Target_INDEX)
4545
and
4646
(
4747
// TODO-Target-change
48-
fc.getTarget().hasName("target")
48+
fc.getTarget().hasName("Target_API")
4949
// or
5050
// fc.getTarget().hasName("new_free")
5151

@@ -61,7 +61,7 @@ Expr getFreeExpr(FunctionCall fc)
6161

6262
predicate isSinkFC(FunctionCall fc)
6363
{
64-
fc.getTarget().hasName("target")
64+
fc.getTarget().hasName("Target_API")
6565
// or
6666
// fc.getTarget().hasName("new_free")
6767
}

0 commit comments

Comments
 (0)