Add full CFG of pkexec's main() function, in pdf format

This commit is contained in:
Michael Hohn
2022-03-03 22:12:20 -08:00
committed by =Michael Hohn
parent e687f55643
commit bc6b32c4c8
7 changed files with 6217 additions and 0 deletions

1
.gitattributes vendored
View File

@@ -1 +1,2 @@
*.zip filter=lfs diff=lfs merge=lfs -text
*.pdf filter=lfs diff=lfs merge=lfs -text

File diff suppressed because it is too large Load Diff

19
PrintCFG.ql Normal file
View File

@@ -0,0 +1,19 @@
/**
* @name Print part of the CFG
* @description Outputs a subset of the control flow graph
* @id cpp/example/polkit/cfg
* @kind graph
*/
import cpp
query predicate edges(ControlFlowNode n1, ControlFlowNode n2) {
n1.getASuccessor() = n2 and
n1.getControlFlowScope().getName() = "main" and
// polkit has many `main` functions, grab the one from pkexec.c
n1.getLocation().getFile().getBaseName() = "pkexec.c"
}
// For reference, see the file
// db/polkit-0.119.db/tmp/polkit/src/programs/pkexec.c
// (after extracting src.zip)

56
PrintCFG.sh Normal file
View File

@@ -0,0 +1,56 @@
#
# Print the CFG from the query in ./PrintCFG.ql
#
#* Add codeql binary PATH
export PATH=$HOME/local/codeql-2.7.6/codeql:"$PATH"
#* Graph in dgml format
cd ~/local/codeql-sample-polkit/
codeql database analyze \
./db/polkit-0.119.db \
./PrintCFG.ql \
--rerun \
-j8 -v --ram=16000 \
--search-path $HOME/local/codeql-2.7.6/ql \
--format=dgml \
--output=PrintCFG.dgml
# Clean up the dgml (xml) output
tidy -xml PrintCFG.dgml/cpp/example/polkit/cfg.dgml | sponge PrintCFG.dgml/cpp/example/polkit/cfg.dgml
# Convert dgml to dot
./dgml2dot < PrintCFG.dgml/cpp/example/polkit/cfg.dgml > cfg.dot
# Produce the DAG we really want
dot -Tpdf < cfg.dot > cfg.pdf
open cfg.pdf
# Faster than dot, as sanity check:
sfdp -Tpdf < cfg.dot > cfg.sfdp.pdf
open cfg.sfdp.pdf
#* Full dot graph from codeql
#
# The dot output from this was broken on [Mar- 3-2022]; use the above.
#
# cd ~/local/codeql-sample-polkit/
# codeql database analyze \
# ./db/polkit-0.119.db \
# ./PrintCFG.ql \
# -j8 -v --ram=16000 \
# --search-path $HOME/local/codeql-2.7.6/ql \
# --format=dot \
# --output=PrintCFG.dot
# # Query-produced .bqrs file
# ls db/polkit-0.119.db/results/cpp-polkit-argv/PrintCFG.bqrs
# # Query-produced .dot file
# ls PrintCFG.dot/cpp/example/polkit/cfg.dot
# # Generate SVG
# cd ~/local/codeql-sample-polkit/PrintIR-pkexec.dot/cpp/example/
# dot -Tsvg ./polkit-ir.dot > polkit-ir.svg

3032
cfg.dot Normal file

File diff suppressed because it is too large Load Diff

BIN
cfg.pdf Normal file

Binary file not shown.

35
dgml2dot Executable file
View File

@@ -0,0 +1,35 @@
#!/usr/bin/env python3
#
# Read dgml from stdin, write dot to stdout
#
import re
import sys
import xml.etree.ElementTree as ET
# Read source
xml = sys.stdin.read()
root = ET.fromstring(xml)
# Form dot element sequence
body_l = ["digraph qlast {",
"node [shape=box];",
]
for node in root.find("{http://schemas.microsoft.com/vs/2009/dgml}Nodes"):
att = node.attrib
keys = set(att.keys()) - set(['Id', 'Label'])
prop_l = ['{}="{}"'.format(key, att[key]) for key in keys]
prop_l.append('{}="{}"'.format("label", att["Label"]))
node_s = "nd_{} [{}];".format(att['Id'], ", ".join(prop_l))
body_l.append(node_s)
for edge in root.find("{http://schemas.microsoft.com/vs/2009/dgml}Links"):
att = edge.attrib
edge_s = 'nd_{} -> nd_{} [label="{}"];'.format(
att["Source"], att["Target"], att.get("Label", ""))
body_l.append(edge_s)
body_l.append("}")
# Write dot
sys.stdout.write("\n".join(body_l))