Add CFG of the copy_mem() function

This commit is contained in:
Michael Hohn
2025-03-17 19:13:24 -07:00
committed by =Michael Hohn
parent 75f0ec79bd
commit 92d605aa7a
6 changed files with 329 additions and 1 deletions

213
cfg.dot/cpp/print-cfg.dot Normal file
View File

@@ -0,0 +1,213 @@
digraph {
compound=true;
0[label="ExprStmt"; ];
1[label="call to memcpy"; ];
2[label="input"; ];
3[label="0"; ];
4[label="access to array"; ];
5[label="ptr"; ];
6[label="buf"; ];
7[label="input"; ];
8[label="1"; ];
9[label="access to array"; ];
10[label="ptr"; ];
11[label="buf"; ];
12[label="input"; ];
13[label="1"; ];
14[label="access to array"; ];
15[label="ptr"; ];
16[label="size"; ];
17[label="ExprStmt"; ];
18[label="call to copy_mem_nested"; ];
19[label="input"; ];
20[label="if (...) ... "; ];
21[label="input_types"; ];
22[label="call to DYN_INPUT_TYPE"; ];
23[label="1"; ];
24[label="1"; ];
25[label="... != ..."; ];
26[label="{ ... }"; ];
27[label="ExprStmt"; ];
28[label="call to memcpy"; ];
29[label="input"; ];
30[label="0"; ];
31[label="access to array"; ];
32[label="ptr"; ];
33[label="buf"; ];
34[label="input"; ];
35[label="1"; ];
36[label="access to array"; ];
37[label="ptr"; ];
38[label="buf"; ];
39[label="input"; ];
40[label="1"; ];
41[label="access to array"; ];
42[label="ptr"; ];
43[label="size"; ];
44[label="ExprStmt"; ];
45[label="call to copy_mem_nested"; ];
46[label="input"; ];
47[label="if (...) ... "; ];
48[label="call to DYN_INPUT_TYPE"; ];
49[label="1"; ];
50[label="1"; ];
51[label="100"; ];
52[label="... == ..."; ];
53[label="ExprStmt"; ];
54[label="call to memcpy"; ];
55[label="input"; ];
56[label="0"; ];
57[label="access to array"; ];
58[label="ptr"; ];
59[label="buf"; ];
60[label="input"; ];
61[label="1"; ];
62[label="access to array"; ];
63[label="ptr"; ];
64[label="buf"; ];
65[label="input"; ];
66[label="1"; ];
67[label="access to array"; ];
68[label="ptr"; ];
69[label="size"; ];
70[label="{ ... }"; ];
71[label="if (...) ... "; ];
72[label="input_types"; ];
73[label="call to DYN_INPUT_TYPE"; ];
74[label="1"; ];
75[label="1"; ];
76[label="... != ..."; ];
77[label="return ..."; ];
78[label="1"; ];
79[label="{ ... }"; ];
80[label="ExprStmt"; ];
81[label="call to memcpy"; ];
82[label="input"; ];
83[label="0"; ];
84[label="access to array"; ];
85[label="ptr"; ];
86[label="buf"; ];
87[label="input"; ];
88[label="1"; ];
89[label="access to array"; ];
90[label="ptr"; ];
91[label="buf"; ];
92[label="input"; ];
93[label="1"; ];
94[label="access to array"; ];
95[label="ptr"; ];
96[label="size"; ];
97[label="ExprStmt"; ];
98[label="call to copy_mem_nested"; ];
99[label="input"; ];
100[label="return ..."; ];
101[label="0"; ];
102[label="{ ... }"; ];
103[label="copy_mem"; ];
0 -> 2[];
1 -> 17[];
2 -> 3[];
3 -> 4[];
4 -> 5[];
5 -> 6[];
6 -> 7[];
7 -> 8[];
8 -> 9[];
9 -> 10[];
10 -> 11[];
11 -> 12[];
12 -> 13[];
13 -> 14[];
14 -> 15[];
15 -> 16[];
16 -> 1[];
17 -> 19[];
18 -> 20[];
19 -> 18[];
20 -> 21[];
21 -> 23[];
22 -> 25[];
23 -> 24[];
24 -> 22[];
25 -> 26[];
25 -> 27[];
26 -> 27[];
27 -> 29[];
28 -> 44[];
29 -> 30[];
30 -> 31[];
31 -> 32[];
32 -> 33[];
33 -> 34[];
34 -> 35[];
35 -> 36[];
36 -> 37[];
37 -> 38[];
38 -> 39[];
39 -> 40[];
40 -> 41[];
41 -> 42[];
42 -> 43[];
43 -> 28[];
44 -> 46[];
45 -> 47[];
46 -> 45[];
47 -> 49[];
48 -> 51[];
49 -> 50[];
50 -> 48[];
51 -> 52[];
52 -> 70[];
52 -> 71[];
53 -> 55[];
54 -> 71[];
55 -> 56[];
56 -> 57[];
57 -> 58[];
58 -> 59[];
59 -> 60[];
60 -> 61[];
61 -> 62[];
62 -> 63[];
63 -> 64[];
64 -> 65[];
65 -> 66[];
66 -> 67[];
67 -> 68[];
68 -> 69[];
69 -> 54[];
70 -> 53[];
71 -> 72[];
72 -> 74[];
73 -> 76[];
74 -> 75[];
75 -> 73[];
76 -> 79[];
76 -> 80[];
77 -> 78[];
78 -> 103[];
79 -> 77[];
80 -> 82[];
81 -> 97[];
82 -> 83[];
83 -> 84[];
84 -> 85[];
85 -> 86[];
86 -> 87[];
87 -> 88[];
88 -> 89[];
89 -> 90[];
90 -> 91[];
91 -> 92[];
92 -> 93[];
93 -> 94[];
94 -> 95[];
95 -> 96[];
96 -> 81[];
97 -> 99[];
98 -> 100[];
99 -> 98[];
100 -> 101[];
101 -> 103[];
102 -> 0[];
}

BIN
cfg.dot/cpp/print-cfg.pdf Normal file

Binary file not shown.

81
graphs/cfg.ql Normal file
View File

@@ -0,0 +1,81 @@
/**
* @name Print part of the CFG
* @description Outputs a subset of the control flow graph
* @id cpp/print-cfg
* @kind graph
*/
// The CFG is large. Just show the part for
// int copy_mem(unsigned int unused, dyn_input_t *input,
// unsigned int input_types)
import cpp
predicate allSuccessors3(int distance, ControlFlowNode n1, ControlFlowNode n2) {
// n1.getASuccessor*() = n2 and
distance = 0 and n1 = n2
or
distance = 1 and n1 = n2.getAPredecessor()
or
distance = 2 and n1 = n2.getAPredecessor().getAPredecessor()
or
// allSuccessors3(distance-1, n2.getAPredecessor(), n2)
// or
exists(ControlFlowNode mid |
// // n1 -> mid
// n1 = mid.getAPredecessor() and
// // mid -> n2
// allSuccessors3(distance-1, mid, n2)
// --- right-to-left recursion
// n1 -> mid
distance < 12 and
allSuccessors3(distance - 1, n1, mid) and
// mid -> n2
mid = n2.getAPredecessor()
)
}
predicate allSuccessors1(ControlFlowNode n1, ControlFlowNode n2) {
// n1.getASuccessor*() = n2 and
n1 = n2
or
// n2 = n1.getASuccessor()
exists(ControlFlowNode mid |
allSuccessors1(n1, mid) and
n2 = mid.getASuccessor()
)
}
query predicate nodes(ControlFlowNode n1, string key, string value) {
exists(ControlFlowNode startFrom |
(edges(n1, _) or edges(_, n1)) and
(
if startFrom.getASuccessor*() = n1
then (
key = "color" and value = "red"
or
key = "line" and value = n1.getLocation().getStartLine().toString()
) else (
key = "color" and value = "black"
or
key = "line" and value = n1.getLocation().getStartLine().toString()
)
)
)
}
// query predicate edgesDist(ControlFlowNode n1, ControlFlowNode n2, int distance) {
// distance = 12 and
// // allSuccessors3(distance, n1, n2) and
// n1.(Function).hasName("copy_mem") and
// n2 = n1.getASuccessor+()
// }
query predicate edges(ControlFlowNode n1, ControlFlowNode n2) {
exists(ControlFlowNode t1, ControlFlowNode t2 |
t1.(Function).hasName("copy_mem") and
t2 = t1.(Function).getEntryPoint() and
n1 = t2.getASuccessor*() and
n1 = n2.getAPredecessor()
)
}

6
graphs/qlpack.yml Normal file
View File

@@ -0,0 +1,6 @@
---
library: false
name: graphs
version: 0.0.1
dependencies:
codeql/cpp-all: 0.6.1

View File

@@ -1,4 +1,4 @@
* Some low-level codeql
* CodeQL AST in dot and pdf
#+BEGIN_SRC sh
# Produce ast in dot format
codeql database analyze \
@@ -22,3 +22,31 @@
# 3280 880 73% 1 file
#+END_SRC
* CodeQL CFG in dot and pdf
XX: The whole control flow graph is very large, so the query narrows it to the
function of interest,
#+BEGIN_SRC c++
int copy_mem(unsigned int unused, dyn_input_t *input,
unsigned int input_types) {...}
#+END_SRC
from [[./tests-common/test_part1.c]]
#+BEGIN_SRC sh
# Produce CFG in dot format
codeql database analyze \
--format=dot --output=cfg.dot \
-j8 -v --ram=16000 \
--rerun \
-- \
cpp-dataflow-part1-database \
graphs/cfg.ql
# Convert dot to pdf
dot -Tpdf < cfg.dot/cpp/print-cfg.dot > cfg.dot/cpp/print-cfg.pdf
# View the graph
open cfg.dot/cpp/print-cfg.pdf
#+END_SRC