Skip to content

Commit 3143336

Browse files
committed
feat: add three new FFI detection passes and test suite
1 parent d8fc3cb commit 3143336

63 files changed

Lines changed: 2392767 additions & 42 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

corpus/ffi-dense/openssl_wrapper.bc.pp

Lines changed: 475 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 307 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,307 @@
1+
; ModuleID = 'sqlite_binding.c'
2+
source_filename = "sqlite_binding.c"
3+
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
4+
target triple = "arm64-apple-macosx15.0.0"
5+
6+
@.str = private unnamed_addr constant [20 x i8] c"SELECT * FROM users\00", align 1
7+
@.str.1 = private unnamed_addr constant [36 x i8] c"INSERT INTO users (name) VALUES (?)\00", align 1
8+
@.str.2 = private unnamed_addr constant [10 x i8] c"test_user\00", align 1
9+
@.str.3 = private unnamed_addr constant [36 x i8] c"SELECT name FROM users WHERE id = ?\00", align 1
10+
@.str.4 = private unnamed_addr constant [18 x i8] c"DELETE FROM users\00", align 1
11+
@.str.5 = private unnamed_addr constant [38 x i8] c"SELECT * FROM users WHERE name = '%s'\00", align 1
12+
@.str.6 = private unnamed_addr constant [31 x i8] c"SELECT name FROM users LIMIT 1\00", align 1
13+
@.str.7 = private unnamed_addr constant [10 x i8] c"User: %s\0A\00", align 1
14+
@.str.8 = private unnamed_addr constant [9 x i8] c":memory:\00", align 1
15+
@.str.9 = private unnamed_addr constant [55 x i8] c"CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)\00", align 1
16+
@.str.10 = private unnamed_addr constant [8 x i8] c"test.db\00", align 1
17+
18+
; Function Attrs: noinline nounwind optnone ssp uwtable(sync)
19+
define i32 @leak_database_open(ptr noundef %0) #0 {
20+
%2 = alloca i32, align 4
21+
%3 = alloca ptr, align 8
22+
%4 = alloca ptr, align 8
23+
%5 = alloca i32, align 4
24+
store ptr %0, ptr %3, align 8
25+
%6 = load ptr, ptr %3, align 8
26+
%7 = call i32 @sqlite3_open(ptr noundef %6, ptr noundef %4)
27+
store i32 %7, ptr %5, align 4
28+
%8 = load i32, ptr %5, align 4
29+
%9 = icmp ne i32 %8, 0
30+
br i1 %9, label %10, label %11
31+
32+
10: ; preds = %1
33+
store i32 -1, ptr %2, align 4
34+
br label %12
35+
36+
11: ; preds = %1
37+
store i32 0, ptr %2, align 4
38+
br label %12
39+
40+
12: ; preds = %11, %10
41+
%13 = load i32, ptr %2, align 4
42+
ret i32 %13
43+
}
44+
45+
declare i32 @sqlite3_open(ptr noundef, ptr noundef) #1
46+
47+
; Function Attrs: noinline nounwind optnone ssp uwtable(sync)
48+
define i32 @leak_statement(ptr noundef %0) #0 {
49+
%2 = alloca i32, align 4
50+
%3 = alloca ptr, align 8
51+
%4 = alloca ptr, align 8
52+
%5 = alloca ptr, align 8
53+
%6 = alloca i32, align 4
54+
store ptr %0, ptr %3, align 8
55+
store ptr @.str, ptr %5, align 8
56+
%7 = load ptr, ptr %3, align 8
57+
%8 = load ptr, ptr %5, align 8
58+
%9 = call i32 @sqlite3_prepare_v2(ptr noundef %7, ptr noundef %8, i32 noundef -1, ptr noundef %4, ptr noundef null)
59+
store i32 %9, ptr %6, align 4
60+
%10 = load i32, ptr %6, align 4
61+
%11 = icmp ne i32 %10, 0
62+
br i1 %11, label %12, label %13
63+
64+
12: ; preds = %1
65+
store i32 -1, ptr %2, align 4
66+
br label %16
67+
68+
13: ; preds = %1
69+
%14 = load ptr, ptr %4, align 8
70+
%15 = call i32 @sqlite3_step(ptr noundef %14)
71+
store i32 0, ptr %2, align 4
72+
br label %16
73+
74+
16: ; preds = %13, %12
75+
%17 = load i32, ptr %2, align 4
76+
ret i32 %17
77+
}
78+
79+
declare i32 @sqlite3_prepare_v2(ptr noundef, ptr noundef, i32 noundef, ptr noundef, ptr noundef) #1
80+
81+
declare i32 @sqlite3_step(ptr noundef) #1
82+
83+
; Function Attrs: noinline nounwind optnone ssp uwtable(sync)
84+
define i32 @bind_dangling_pointer(ptr noundef %0) #0 {
85+
%2 = alloca ptr, align 8
86+
%3 = alloca ptr, align 8
87+
%4 = alloca ptr, align 8
88+
%5 = alloca ptr, align 8
89+
store ptr %0, ptr %2, align 8
90+
store ptr @.str.1, ptr %4, align 8
91+
%6 = load ptr, ptr %2, align 8
92+
%7 = load ptr, ptr %4, align 8
93+
%8 = call i32 @sqlite3_prepare_v2(ptr noundef %6, ptr noundef %7, i32 noundef -1, ptr noundef %3, ptr noundef null)
94+
%9 = call ptr @malloc(i64 noundef 20) #5
95+
store ptr %9, ptr %5, align 8
96+
%10 = load ptr, ptr %5, align 8
97+
%11 = load ptr, ptr %5, align 8
98+
%12 = call i64 @llvm.objectsize.i64.p0(ptr %11, i1 false, i1 true, i1 false)
99+
%13 = call ptr @__strcpy_chk(ptr noundef %10, ptr noundef @.str.2, i64 noundef %12) #6
100+
%14 = load ptr, ptr %5, align 8
101+
call void @free(ptr noundef %14)
102+
%15 = load ptr, ptr %3, align 8
103+
%16 = load ptr, ptr %5, align 8
104+
%17 = call i32 @sqlite3_bind_text(ptr noundef %15, i32 noundef 1, ptr noundef %16, i32 noundef -1, ptr noundef inttoptr (i64 -1 to ptr))
105+
%18 = load ptr, ptr %3, align 8
106+
%19 = call i32 @sqlite3_finalize(ptr noundef %18)
107+
ret i32 0
108+
}
109+
110+
; Function Attrs: allocsize(0)
111+
declare ptr @malloc(i64 noundef) #2
112+
113+
; Function Attrs: nounwind
114+
declare ptr @__strcpy_chk(ptr noundef, ptr noundef, i64 noundef) #3
115+
116+
; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
117+
declare i64 @llvm.objectsize.i64.p0(ptr, i1 immarg, i1 immarg, i1 immarg) #4
118+
119+
declare void @free(ptr noundef) #1
120+
121+
declare i32 @sqlite3_bind_text(ptr noundef, i32 noundef, ptr noundef, i32 noundef, ptr noundef) #1
122+
123+
declare i32 @sqlite3_finalize(ptr noundef) #1
124+
125+
; Function Attrs: noinline nounwind optnone ssp uwtable(sync)
126+
define ptr @get_user_name_dangling(ptr noundef %0, i32 noundef %1) #0 {
127+
%3 = alloca ptr, align 8
128+
%4 = alloca i32, align 4
129+
%5 = alloca ptr, align 8
130+
%6 = alloca ptr, align 8
131+
%7 = alloca ptr, align 8
132+
store ptr %0, ptr %3, align 8
133+
store i32 %1, ptr %4, align 4
134+
store ptr @.str.3, ptr %6, align 8
135+
%8 = load ptr, ptr %3, align 8
136+
%9 = load ptr, ptr %6, align 8
137+
%10 = call i32 @sqlite3_prepare_v2(ptr noundef %8, ptr noundef %9, i32 noundef -1, ptr noundef %5, ptr noundef null)
138+
%11 = load ptr, ptr %5, align 8
139+
%12 = load i32, ptr %4, align 4
140+
%13 = call i32 @sqlite3_bind_int(ptr noundef %11, i32 noundef 1, i32 noundef %12)
141+
%14 = load ptr, ptr %5, align 8
142+
%15 = call i32 @sqlite3_step(ptr noundef %14)
143+
%16 = load ptr, ptr %5, align 8
144+
%17 = call ptr @sqlite3_column_text(ptr noundef %16, i32 noundef 0)
145+
store ptr %17, ptr %7, align 8
146+
%18 = load ptr, ptr %5, align 8
147+
%19 = call i32 @sqlite3_finalize(ptr noundef %18)
148+
%20 = load ptr, ptr %7, align 8
149+
ret ptr %20
150+
}
151+
152+
declare i32 @sqlite3_bind_int(ptr noundef, i32 noundef, i32 noundef) #1
153+
154+
declare ptr @sqlite3_column_text(ptr noundef, i32 noundef) #1
155+
156+
; Function Attrs: noinline nounwind optnone ssp uwtable(sync)
157+
define i32 @dangerous_exec(ptr noundef %0) #0 {
158+
%2 = alloca ptr, align 8
159+
%3 = alloca ptr, align 8
160+
store ptr %0, ptr %2, align 8
161+
store ptr @.str.4, ptr %3, align 8
162+
%4 = load ptr, ptr %2, align 8
163+
%5 = load ptr, ptr %3, align 8
164+
%6 = call i32 @sqlite3_exec(ptr noundef %4, ptr noundef %5, ptr noundef null, ptr noundef null, ptr noundef null)
165+
ret i32 0
166+
}
167+
168+
declare i32 @sqlite3_exec(ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef) #1
169+
170+
; Function Attrs: noinline nounwind optnone ssp uwtable(sync)
171+
define i32 @sql_injection(ptr noundef %0, ptr noundef %1) #0 {
172+
%3 = alloca ptr, align 8
173+
%4 = alloca ptr, align 8
174+
%5 = alloca [256 x i8], align 1
175+
%6 = alloca ptr, align 8
176+
store ptr %0, ptr %3, align 8
177+
store ptr %1, ptr %4, align 8
178+
%7 = getelementptr inbounds [256 x i8], ptr %5, i64 0, i64 0
179+
%8 = load ptr, ptr %4, align 8
180+
%9 = call i32 (ptr, i32, i64, ptr, ...) @__sprintf_chk(ptr noundef %7, i32 noundef 0, i64 noundef 256, ptr noundef @.str.5, ptr noundef %8)
181+
store ptr null, ptr %6, align 8
182+
%10 = load ptr, ptr %3, align 8
183+
%11 = getelementptr inbounds [256 x i8], ptr %5, i64 0, i64 0
184+
%12 = call i32 @sqlite3_exec(ptr noundef %10, ptr noundef %11, ptr noundef null, ptr noundef null, ptr noundef %6)
185+
%13 = load ptr, ptr %6, align 8
186+
%14 = icmp ne ptr %13, null
187+
br i1 %14, label %15, label %17
188+
189+
15: ; preds = %2
190+
%16 = load ptr, ptr %6, align 8
191+
call void @sqlite3_free(ptr noundef %16)
192+
br label %17
193+
194+
17: ; preds = %15, %2
195+
ret i32 0
196+
}
197+
198+
declare i32 @__sprintf_chk(ptr noundef, i32 noundef, i64 noundef, ptr noundef, ...) #1
199+
200+
declare void @sqlite3_free(ptr noundef) #1
201+
202+
; Function Attrs: noinline nounwind optnone ssp uwtable(sync)
203+
define i32 @correct_usage(ptr noundef %0) #0 {
204+
%2 = alloca i32, align 4
205+
%3 = alloca ptr, align 8
206+
%4 = alloca ptr, align 8
207+
%5 = alloca i32, align 4
208+
%6 = alloca ptr, align 8
209+
%7 = alloca ptr, align 8
210+
%8 = alloca ptr, align 8
211+
store ptr %0, ptr %3, align 8
212+
%9 = load ptr, ptr %3, align 8
213+
%10 = call i32 @sqlite3_open(ptr noundef %9, ptr noundef %4)
214+
store i32 %10, ptr %5, align 4
215+
%11 = load i32, ptr %5, align 4
216+
%12 = icmp ne i32 %11, 0
217+
br i1 %12, label %13, label %16
218+
219+
13: ; preds = %1
220+
%14 = load ptr, ptr %4, align 8
221+
%15 = call i32 @sqlite3_close(ptr noundef %14)
222+
store i32 -1, ptr %2, align 4
223+
br label %39
224+
225+
16: ; preds = %1
226+
store ptr @.str.6, ptr %7, align 8
227+
%17 = load ptr, ptr %4, align 8
228+
%18 = load ptr, ptr %7, align 8
229+
%19 = call i32 @sqlite3_prepare_v2(ptr noundef %17, ptr noundef %18, i32 noundef -1, ptr noundef %6, ptr noundef null)
230+
store i32 %19, ptr %5, align 4
231+
%20 = load i32, ptr %5, align 4
232+
%21 = icmp ne i32 %20, 0
233+
br i1 %21, label %22, label %25
234+
235+
22: ; preds = %16
236+
%23 = load ptr, ptr %4, align 8
237+
%24 = call i32 @sqlite3_close(ptr noundef %23)
238+
store i32 -1, ptr %2, align 4
239+
br label %39
240+
241+
25: ; preds = %16
242+
%26 = load ptr, ptr %6, align 8
243+
%27 = call i32 @sqlite3_step(ptr noundef %26)
244+
%28 = icmp eq i32 %27, 100
245+
br i1 %28, label %29, label %34
246+
247+
29: ; preds = %25
248+
%30 = load ptr, ptr %6, align 8
249+
%31 = call ptr @sqlite3_column_text(ptr noundef %30, i32 noundef 0)
250+
store ptr %31, ptr %8, align 8
251+
%32 = load ptr, ptr %8, align 8
252+
%33 = call i32 (ptr, ...) @printf(ptr noundef @.str.7, ptr noundef %32)
253+
br label %34
254+
255+
34: ; preds = %29, %25
256+
%35 = load ptr, ptr %6, align 8
257+
%36 = call i32 @sqlite3_finalize(ptr noundef %35)
258+
%37 = load ptr, ptr %4, align 8
259+
%38 = call i32 @sqlite3_close(ptr noundef %37)
260+
store i32 0, ptr %2, align 4
261+
br label %39
262+
263+
39: ; preds = %34, %22, %13
264+
%40 = load i32, ptr %2, align 4
265+
ret i32 %40
266+
}
267+
268+
declare i32 @sqlite3_close(ptr noundef) #1
269+
270+
declare i32 @printf(ptr noundef, ...) #1
271+
272+
; Function Attrs: noinline nounwind optnone ssp uwtable(sync)
273+
define i32 @main() #0 {
274+
%1 = alloca i32, align 4
275+
%2 = alloca ptr, align 8
276+
store i32 0, ptr %1, align 4
277+
%3 = call i32 @sqlite3_open(ptr noundef @.str.8, ptr noundef %2)
278+
%4 = load ptr, ptr %2, align 8
279+
%5 = call i32 @sqlite3_exec(ptr noundef %4, ptr noundef @.str.9, ptr noundef null, ptr noundef null, ptr noundef null)
280+
%6 = call i32 @leak_database_open(ptr noundef @.str.10)
281+
%7 = load ptr, ptr %2, align 8
282+
%8 = call i32 @leak_statement(ptr noundef %7)
283+
%9 = load ptr, ptr %2, align 8
284+
%10 = call i32 @bind_dangling_pointer(ptr noundef %9)
285+
%11 = load ptr, ptr %2, align 8
286+
%12 = call i32 @dangerous_exec(ptr noundef %11)
287+
%13 = load ptr, ptr %2, align 8
288+
%14 = call i32 @sqlite3_close(ptr noundef %13)
289+
ret i32 0
290+
}
291+
292+
attributes #0 = { noinline nounwind optnone ssp uwtable(sync) "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+altnzcv,+ccdp,+ccidx,+ccpp,+complxnum,+crc,+dit,+dotprod,+flagm,+fp-armv8,+fp16fml,+fptoint,+fullfp16,+jsconv,+lse,+neon,+pauth,+perfmon,+predres,+ras,+rcpc,+rdm,+sb,+sha2,+sha3,+specrestrict,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a" }
293+
attributes #1 = { "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+altnzcv,+ccdp,+ccidx,+ccpp,+complxnum,+crc,+dit,+dotprod,+flagm,+fp-armv8,+fp16fml,+fptoint,+fullfp16,+jsconv,+lse,+neon,+pauth,+perfmon,+predres,+ras,+rcpc,+rdm,+sb,+sha2,+sha3,+specrestrict,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a" }
294+
attributes #2 = { allocsize(0) "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+altnzcv,+ccdp,+ccidx,+ccpp,+complxnum,+crc,+dit,+dotprod,+flagm,+fp-armv8,+fp16fml,+fptoint,+fullfp16,+jsconv,+lse,+neon,+pauth,+perfmon,+predres,+ras,+rcpc,+rdm,+sb,+sha2,+sha3,+specrestrict,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a" }
295+
attributes #3 = { nounwind "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+altnzcv,+ccdp,+ccidx,+ccpp,+complxnum,+crc,+dit,+dotprod,+flagm,+fp-armv8,+fp16fml,+fptoint,+fullfp16,+jsconv,+lse,+neon,+pauth,+perfmon,+predres,+ras,+rcpc,+rdm,+sb,+sha2,+sha3,+specrestrict,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a" }
296+
attributes #4 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
297+
attributes #5 = { allocsize(0) }
298+
attributes #6 = { nounwind }
299+
300+
!llvm.module.flags = !{!0, !1, !2, !3}
301+
!llvm.ident = !{!4}
302+
303+
!0 = !{i32 1, !"wchar_size", i32 4}
304+
!1 = !{i32 8, !"PIC Level", i32 2}
305+
!2 = !{i32 7, !"uwtable", i32 1}
306+
!3 = !{i32 7, !"frame-pointer", i32 1}
307+
!4 = !{!"Homebrew clang version 21.1.8"}

0 commit comments

Comments
 (0)