mirror of
https://github.com/github/codeql.git
synced 2026-05-17 04:37:07 +02:00
Compare commits
691 Commits
ginsbach/E
...
codeql-cli
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
da3e5479df | ||
|
|
4df1c12876 | ||
|
|
fd82aeb1f8 | ||
|
|
65bf76e3ed | ||
|
|
8b5603cf71 | ||
|
|
6925d4e564 | ||
|
|
125a4b9b10 | ||
|
|
2ec6dafd18 | ||
|
|
9aebc58214 | ||
|
|
1fab97b765 | ||
|
|
0e9286dd34 | ||
|
|
b70836e241 | ||
|
|
33d05984c8 | ||
|
|
32e6d0934e | ||
|
|
7ede3aa516 | ||
|
|
0d91622d18 | ||
|
|
4323e6853f | ||
|
|
c8f4b287d1 | ||
|
|
7e93b99ff9 | ||
|
|
8691075aae | ||
|
|
5a91aa2105 | ||
|
|
abc58ac8b3 | ||
|
|
1dae787605 | ||
|
|
492e27b8e8 | ||
|
|
e589019e04 | ||
|
|
4ea6133042 | ||
|
|
c78818d7dd | ||
|
|
3bc1d47738 | ||
|
|
ee3e7e34ba | ||
|
|
c0638a5fcb | ||
|
|
5ca9c090a8 | ||
|
|
d6fddde6e0 | ||
|
|
43bca84310 | ||
|
|
5b152cfdec | ||
|
|
5540b9df71 | ||
|
|
6c00ceaec9 | ||
|
|
ac52a1b123 | ||
|
|
9d72fab287 | ||
|
|
3b8234ecec | ||
|
|
92bce4e432 | ||
|
|
9761580b7e | ||
|
|
8e474c946e | ||
|
|
37b508bf43 | ||
|
|
2c758a9842 | ||
|
|
8c6c28d61f | ||
|
|
75e545a67f | ||
|
|
cf21997c0f | ||
|
|
89dcad48f4 | ||
|
|
c2d0a12e1e | ||
|
|
13d9d8ad3f | ||
|
|
4b947db0f8 | ||
|
|
2951ae9c7c | ||
|
|
b2ee625268 | ||
|
|
478f39a967 | ||
|
|
6511e21f81 | ||
|
|
2192ed04be | ||
|
|
4140579dd6 | ||
|
|
7f659804e4 | ||
|
|
cfe25593ee | ||
|
|
466bf85a67 | ||
|
|
1b2f160b55 | ||
|
|
b1ee795225 | ||
|
|
621b4833f3 | ||
|
|
39f602c032 | ||
|
|
bb56b0d45b | ||
|
|
9a0c5877ea | ||
|
|
97cf15affc | ||
|
|
a20fed8ae5 | ||
|
|
a8cc14493f | ||
|
|
82387461ee | ||
|
|
b3dc6cba78 | ||
|
|
5da7ae877b | ||
|
|
199f2473e5 | ||
|
|
5f8c457295 | ||
|
|
91ced7ea0c | ||
|
|
cbe5561eb6 | ||
|
|
83fe9e0d51 | ||
|
|
31a73d466b | ||
|
|
56ae8684e1 | ||
|
|
fcc3800756 | ||
|
|
091163bf8e | ||
|
|
78c40e209b | ||
|
|
574bb871e0 | ||
|
|
329fd803e2 | ||
|
|
9d736723fb | ||
|
|
50785f7f21 | ||
|
|
63e5c52d7e | ||
|
|
f5605c94c5 | ||
|
|
12942667bf | ||
|
|
605c8e201e | ||
|
|
604af65b02 | ||
|
|
709c111522 | ||
|
|
3a977b86d4 | ||
|
|
5d6c4a63bb | ||
|
|
49ecc60c0f | ||
|
|
d1da041fcf | ||
|
|
8432f6e42e | ||
|
|
965f1fc547 | ||
|
|
f148f434e1 | ||
|
|
019447b681 | ||
|
|
ad391df03f | ||
|
|
defd4a1d08 | ||
|
|
f1df63657b | ||
|
|
28d3a6b404 | ||
|
|
766b0bf773 | ||
|
|
68a96a44d8 | ||
|
|
ff54dfe8aa | ||
|
|
2c03d1f14a | ||
|
|
2cc732e235 | ||
|
|
26296c44d3 | ||
|
|
a883db0935 | ||
|
|
12ebf717eb | ||
|
|
0245cd872c | ||
|
|
69d50e103f | ||
|
|
68f0dfe046 | ||
|
|
4f6b698ca3 | ||
|
|
f432cf9c4d | ||
|
|
09dd708086 | ||
|
|
1189665970 | ||
|
|
a502bb1ac2 | ||
|
|
e0eadc75dd | ||
|
|
a1f4246c5f | ||
|
|
92a730c9ac | ||
|
|
cd3143f106 | ||
|
|
9a03f2eb26 | ||
|
|
65bd1aff83 | ||
|
|
dd8d04bb94 | ||
|
|
37cc78255a | ||
|
|
320f75fa51 | ||
|
|
43d14c28c2 | ||
|
|
997547b8ef | ||
|
|
5fb7541a94 | ||
|
|
825c813095 | ||
|
|
6efc19daac | ||
|
|
f7d822b19c | ||
|
|
96a32c0179 | ||
|
|
deb035cf4e | ||
|
|
0b7111b867 | ||
|
|
74cd982aca | ||
|
|
6b366d8384 | ||
|
|
79cc7318ba | ||
|
|
1945fb8258 | ||
|
|
43ac82f6a3 | ||
|
|
d53dada67f | ||
|
|
ec3ad85504 | ||
|
|
c8632b70b7 | ||
|
|
796cb193fc | ||
|
|
fc8a662f0d | ||
|
|
05572b49de | ||
|
|
ad9b637bec | ||
|
|
ad5c5acae5 | ||
|
|
472a6b5fe1 | ||
|
|
0ec10e5c30 | ||
|
|
28850460b2 | ||
|
|
d5cdfc673e | ||
|
|
fbee6bbe21 | ||
|
|
8ebebf03c2 | ||
|
|
ac6715fb3a | ||
|
|
71a5e410d7 | ||
|
|
937e3dc469 | ||
|
|
441cefd0bd | ||
|
|
27e5251285 | ||
|
|
804ffdb682 | ||
|
|
0e8c137a98 | ||
|
|
620d228ffa | ||
|
|
46ebf503c7 | ||
|
|
ca8fe033d7 | ||
|
|
43b2977cb4 | ||
|
|
bdcecdfc2c | ||
|
|
475d872ffb | ||
|
|
d64a9368d2 | ||
|
|
bc2e7d4e0d | ||
|
|
f6975117fe | ||
|
|
d9f47bdec9 | ||
|
|
7883124abd | ||
|
|
12732525b5 | ||
|
|
8ccb2ed059 | ||
|
|
ededa3c006 | ||
|
|
2f84a4a5b5 | ||
|
|
6d33a7ec70 | ||
|
|
f2dd96ecf4 | ||
|
|
57f1d07b2b | ||
|
|
05df1d3cb9 | ||
|
|
24c28ed873 | ||
|
|
ea4af8323c | ||
|
|
7888dcbce2 | ||
|
|
3785dbec9e | ||
|
|
b3b139bb02 | ||
|
|
45b627df1d | ||
|
|
bc0b383595 | ||
|
|
b688df9dec | ||
|
|
2d734056b1 | ||
|
|
74b37e71a0 | ||
|
|
19e5c3d805 | ||
|
|
919fea53f0 | ||
|
|
1c6ecf1216 | ||
|
|
0cf1195678 | ||
|
|
0bcdb421ed | ||
|
|
54546f6e99 | ||
|
|
8353fdd041 | ||
|
|
b33058c967 | ||
|
|
44bb5e7220 | ||
|
|
6134518d60 | ||
|
|
94386f0550 | ||
|
|
49e03b4dfd | ||
|
|
7aced48443 | ||
|
|
5c2cf79785 | ||
|
|
c2ddf25f11 | ||
|
|
996de78a66 | ||
|
|
1485d7072d | ||
|
|
4342b2b799 | ||
|
|
b1e723991e | ||
|
|
6dea73b081 | ||
|
|
cd3fa64ee3 | ||
|
|
2f29459cda | ||
|
|
36ebe99f2f | ||
|
|
af977e9ac7 | ||
|
|
a807db52ad | ||
|
|
acc66c7b58 | ||
|
|
6629bd8279 | ||
|
|
b361f76643 | ||
|
|
448cc82ef9 | ||
|
|
54775e0958 | ||
|
|
e7a6259bd7 | ||
|
|
fbe79e8a52 | ||
|
|
680e31dc48 | ||
|
|
53e1939b60 | ||
|
|
01738c2e42 | ||
|
|
eabe651edf | ||
|
|
29a6af4efd | ||
|
|
f319381f27 | ||
|
|
9b8302f983 | ||
|
|
805e31fdb9 | ||
|
|
807ab986f4 | ||
|
|
a9fb49a2c3 | ||
|
|
2709bf0615 | ||
|
|
7d4a70cc1d | ||
|
|
ad60aff860 | ||
|
|
fdd1e3fefe | ||
|
|
8b953e4f22 | ||
|
|
df4b338c5d | ||
|
|
1990438376 | ||
|
|
24bea738c9 | ||
|
|
7f8829ad8e | ||
|
|
ca913b452c | ||
|
|
200d46f5c7 | ||
|
|
bbd7ed57ce | ||
|
|
e9fdca7d39 | ||
|
|
d6a3b2e91f | ||
|
|
c5357ff556 | ||
|
|
a537c0091e | ||
|
|
a508089df8 | ||
|
|
d264fb5865 | ||
|
|
70bf61dc57 | ||
|
|
8f8b0428ab | ||
|
|
eba901f610 | ||
|
|
95763dd225 | ||
|
|
5c05ff843a | ||
|
|
064c4fca12 | ||
|
|
3ae69d5f3d | ||
|
|
8ee16f68a7 | ||
|
|
13b40bbab4 | ||
|
|
4036140f4b | ||
|
|
8c82405b5b | ||
|
|
6384cf2e4f | ||
|
|
529712122c | ||
|
|
b9acaa0cbd | ||
|
|
a08d594371 | ||
|
|
58aa7588e5 | ||
|
|
54f11ca611 | ||
|
|
70bff4e726 | ||
|
|
16f3fc6c33 | ||
|
|
327c4b345d | ||
|
|
b71f9ae240 | ||
|
|
477edd215c | ||
|
|
9ef22fff8e | ||
|
|
10a678dcbd | ||
|
|
9c3e275e66 | ||
|
|
ac72f8523a | ||
|
|
c8eefb7c5c | ||
|
|
f84a3084f0 | ||
|
|
b13f11883c | ||
|
|
9e87095bed | ||
|
|
9661ee407f | ||
|
|
0f5be2d096 | ||
|
|
909f57261c | ||
|
|
16e9e8e836 | ||
|
|
7a7db0efe8 | ||
|
|
df5f76872f | ||
|
|
c199d0cbbe | ||
|
|
8858f213ff | ||
|
|
97e77944eb | ||
|
|
7c04c9f969 | ||
|
|
29cceeba1a | ||
|
|
2ed54d52ad | ||
|
|
26dae8144c | ||
|
|
d33cd71685 | ||
|
|
85d1e06335 | ||
|
|
c83895fdd2 | ||
|
|
1d36405084 | ||
|
|
03a9a1688e | ||
|
|
199587095a | ||
|
|
cbde11ddc9 | ||
|
|
21c030fa46 | ||
|
|
a825213c05 | ||
|
|
46627c677d | ||
|
|
87a8dccf7a | ||
|
|
31d0897f74 | ||
|
|
c941e917e7 | ||
|
|
72854537f4 | ||
|
|
77cab9d068 | ||
|
|
918700ff6f | ||
|
|
da0742f3ec | ||
|
|
30c6082b5d | ||
|
|
b43a0e758b | ||
|
|
e121579a85 | ||
|
|
9f59a3501c | ||
|
|
be7db8079a | ||
|
|
86ebf3d9f6 | ||
|
|
f07d8ee493 | ||
|
|
f4ba2e1fd0 | ||
|
|
c582a9ccd6 | ||
|
|
8b828cecf1 | ||
|
|
01ee3f7011 | ||
|
|
27f2000eff | ||
|
|
1f2e0683e7 | ||
|
|
cb6978063e | ||
|
|
c267a88f88 | ||
|
|
a6701ced8d | ||
|
|
d82d5c23bf | ||
|
|
391e9f7471 | ||
|
|
03e8865933 | ||
|
|
05e1cd437d | ||
|
|
e20ae48699 | ||
|
|
c95b5ce598 | ||
|
|
6ac0f0e031 | ||
|
|
68a37f99e3 | ||
|
|
14a362d1bc | ||
|
|
33ea822f40 | ||
|
|
30f705822d | ||
|
|
344535b559 | ||
|
|
4778ef616a | ||
|
|
88b4f971b5 | ||
|
|
1da42cb590 | ||
|
|
519905ee9e | ||
|
|
32e7a9d445 | ||
|
|
2f822cb0cd | ||
|
|
43accc50cd | ||
|
|
053a749e14 | ||
|
|
655b3de6bb | ||
|
|
649c8831ec | ||
|
|
0a18db8960 | ||
|
|
c6c6a857df | ||
|
|
2c45550a9f | ||
|
|
d1cf7f0624 | ||
|
|
232377a583 | ||
|
|
8f6f9f4359 | ||
|
|
edf6c7fbd6 | ||
|
|
a96d3d7be8 | ||
|
|
7764fbb664 | ||
|
|
8e4bd1a102 | ||
|
|
34fae324a0 | ||
|
|
4f538a2b1f | ||
|
|
6d0c8c6d77 | ||
|
|
df241ad4f6 | ||
|
|
ac13f408e4 | ||
|
|
4ab2977358 | ||
|
|
b53c3547d0 | ||
|
|
663c3e7b6d | ||
|
|
11cba94032 | ||
|
|
6736dd4e8f | ||
|
|
53ee565fdb | ||
|
|
76544f2966 | ||
|
|
742139927c | ||
|
|
07598e8b62 | ||
|
|
006d77ffdd | ||
|
|
1d7d45e16b | ||
|
|
8cd357a8a0 | ||
|
|
1e9520c737 | ||
|
|
123458fd21 | ||
|
|
6de5a618f3 | ||
|
|
6d8e2f8231 | ||
|
|
01c75e38f7 | ||
|
|
1b794e056a | ||
|
|
7be938c6c3 | ||
|
|
75078346c0 | ||
|
|
c39e5a7d97 | ||
|
|
3a0def7848 | ||
|
|
fefb35bede | ||
|
|
96c379a076 | ||
|
|
7ba18fa5d0 | ||
|
|
214969feaf | ||
|
|
439cf7a659 | ||
|
|
b32a8c2489 | ||
|
|
990b7f0b70 | ||
|
|
0c075abe3f | ||
|
|
a6b4a18d51 | ||
|
|
8f95e26ed6 | ||
|
|
99e62d66e5 | ||
|
|
2cd4d984cc | ||
|
|
117e330d53 | ||
|
|
3debd1ada9 | ||
|
|
70476c0e14 | ||
|
|
7ddc909d4e | ||
|
|
1351f57d2b | ||
|
|
dda4a97080 | ||
|
|
054bbc2ff7 | ||
|
|
b547dc4621 | ||
|
|
c7d20eb98a | ||
|
|
ebde0bdc47 | ||
|
|
95c2b9f8f7 | ||
|
|
89cf215ebb | ||
|
|
2062a774fc | ||
|
|
d198a964e0 | ||
|
|
675a072639 | ||
|
|
e362e536c0 | ||
|
|
d4de56c157 | ||
|
|
0739c03d03 | ||
|
|
d7094a96b5 | ||
|
|
b573246639 | ||
|
|
767d55bb18 | ||
|
|
c7a3b6543e | ||
|
|
399967b507 | ||
|
|
2907861075 | ||
|
|
acc06fab20 | ||
|
|
4dea5eef70 | ||
|
|
ab9ba02ea1 | ||
|
|
cc5e6b2195 | ||
|
|
18760b4025 | ||
|
|
1723c6ed09 | ||
|
|
9f260cf72f | ||
|
|
9de3617032 | ||
|
|
7c5cdd9a9b | ||
|
|
51f639111b | ||
|
|
8177b0938d | ||
|
|
928b7475b2 | ||
|
|
ae3253b9c3 | ||
|
|
3bff6c4a4a | ||
|
|
5edb60ea04 | ||
|
|
c3c8d5db13 | ||
|
|
e57b272cfa | ||
|
|
e40e4c3856 | ||
|
|
fb693837e4 | ||
|
|
36720ca4dd | ||
|
|
d20bc98363 | ||
|
|
6c9c8904d7 | ||
|
|
dfbdd2bd02 | ||
|
|
47a4ba33a4 | ||
|
|
a034e29040 | ||
|
|
097ac69207 | ||
|
|
8d0c14ca4e | ||
|
|
4281fe74bd | ||
|
|
4397863586 | ||
|
|
597f678978 | ||
|
|
c415795595 | ||
|
|
3ffda2f341 | ||
|
|
3bb3fccfdb | ||
|
|
e1f2433dbf | ||
|
|
22aa7f378a | ||
|
|
1124355cdb | ||
|
|
5a1246a586 | ||
|
|
0d7a842e2f | ||
|
|
f1e9f0e323 | ||
|
|
5722084dd5 | ||
|
|
db954d6d9f | ||
|
|
5b7485d11d | ||
|
|
156f867c96 | ||
|
|
9393181c4e | ||
|
|
a5333ae1a1 | ||
|
|
98195db500 | ||
|
|
5d6a5d5cbb | ||
|
|
f4f919635a | ||
|
|
b1d5b8175c | ||
|
|
d19259e6bb | ||
|
|
7211f4ace3 | ||
|
|
22b833fbda | ||
|
|
990043ce86 | ||
|
|
71703aa497 | ||
|
|
4f1ca21ef9 | ||
|
|
5f7d746266 | ||
|
|
d437a096f1 | ||
|
|
b51940d1e2 | ||
|
|
ccbf7055f1 | ||
|
|
d16570b05e | ||
|
|
c4def103f7 | ||
|
|
15de398806 | ||
|
|
a0c9c98373 | ||
|
|
fd8b37cc28 | ||
|
|
09a2aeead6 | ||
|
|
f940cb2bdd | ||
|
|
2a207f9f6f | ||
|
|
73f854f073 | ||
|
|
411aa6d2e5 | ||
|
|
3dabd51cf7 | ||
|
|
1518cade7b | ||
|
|
813ce7d3f8 | ||
|
|
f2805ba80c | ||
|
|
82fe647a40 | ||
|
|
528389af38 | ||
|
|
a2d4f58af7 | ||
|
|
2cd0c64e41 | ||
|
|
e0cb1792bd | ||
|
|
6876838dd1 | ||
|
|
7701a31f4a | ||
|
|
52abf3ba02 | ||
|
|
f57d691424 | ||
|
|
6fdec47e83 | ||
|
|
c7de873a22 | ||
|
|
a1e9a4eddf | ||
|
|
2195f0bb78 | ||
|
|
e5b4a15e35 | ||
|
|
33e63109bb | ||
|
|
24a0ac1223 | ||
|
|
aef357c757 | ||
|
|
8114071804 | ||
|
|
bb0173c9af | ||
|
|
7721d14314 | ||
|
|
da2f0f6069 | ||
|
|
7556d7b57b | ||
|
|
fad5e0daa8 | ||
|
|
a25330e6ed | ||
|
|
f12daefabe | ||
|
|
8d16d0225c | ||
|
|
a486549956 | ||
|
|
6013c347df | ||
|
|
7bb3758093 | ||
|
|
a004d9b2a2 | ||
|
|
fd733676cb | ||
|
|
eb30233d44 | ||
|
|
8c90250dfc | ||
|
|
6a9ed88d6e | ||
|
|
d6d7c6d55f | ||
|
|
463ae4b1eb | ||
|
|
0788a90d88 | ||
|
|
d10b9e665c | ||
|
|
7c5b186c71 | ||
|
|
f714e5c5ba | ||
|
|
84e5f2846b | ||
|
|
5c9a401806 | ||
|
|
52bbfa30d2 | ||
|
|
b3225cf7e3 | ||
|
|
379c913ce3 | ||
|
|
e33ddce79f | ||
|
|
d1dd05e7bb | ||
|
|
d010b6eb01 | ||
|
|
3d435ddca0 | ||
|
|
2908570ce9 | ||
|
|
b185cc8b95 | ||
|
|
e68d10119b | ||
|
|
799f33eb3a | ||
|
|
9dd3b33410 | ||
|
|
2b2bd17d10 | ||
|
|
785e0273f2 | ||
|
|
cda671711f | ||
|
|
24728a3417 | ||
|
|
e89662beb7 | ||
|
|
6124940f55 | ||
|
|
da924efedb | ||
|
|
5b26a426dc | ||
|
|
56490732bd | ||
|
|
831509539b | ||
|
|
de71758236 | ||
|
|
8fda879461 | ||
|
|
dee1ec31ee | ||
|
|
d8574a6919 | ||
|
|
ba01a70e0a | ||
|
|
ab74946e26 | ||
|
|
a02aabe797 | ||
|
|
838290d670 | ||
|
|
72b4e67477 | ||
|
|
a4de3110ae | ||
|
|
dd8af3baf7 | ||
|
|
11c4a638bc | ||
|
|
aefd941135 | ||
|
|
f810e17d9e | ||
|
|
b79e2dd0ba | ||
|
|
f58064e119 | ||
|
|
af1c4e0896 | ||
|
|
60a1d02357 | ||
|
|
e00b5351a4 | ||
|
|
c46b528c05 | ||
|
|
cce17743bb | ||
|
|
2924faf7f8 | ||
|
|
552e156468 | ||
|
|
1289f1483f | ||
|
|
bb45d0632b | ||
|
|
649091c0ed | ||
|
|
425448a10a | ||
|
|
064708620f | ||
|
|
98319ce2ad | ||
|
|
9728dbb247 | ||
|
|
d4bc38462f | ||
|
|
5e8b12a08b | ||
|
|
c10d89927d | ||
|
|
2fffa9db3c | ||
|
|
72bfbacaaf | ||
|
|
e6104981ff | ||
|
|
76678ef3d2 | ||
|
|
f825904ee0 | ||
|
|
5684ca5d51 | ||
|
|
4a2d795076 | ||
|
|
82d190f4bf | ||
|
|
a46b5f9529 | ||
|
|
d65da1f8a1 | ||
|
|
8b345518f4 | ||
|
|
d1b4172486 | ||
|
|
d85838477e | ||
|
|
47a90c8b32 | ||
|
|
c70198e4e4 | ||
|
|
f7195f04f8 | ||
|
|
b6d5225bf5 | ||
|
|
bf09c92528 | ||
|
|
63ccbec933 | ||
|
|
3e11dbded0 | ||
|
|
4b2025d2c4 | ||
|
|
2aad14771c | ||
|
|
7ef5586cc7 | ||
|
|
e56b9debf8 | ||
|
|
3027f75617 | ||
|
|
223f0c8684 | ||
|
|
cb6640474e | ||
|
|
59b74871c2 | ||
|
|
91072477b7 | ||
|
|
8f56f8d5a0 | ||
|
|
fa14f9540b | ||
|
|
0103ee2872 | ||
|
|
5289e4f424 | ||
|
|
02cdde1447 | ||
|
|
aef362152e | ||
|
|
c8b2674206 | ||
|
|
b1d4776b17 | ||
|
|
7cc248703a | ||
|
|
92dd5bd1f4 | ||
|
|
488da145e8 | ||
|
|
74b817b642 | ||
|
|
898c569f1b | ||
|
|
a72ae9c960 | ||
|
|
8efa38be79 | ||
|
|
e323833bc3 | ||
|
|
07f84a5add | ||
|
|
1cab99290e | ||
|
|
f5f12c2f81 | ||
|
|
ee9c4fa763 | ||
|
|
f5ac3fd611 | ||
|
|
6d389c31c7 | ||
|
|
fcb6882f16 | ||
|
|
e459884b69 | ||
|
|
fb92d9b034 | ||
|
|
8b2a424fb0 | ||
|
|
b71d09630a | ||
|
|
ace8b09a36 | ||
|
|
9d4c38b5f1 | ||
|
|
17a687b38f | ||
|
|
b82e84930c | ||
|
|
2a0c7c8801 | ||
|
|
de9dab9ba3 | ||
|
|
cd6975f7b7 | ||
|
|
0d803698ac | ||
|
|
f96a250ffc | ||
|
|
aca3d897a2 | ||
|
|
a9c4d6f383 | ||
|
|
38f00775bd | ||
|
|
07011f7460 | ||
|
|
f5daec9da0 | ||
|
|
81edb4780d | ||
|
|
704b3850f4 | ||
|
|
a0f4fa28b2 | ||
|
|
e3beacbda2 | ||
|
|
1ca5c593f9 | ||
|
|
9e54d53537 | ||
|
|
a34f9bef2b | ||
|
|
e84a98bd97 | ||
|
|
b4e710f459 | ||
|
|
fdb4362b6f | ||
|
|
3dc35f1fab | ||
|
|
c63c1be11c | ||
|
|
19416a9ee3 | ||
|
|
b6c9be23c1 | ||
|
|
42e7d1e983 | ||
|
|
9af2d0218b | ||
|
|
952e417d13 | ||
|
|
e564c41043 | ||
|
|
95be12ed80 | ||
|
|
b4a6063e20 | ||
|
|
ac94ac6584 | ||
|
|
055baf2769 | ||
|
|
aacbfc0fd8 | ||
|
|
a6e106e025 | ||
|
|
9fb00daeec | ||
|
|
bd75f0187b | ||
|
|
9a35febe80 |
35
.github/workflows/go-tests-other-os.yml
vendored
35
.github/workflows/go-tests-other-os.yml
vendored
@@ -1,35 +0,0 @@
|
||||
name: "Go: Run Tests - Other OS"
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "go/**"
|
||||
- "!go/documentation/**"
|
||||
- "!go/ql/**" # don't run other-os if only ql/ files changed
|
||||
- .github/workflows/go-tests-other-os.yml
|
||||
- .github/actions/**
|
||||
- codeql-workspace.yml
|
||||
- MODULE.bazel
|
||||
- .bazelrc
|
||||
- misc/bazel/**
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test-mac:
|
||||
name: Test MacOS
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
- name: Run tests
|
||||
uses: ./go/actions/test
|
||||
|
||||
test-win:
|
||||
name: Test Windows
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
- name: Run tests
|
||||
uses: ./go/actions/test
|
||||
22
.github/workflows/go-tests-rtjo.yml
vendored
22
.github/workflows/go-tests-rtjo.yml
vendored
@@ -1,22 +0,0 @@
|
||||
name: "Go: Run RTJO Tests"
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- labeled
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test-linux:
|
||||
if: "github.repository_owner == 'github' && github.event.label.name == 'Run: RTJO Language Tests'"
|
||||
name: RTJO Test Linux (Ubuntu)
|
||||
runs-on: ubuntu-latest-xl
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
- name: Run tests
|
||||
uses: ./go/actions/test
|
||||
with:
|
||||
run-code-checks: true
|
||||
dynamic-join-order-mode: all
|
||||
13
.github/workflows/go-tests.yml
vendored
13
.github/workflows/go-tests.yml
vendored
@@ -1,20 +1,9 @@
|
||||
name: "Go: Run Tests"
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- "go/**"
|
||||
- "!go/documentation/**"
|
||||
- "shared/**"
|
||||
- .github/workflows/go-tests.yml
|
||||
- .github/actions/**
|
||||
- codeql-workspace.yml
|
||||
branches:
|
||||
- main
|
||||
- "rc/*"
|
||||
pull_request:
|
||||
paths:
|
||||
- "go/**"
|
||||
- "!go/documentation/**"
|
||||
- "!go/documentation/**"
|
||||
- "shared/**"
|
||||
- .github/workflows/go-tests.yml
|
||||
- .github/actions/**
|
||||
|
||||
27
MODULE.bazel
27
MODULE.bazel
@@ -37,6 +37,7 @@ bazel_dep(name = "buildifier_prebuilt", version = "6.4.0", dev_dependency = True
|
||||
# the versions there are canonical, the versions here are used for CI in github/codeql, as well as for the vendoring of dependencies.
|
||||
RUST_EDITION = "2024"
|
||||
|
||||
# run buildutils-internal/scripts/fill-rust-sha256s.py when updating (internal repo)
|
||||
RUST_VERSION = "1.86.0"
|
||||
|
||||
rust = use_extension("@rules_rust//rust:extensions.bzl", "rust")
|
||||
@@ -47,6 +48,29 @@ rust.toolchain(
|
||||
"x86_64-apple-darwin",
|
||||
"aarch64-apple-darwin",
|
||||
],
|
||||
# generated by buildutils-internal/scripts/fill-rust-sha256s.py (internal repo)
|
||||
sha256s = {
|
||||
"rustc-1.86.0-x86_64-unknown-linux-gnu.tar.xz": "4438b809ce4a083af31ed17aeeedcc8fc60ccffc0625bef1926620751b6989d7",
|
||||
"rustc-1.86.0-x86_64-apple-darwin.tar.xz": "42b76253626febb7912541a30d3379f463dec89581aad4cb72c6c04fb5a71dc5",
|
||||
"rustc-1.86.0-aarch64-apple-darwin.tar.xz": "23b8f52102249a47ab5bc859d54c9a3cb588a3259ba3f00f557d50edeca4fde9",
|
||||
"rustc-1.86.0-x86_64-pc-windows-msvc.tar.xz": "fdde839fea274529a31e51eb85c6df1782cc8479c9d1bc24e2914d66a0de41ab",
|
||||
"clippy-1.86.0-x86_64-unknown-linux-gnu.tar.xz": "02aaff2c1407d2da8dba19aa4970dd873e311902b120a66cbcdbe51eb8836edf",
|
||||
"clippy-1.86.0-x86_64-apple-darwin.tar.xz": "bb85efda7bbffaf124867f5ca36d50932b1e8f533c62ee923438afb32ff8fe9a",
|
||||
"clippy-1.86.0-aarch64-apple-darwin.tar.xz": "239fa3a604b124f0312f2af08537874a1227dba63385484b468cca62e7c4f2f2",
|
||||
"clippy-1.86.0-x86_64-pc-windows-msvc.tar.xz": "d00498f47d49219f032e2c5eeebdfc3d32317c0dc3d3fd7125327445bc482cb4",
|
||||
"cargo-1.86.0-x86_64-unknown-linux-gnu.tar.xz": "c5c1590f7e9246ad9f4f97cfe26ffa92707b52a769726596a9ef81565ebd908b",
|
||||
"cargo-1.86.0-x86_64-apple-darwin.tar.xz": "af163eb02d1a178044d1b4f2375960efd47130f795f6e33d09e345454bb26f4e",
|
||||
"cargo-1.86.0-aarch64-apple-darwin.tar.xz": "3cb13873d48c3e1e4cc684d42c245226a11fba52af6b047c3346ed654e7a05c0",
|
||||
"cargo-1.86.0-x86_64-pc-windows-msvc.tar.xz": "e57a9d89619b5604899bac443e68927bdd371e40f2e03e18950b6ceb3eb67966",
|
||||
"llvm-tools-1.86.0-x86_64-unknown-linux-gnu.tar.xz": "282145ab7a63c98b625856f44b905b4dc726b497246b824632a5790debe95a78",
|
||||
"llvm-tools-1.86.0-x86_64-apple-darwin.tar.xz": "b55706e92f7da989207c50c13c7add483a9fedd233bc431b106eca2a8f151ec9",
|
||||
"llvm-tools-1.86.0-aarch64-apple-darwin.tar.xz": "04d3618c686845853585f036e3211eb9e18f2d290f4610a7a78bdc1fcce1ebd9",
|
||||
"llvm-tools-1.86.0-x86_64-pc-windows-msvc.tar.xz": "721a17cc8dc219177e4277a3592253934ef08daa1e1b12eda669a67d15fad8dd",
|
||||
"rust-std-1.86.0-x86_64-unknown-linux-gnu.tar.xz": "67be7184ea388d8ce0feaf7fdea46f1775cfc2970930264343b3089898501d37",
|
||||
"rust-std-1.86.0-x86_64-apple-darwin.tar.xz": "3b1140d54870a080080e84700143f4a342fbd02a410a319b05d9c02e7dcf44cc",
|
||||
"rust-std-1.86.0-aarch64-apple-darwin.tar.xz": "0fb121fb3b8fa9027d79ff598500a7e5cd086ddbc3557482ed3fdda00832c61b",
|
||||
"rust-std-1.86.0-x86_64-pc-windows-msvc.tar.xz": "3d5354b7b9cb950b58bff3fce18a652aa374bb30c8f70caebd3bd0b43cb41a33",
|
||||
},
|
||||
versions = [RUST_VERSION],
|
||||
)
|
||||
use_repo(rust, "rust_toolchains")
|
||||
@@ -206,6 +230,7 @@ use_repo(
|
||||
"kotlin-compiler-2.1.0-Beta1",
|
||||
"kotlin-compiler-2.1.20-Beta1",
|
||||
"kotlin-compiler-2.2.0-Beta1",
|
||||
"kotlin-compiler-2.2.20-Beta2",
|
||||
"kotlin-compiler-embeddable-1.6.0",
|
||||
"kotlin-compiler-embeddable-1.6.20",
|
||||
"kotlin-compiler-embeddable-1.7.0",
|
||||
@@ -218,6 +243,7 @@ use_repo(
|
||||
"kotlin-compiler-embeddable-2.1.0-Beta1",
|
||||
"kotlin-compiler-embeddable-2.1.20-Beta1",
|
||||
"kotlin-compiler-embeddable-2.2.0-Beta1",
|
||||
"kotlin-compiler-embeddable-2.2.20-Beta2",
|
||||
"kotlin-stdlib-1.6.0",
|
||||
"kotlin-stdlib-1.6.20",
|
||||
"kotlin-stdlib-1.7.0",
|
||||
@@ -230,6 +256,7 @@ use_repo(
|
||||
"kotlin-stdlib-2.1.0-Beta1",
|
||||
"kotlin-stdlib-2.1.20-Beta1",
|
||||
"kotlin-stdlib-2.2.0-Beta1",
|
||||
"kotlin-stdlib-2.2.20-Beta2",
|
||||
)
|
||||
|
||||
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
## 0.4.14
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.4.13
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* The `actions/artifact-poisoning/critical` and `actions/artifact-poisoning/medium` queries now exclude artifacts downloaded to `$[{ runner.temp }}` in addition to `/tmp`.
|
||||
|
||||
## 0.4.12
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
5
actions/ql/lib/change-notes/released/0.4.13.md
Normal file
5
actions/ql/lib/change-notes/released/0.4.13.md
Normal file
@@ -0,0 +1,5 @@
|
||||
## 0.4.13
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* The `actions/artifact-poisoning/critical` and `actions/artifact-poisoning/medium` queries now exclude artifacts downloaded to `$[{ runner.temp }}` in addition to `/tmp`.
|
||||
3
actions/ql/lib/change-notes/released/0.4.14.md
Normal file
3
actions/ql/lib/change-notes/released/0.4.14.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.4.14
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.4.12
|
||||
lastReleaseVersion: 0.4.14
|
||||
|
||||
@@ -72,7 +72,7 @@ string normalizePath(string path) {
|
||||
then result = path
|
||||
else
|
||||
// foo -> GITHUB_WORKSPACE/foo
|
||||
if path.regexpMatch("^[^/~].*")
|
||||
if path.regexpMatch("^[^$/~].*")
|
||||
then result = "GITHUB_WORKSPACE/" + path.regexpReplaceAll("/$", "")
|
||||
else
|
||||
// ~/foo -> ~/foo
|
||||
|
||||
@@ -262,8 +262,10 @@ class ArtifactPoisoningSink extends DataFlow::Node {
|
||||
|
||||
ArtifactPoisoningSink() {
|
||||
download.getAFollowingStep() = poisonable and
|
||||
// excluding artifacts downloaded to /tmp
|
||||
// excluding artifacts downloaded to the temporary directory
|
||||
not download.getPath().regexpMatch("^/tmp.*") and
|
||||
not download.getPath().regexpMatch("^\\$\\{\\{\\s*runner\\.temp\\s*}}.*") and
|
||||
not download.getPath().regexpMatch("^\\$RUNNER_TEMP.*") and
|
||||
(
|
||||
poisonable.(Run).getScript() = this.asExpr() and
|
||||
(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-all
|
||||
version: 0.4.13-dev
|
||||
version: 0.4.14
|
||||
library: true
|
||||
warnOnImplicitThis: true
|
||||
dependencies:
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
## 0.6.6
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.6.5
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.6.4
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
3
actions/ql/src/change-notes/released/0.6.5.md
Normal file
3
actions/ql/src/change-notes/released/0.6.5.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.6.5
|
||||
|
||||
No user-facing changes.
|
||||
3
actions/ql/src/change-notes/released/0.6.6.md
Normal file
3
actions/ql/src/change-notes/released/0.6.6.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.6.6
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.6.4
|
||||
lastReleaseVersion: 0.6.6
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-queries
|
||||
version: 0.6.5-dev
|
||||
version: 0.6.6
|
||||
library: false
|
||||
warnOnImplicitThis: true
|
||||
groups: [actions, queries]
|
||||
|
||||
19
actions/ql/test/query-tests/Security/CWE-829/.github/workflows/artifactpoisoning93.yml
vendored
Normal file
19
actions/ql/test/query-tests/Security/CWE-829/.github/workflows/artifactpoisoning93.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
on:
|
||||
workflow_run:
|
||||
workflows:
|
||||
- Benchmark
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
benchmark:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Download From PR
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
path: ${{ runner.temp }}/artifacts/
|
||||
- run: npm install
|
||||
19
actions/ql/test/query-tests/Security/CWE-829/.github/workflows/artifactpoisoning94.yml
vendored
Normal file
19
actions/ql/test/query-tests/Security/CWE-829/.github/workflows/artifactpoisoning94.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
on:
|
||||
workflow_run:
|
||||
workflows:
|
||||
- Benchmark
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
benchmark:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Download From PR
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
path: /tmp/artifacts/
|
||||
- run: npm install
|
||||
19
actions/ql/test/query-tests/Security/CWE-829/.github/workflows/artifactpoisoning95.yml
vendored
Normal file
19
actions/ql/test/query-tests/Security/CWE-829/.github/workflows/artifactpoisoning95.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
on:
|
||||
workflow_run:
|
||||
workflows:
|
||||
- Benchmark
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
benchmark:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Download From PR
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
path: $RUNNER_TEMP/artifacts/
|
||||
- run: npm install
|
||||
18
actions/ql/test/query-tests/Security/CWE-829/.github/workflows/artifactpoisoning96.yml
vendored
Normal file
18
actions/ql/test/query-tests/Security/CWE-829/.github/workflows/artifactpoisoning96.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
on:
|
||||
workflow_run:
|
||||
workflows:
|
||||
- Benchmark
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
benchmark:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Download From PR
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
- run: npm install
|
||||
19
actions/ql/test/query-tests/Security/CWE-829/.github/workflows/artifactpoisoning97.yml
vendored
Normal file
19
actions/ql/test/query-tests/Security/CWE-829/.github/workflows/artifactpoisoning97.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
on:
|
||||
workflow_run:
|
||||
workflows:
|
||||
- Benchmark
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
benchmark:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Download From PR
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
path: ${{ runner.temp }}/artifacts/
|
||||
- run: npm install
|
||||
@@ -13,6 +13,7 @@ edges
|
||||
| .github/workflows/artifactpoisoning42.yml:13:9:21:6 | Run Step | .github/workflows/artifactpoisoning42.yml:22:14:22:18 | ./cmd | provenance | Config |
|
||||
| .github/workflows/artifactpoisoning71.yml:9:9:16:6 | Uses Step | .github/workflows/artifactpoisoning71.yml:17:14:18:40 | sed -f config foo.md > bar.md\n | provenance | Config |
|
||||
| .github/workflows/artifactpoisoning81.yml:28:9:31:6 | Uses Step | .github/workflows/artifactpoisoning81.yml:31:14:31:27 | python test.py | provenance | Config |
|
||||
| .github/workflows/artifactpoisoning96.yml:13:9:18:6 | Uses Step | .github/workflows/artifactpoisoning96.yml:18:14:18:24 | npm install | provenance | Config |
|
||||
| .github/workflows/artifactpoisoning101.yml:10:9:16:6 | Uses Step | .github/workflows/artifactpoisoning101.yml:17:14:19:59 | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n | provenance | Config |
|
||||
| .github/workflows/test18.yml:12:15:33:12 | Uses Step | .github/workflows/test18.yml:36:15:40:58 | Uses Step | provenance | Config |
|
||||
| .github/workflows/test25.yml:22:9:32:6 | Uses Step: downloadBuildScan | .github/workflows/test25.yml:39:14:40:45 | ./gradlew buildScanPublishPrevious\n | provenance | Config |
|
||||
@@ -44,6 +45,8 @@ nodes
|
||||
| .github/workflows/artifactpoisoning81.yml:31:14:31:27 | python test.py | semmle.label | python test.py |
|
||||
| .github/workflows/artifactpoisoning92.yml:28:9:29:6 | Uses Step | semmle.label | Uses Step |
|
||||
| .github/workflows/artifactpoisoning92.yml:29:14:29:26 | make snapshot | semmle.label | make snapshot |
|
||||
| .github/workflows/artifactpoisoning96.yml:13:9:18:6 | Uses Step | semmle.label | Uses Step |
|
||||
| .github/workflows/artifactpoisoning96.yml:18:14:18:24 | npm install | semmle.label | npm install |
|
||||
| .github/workflows/artifactpoisoning101.yml:10:9:16:6 | Uses Step | semmle.label | Uses Step |
|
||||
| .github/workflows/artifactpoisoning101.yml:17:14:19:59 | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n | semmle.label | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n |
|
||||
| .github/workflows/test18.yml:12:15:33:12 | Uses Step | semmle.label | Uses Step |
|
||||
@@ -66,6 +69,7 @@ subpaths
|
||||
| .github/workflows/artifactpoisoning81.yml:31:14:31:27 | python test.py | .github/workflows/artifactpoisoning81.yml:28:9:31:6 | Uses Step | .github/workflows/artifactpoisoning81.yml:31:14:31:27 | python test.py | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning81.yml:31:14:31:27 | python test.py | python test.py | .github/workflows/artifactpoisoning81.yml:3:5:3:23 | pull_request_target | pull_request_target |
|
||||
| .github/workflows/artifactpoisoning92.yml:28:9:29:6 | Uses Step | .github/actions/download-artifact-2/action.yaml:6:7:25:4 | Uses Step | .github/workflows/artifactpoisoning92.yml:28:9:29:6 | Uses Step | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning92.yml:28:9:29:6 | Uses Step | Uses Step | .github/workflows/artifactpoisoning92.yml:3:3:3:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning92.yml:29:14:29:26 | make snapshot | .github/actions/download-artifact-2/action.yaml:6:7:25:4 | Uses Step | .github/workflows/artifactpoisoning92.yml:29:14:29:26 | make snapshot | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning92.yml:29:14:29:26 | make snapshot | make snapshot | .github/workflows/artifactpoisoning92.yml:3:3:3:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning96.yml:18:14:18:24 | npm install | .github/workflows/artifactpoisoning96.yml:13:9:18:6 | Uses Step | .github/workflows/artifactpoisoning96.yml:18:14:18:24 | npm install | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning96.yml:18:14:18:24 | npm install | npm install | .github/workflows/artifactpoisoning96.yml:2:3:2:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning101.yml:17:14:19:59 | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n | .github/workflows/artifactpoisoning101.yml:10:9:16:6 | Uses Step | .github/workflows/artifactpoisoning101.yml:17:14:19:59 | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning101.yml:17:14:19:59 | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n | .github/workflows/artifactpoisoning101.yml:4:3:4:21 | pull_request_target | pull_request_target |
|
||||
| .github/workflows/test18.yml:36:15:40:58 | Uses Step | .github/workflows/test18.yml:12:15:33:12 | Uses Step | .github/workflows/test18.yml:36:15:40:58 | Uses Step | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/test18.yml:36:15:40:58 | Uses Step | Uses Step | .github/workflows/test18.yml:3:5:3:16 | workflow_run | workflow_run |
|
||||
| .github/workflows/test25.yml:39:14:40:45 | ./gradlew buildScanPublishPrevious\n | .github/workflows/test25.yml:22:9:32:6 | Uses Step: downloadBuildScan | .github/workflows/test25.yml:39:14:40:45 | ./gradlew buildScanPublishPrevious\n | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/test25.yml:39:14:40:45 | ./gradlew buildScanPublishPrevious\n | ./gradlew buildScanPublishPrevious\n | .github/workflows/test25.yml:2:3:2:14 | workflow_run | workflow_run |
|
||||
|
||||
@@ -13,6 +13,7 @@ edges
|
||||
| .github/workflows/artifactpoisoning42.yml:13:9:21:6 | Run Step | .github/workflows/artifactpoisoning42.yml:22:14:22:18 | ./cmd | provenance | Config |
|
||||
| .github/workflows/artifactpoisoning71.yml:9:9:16:6 | Uses Step | .github/workflows/artifactpoisoning71.yml:17:14:18:40 | sed -f config foo.md > bar.md\n | provenance | Config |
|
||||
| .github/workflows/artifactpoisoning81.yml:28:9:31:6 | Uses Step | .github/workflows/artifactpoisoning81.yml:31:14:31:27 | python test.py | provenance | Config |
|
||||
| .github/workflows/artifactpoisoning96.yml:13:9:18:6 | Uses Step | .github/workflows/artifactpoisoning96.yml:18:14:18:24 | npm install | provenance | Config |
|
||||
| .github/workflows/artifactpoisoning101.yml:10:9:16:6 | Uses Step | .github/workflows/artifactpoisoning101.yml:17:14:19:59 | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n | provenance | Config |
|
||||
| .github/workflows/test18.yml:12:15:33:12 | Uses Step | .github/workflows/test18.yml:36:15:40:58 | Uses Step | provenance | Config |
|
||||
| .github/workflows/test25.yml:22:9:32:6 | Uses Step: downloadBuildScan | .github/workflows/test25.yml:39:14:40:45 | ./gradlew buildScanPublishPrevious\n | provenance | Config |
|
||||
@@ -44,6 +45,8 @@ nodes
|
||||
| .github/workflows/artifactpoisoning81.yml:31:14:31:27 | python test.py | semmle.label | python test.py |
|
||||
| .github/workflows/artifactpoisoning92.yml:28:9:29:6 | Uses Step | semmle.label | Uses Step |
|
||||
| .github/workflows/artifactpoisoning92.yml:29:14:29:26 | make snapshot | semmle.label | make snapshot |
|
||||
| .github/workflows/artifactpoisoning96.yml:13:9:18:6 | Uses Step | semmle.label | Uses Step |
|
||||
| .github/workflows/artifactpoisoning96.yml:18:14:18:24 | npm install | semmle.label | npm install |
|
||||
| .github/workflows/artifactpoisoning101.yml:10:9:16:6 | Uses Step | semmle.label | Uses Step |
|
||||
| .github/workflows/artifactpoisoning101.yml:17:14:19:59 | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n | semmle.label | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n |
|
||||
| .github/workflows/test18.yml:12:15:33:12 | Uses Step | semmle.label | Uses Step |
|
||||
|
||||
@@ -51,6 +51,16 @@ edges
|
||||
| .github/workflows/artifactpoisoning92.yml:19:9:25:6 | Run Step: metadata | .github/workflows/artifactpoisoning92.yml:25:9:28:6 | Uses Step |
|
||||
| .github/workflows/artifactpoisoning92.yml:25:9:28:6 | Uses Step | .github/workflows/artifactpoisoning92.yml:28:9:29:6 | Uses Step |
|
||||
| .github/workflows/artifactpoisoning92.yml:28:9:29:6 | Uses Step | .github/workflows/artifactpoisoning92.yml:29:9:29:27 | Run Step |
|
||||
| .github/workflows/artifactpoisoning93.yml:12:9:13:6 | Uses Step | .github/workflows/artifactpoisoning93.yml:13:9:19:6 | Uses Step |
|
||||
| .github/workflows/artifactpoisoning93.yml:13:9:19:6 | Uses Step | .github/workflows/artifactpoisoning93.yml:19:9:19:24 | Run Step |
|
||||
| .github/workflows/artifactpoisoning94.yml:12:9:13:6 | Uses Step | .github/workflows/artifactpoisoning94.yml:13:9:19:6 | Uses Step |
|
||||
| .github/workflows/artifactpoisoning94.yml:13:9:19:6 | Uses Step | .github/workflows/artifactpoisoning94.yml:19:9:19:24 | Run Step |
|
||||
| .github/workflows/artifactpoisoning95.yml:12:9:13:6 | Uses Step | .github/workflows/artifactpoisoning95.yml:13:9:19:6 | Uses Step |
|
||||
| .github/workflows/artifactpoisoning95.yml:13:9:19:6 | Uses Step | .github/workflows/artifactpoisoning95.yml:19:9:19:24 | Run Step |
|
||||
| .github/workflows/artifactpoisoning96.yml:12:9:13:6 | Uses Step | .github/workflows/artifactpoisoning96.yml:13:9:18:6 | Uses Step |
|
||||
| .github/workflows/artifactpoisoning96.yml:13:9:18:6 | Uses Step | .github/workflows/artifactpoisoning96.yml:18:9:18:24 | Run Step |
|
||||
| .github/workflows/artifactpoisoning97.yml:12:9:13:6 | Uses Step | .github/workflows/artifactpoisoning97.yml:13:9:19:6 | Uses Step |
|
||||
| .github/workflows/artifactpoisoning97.yml:13:9:19:6 | Uses Step | .github/workflows/artifactpoisoning97.yml:19:9:19:25 | Run Step |
|
||||
| .github/workflows/artifactpoisoning101.yml:10:9:16:6 | Uses Step | .github/workflows/artifactpoisoning101.yml:16:9:19:59 | Run Step: pr_number |
|
||||
| .github/workflows/auto_ci.yml:20:9:27:6 | Uses Step | .github/workflows/auto_ci.yml:27:9:32:6 | Uses Step |
|
||||
| .github/workflows/auto_ci.yml:27:9:32:6 | Uses Step | .github/workflows/auto_ci.yml:32:9:37:6 | Run Step |
|
||||
|
||||
@@ -231,35 +231,10 @@
|
||||
"java/ql/src/experimental/Security/CWE/CWE-400/LocalThreadResourceAbuse.qhelp",
|
||||
"java/ql/src/experimental/Security/CWE/CWE-400/ThreadResourceAbuse.qhelp"
|
||||
],
|
||||
"CryptoAlgorithms Python/JS/Ruby": [
|
||||
"javascript/ql/lib/semmle/javascript/security/CryptoAlgorithms.qll",
|
||||
"python/ql/lib/semmle/python/concepts/CryptoAlgorithms.qll",
|
||||
"ruby/ql/lib/codeql/ruby/security/CryptoAlgorithms.qll",
|
||||
"rust/ql/lib/codeql/rust/security/CryptoAlgorithms.qll"
|
||||
],
|
||||
"CryptoAlgorithmNames Python/JS/Ruby": [
|
||||
"javascript/ql/lib/semmle/javascript/security/internal/CryptoAlgorithmNames.qll",
|
||||
"python/ql/lib/semmle/python/concepts/internal/CryptoAlgorithmNames.qll",
|
||||
"ruby/ql/lib/codeql/ruby/security/internal/CryptoAlgorithmNames.qll",
|
||||
"rust/ql/lib/codeql/rust/security/internal/CryptoAlgorithmNames.qll"
|
||||
],
|
||||
"SensitiveDataHeuristics Python/JS": [
|
||||
"javascript/ql/lib/semmle/javascript/security/internal/SensitiveDataHeuristics.qll",
|
||||
"python/ql/lib/semmle/python/security/internal/SensitiveDataHeuristics.qll",
|
||||
"ruby/ql/lib/codeql/ruby/security/internal/SensitiveDataHeuristics.qll",
|
||||
"swift/ql/lib/codeql/swift/security/internal/SensitiveDataHeuristics.qll",
|
||||
"rust/ql/lib/codeql/rust/security/internal/SensitiveDataHeuristics.qll"
|
||||
],
|
||||
"IncompleteUrlSubstringSanitization": [
|
||||
"javascript/ql/src/Security/CWE-020/IncompleteUrlSubstringSanitization.qll",
|
||||
"ruby/ql/src/queries/security/cwe-020/IncompleteUrlSubstringSanitization.qll"
|
||||
],
|
||||
"Concepts Python/Ruby/JS": [
|
||||
"python/ql/lib/semmle/python/internal/ConceptsShared.qll",
|
||||
"ruby/ql/lib/codeql/ruby/internal/ConceptsShared.qll",
|
||||
"javascript/ql/lib/semmle/javascript/internal/ConceptsShared.qll",
|
||||
"rust/ql/lib/codeql/rust/internal/ConceptsShared.qll"
|
||||
],
|
||||
"ApiGraphModels": [
|
||||
"javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll",
|
||||
"ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll",
|
||||
|
||||
@@ -2,6 +2,9 @@ language: cpp
|
||||
strategy: dca
|
||||
destination: cpp/ql/lib/ext/generated
|
||||
targets:
|
||||
- name: glibc
|
||||
with-sinks: false
|
||||
with-sources: false
|
||||
- name: zlib
|
||||
with-sinks: false
|
||||
with-sources: false
|
||||
|
||||
@@ -1,3 +1,30 @@
|
||||
## 5.4.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Exposed various SSA-related classes (`Definition`, `PhiNode`, `ExplicitDefinition`, `DirectExplicitDefinition`, and `IndirectExplicitDefinition`) which were previously only usable inside the internal dataflow directory.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `cpp/overrun-write` query now recognizes more bound checks and thus produces fewer false positives.
|
||||
|
||||
## 5.3.0
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* The `UnknownDefaultLocation`, `UnknownExprLocation`, and `UnknownStmtLocation` classes have been deprecated. Use `UnknownLocation` instead.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added a `isFinalValueOfParameter` predicate to `DataFlow::Node` which holds when a dataflow node represents the final value of an output parameter of a function.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `FunctionWithWrappers` library (`semmle.code.cpp.security.FunctionWithWrappers`) no longer considers calls through function pointers as wrapper functions.
|
||||
* The analysis of C/C++ code targeting 64-bit Arm platforms has been improved. This includes support for the Arm-specific builtin functions, support for the `arm_neon.h` header and Neon vector types, and support for the `fp8` scalar type. The `arm_sve.h` header and scalable vectors are only partially supported at this point.
|
||||
* Added support for `__fp16 _Complex` and `__bf16 _Complex` types
|
||||
* Added `sql-injection` sink models for the Oracle Call Interface (OCI) database library functions `OCIStmtPrepare` and `OCIStmtPrepare2`.
|
||||
|
||||
## 5.2.0
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added `sql-injection` sink models for the Oracle Call Interface (OCI) database library functions `OCIStmtPrepare` and `OCIStmtPrepare2`.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The analysis of C/C++ code targeting 64-bit Arm platforms has been improved. This includes support for the Arm-specific builtin functions, support for the `arm_neon.h` header and Neon vector types, and support for the `fp8` scalar type. The `arm_sve.h` header and scalable vectors are only partially supported at this point.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added support for `__fp16 _Complex` and `__bf16 _Complex` types
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: deprecated
|
||||
---
|
||||
* The `UnknownDefaultLocation`, `UnknownExprLocation`, and `UnknownStmtLocation` classes have been deprecated. Use `UnknownLocation` instead.
|
||||
16
cpp/ql/lib/change-notes/released/5.3.0.md
Normal file
16
cpp/ql/lib/change-notes/released/5.3.0.md
Normal file
@@ -0,0 +1,16 @@
|
||||
## 5.3.0
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* The `UnknownDefaultLocation`, `UnknownExprLocation`, and `UnknownStmtLocation` classes have been deprecated. Use `UnknownLocation` instead.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added a `isFinalValueOfParameter` predicate to `DataFlow::Node` which holds when a dataflow node represents the final value of an output parameter of a function.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `FunctionWithWrappers` library (`semmle.code.cpp.security.FunctionWithWrappers`) no longer considers calls through function pointers as wrapper functions.
|
||||
* The analysis of C/C++ code targeting 64-bit Arm platforms has been improved. This includes support for the Arm-specific builtin functions, support for the `arm_neon.h` header and Neon vector types, and support for the `fp8` scalar type. The `arm_sve.h` header and scalable vectors are only partially supported at this point.
|
||||
* Added support for `__fp16 _Complex` and `__bf16 _Complex` types
|
||||
* Added `sql-injection` sink models for the Oracle Call Interface (OCI) database library functions `OCIStmtPrepare` and `OCIStmtPrepare2`.
|
||||
9
cpp/ql/lib/change-notes/released/5.4.0.md
Normal file
9
cpp/ql/lib/change-notes/released/5.4.0.md
Normal file
@@ -0,0 +1,9 @@
|
||||
## 5.4.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Exposed various SSA-related classes (`Definition`, `PhiNode`, `ExplicitDefinition`, `DirectExplicitDefinition`, and `IndirectExplicitDefinition`) which were previously only usable inside the internal dataflow directory.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `cpp/overrun-write` query now recognizes more bound checks and thus produces fewer false positives.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 5.2.0
|
||||
lastReleaseVersion: 5.4.0
|
||||
|
||||
@@ -32,4 +32,18 @@ extensions:
|
||||
- ["", "", False, "CommandLineToArgvA", "", "", "Argument[*0]", "ReturnValue[**]", "taint", "manual"]
|
||||
- ["", "", False, "CommandLineToArgvW", "", "", "Argument[*0]", "ReturnValue[**]", "taint", "manual"]
|
||||
# fileapi.h
|
||||
- ["", "", False, "ReadFileEx", "", "", "Argument[*3].Field[@hEvent]", "Argument[4].Parameter[*2].Field[@hEvent]", "value", "manual"]
|
||||
- ["", "", False, "ReadFileEx", "", "", "Argument[*3].Field[@hEvent]", "Argument[4].Parameter[*2].Field[@hEvent]", "value", "manual"]
|
||||
# processthreadsapi.h
|
||||
- ["", "", False, "CreateThread", "", "", "Argument[@3]", "Argument[2].Parameter[@0]", "value", "manual"]
|
||||
- ["", "", False, "CreateRemoteThread", "", "", "Argument[@4]", "Argument[3].Parameter[@0]", "value", "manual"]
|
||||
- ["", "", False, "CreateRemoteThreadEx", "", "", "Argument[@4]", "Argument[3].Parameter[@0]", "value", "manual"]
|
||||
# wdm.h
|
||||
- ["", "", False, "RtlCopyVolatileMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
|
||||
- ["", "", False, "RtlCopyDeviceMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
|
||||
- ["", "", False, "RtlCopyMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
|
||||
- ["", "", False, "RtlCopyMemoryNonTemporal", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
|
||||
- ["", "", False, "RtlCopyUnicodeString", "", "", "Argument[*1].Field[*Buffer]", "Argument[*0].Field[*Buffer]", "value", "manual"]
|
||||
- ["", "", False, "RtlMoveMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
|
||||
- ["", "", False, "RtlMoveVolatileMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
|
||||
# winternl.h
|
||||
- ["", "", False, "RtlInitUnicodeString", "", "", "Argument[*1]", "Argument[*0].Field[*Buffer]", "value", "manual"]
|
||||
5494
cpp/ql/lib/ext/generated/glibc/glibc.model.yml
Normal file
5494
cpp/ql/lib/ext/generated/glibc/glibc.model.yml
Normal file
File diff suppressed because it is too large
Load Diff
6
cpp/ql/lib/ext/pthread.model.yml
Normal file
6
cpp/ql/lib/ext/pthread.model.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/cpp-all
|
||||
extensible: summaryModel
|
||||
data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
|
||||
- ["", "", False, "pthread_create", "", "", "Argument[@3]", "Argument[2].Parameter[@0]", "value", "manual"]
|
||||
11
cpp/ql/lib/ext/std.thread.model.yml
Normal file
11
cpp/ql/lib/ext/std.thread.model.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/cpp-all
|
||||
extensible: summaryModel
|
||||
data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
|
||||
- ["std", "thread", True, "thread", "", "", "Argument[*@1]", "Argument[0].Parameter[@0]", "value", "manual"]
|
||||
- ["std", "thread", True, "thread", "", "", "Argument[*@2]", "Argument[0].Parameter[@1]", "value", "manual"]
|
||||
- ["std", "thread", True, "thread", "", "", "Argument[*@3]", "Argument[0].Parameter[@2]", "value", "manual"]
|
||||
- ["std", "thread", True, "thread", "", "", "Argument[*@4]", "Argument[0].Parameter[@3]", "value", "manual"]
|
||||
- ["std", "thread", True, "thread", "", "", "Argument[*@5]", "Argument[0].Parameter[@4]", "value", "manual"]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 5.2.1-dev
|
||||
version: 5.4.0
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
@@ -57,7 +57,9 @@ class RequiresExpr extends Expr, @requires_expr {
|
||||
/**
|
||||
* A C++ requirement in a requires expression.
|
||||
*/
|
||||
class RequirementExpr extends Expr { }
|
||||
class RequirementExpr extends Expr {
|
||||
RequirementExpr() { this.getParent() instanceof RequiresExpr }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ simple requirement in a requires expression.
|
||||
@@ -70,7 +72,6 @@ class RequirementExpr extends Expr { }
|
||||
*/
|
||||
class SimpleRequirementExpr extends RequirementExpr {
|
||||
SimpleRequirementExpr() {
|
||||
this.getParent() instanceof RequiresExpr and
|
||||
not this instanceof TypeRequirementExpr and
|
||||
not this instanceof CompoundRequirementExpr and
|
||||
not this instanceof NestedRequirementExpr
|
||||
@@ -89,8 +90,6 @@ class SimpleRequirementExpr extends RequirementExpr {
|
||||
* with `T` a template parameter, then `typename T::a_field;` is a type requirement.
|
||||
*/
|
||||
class TypeRequirementExpr extends RequirementExpr, TypeName {
|
||||
TypeRequirementExpr() { this.getParent() instanceof RequiresExpr }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "TypeRequirementExpr" }
|
||||
}
|
||||
|
||||
@@ -140,7 +139,7 @@ class CompoundRequirementExpr extends RequirementExpr, @compound_requirement {
|
||||
* with `T` a template parameter, then `requires std::is_same<T, int>::value;` is
|
||||
* a nested requirement.
|
||||
*/
|
||||
class NestedRequirementExpr extends Expr, @nested_requirement {
|
||||
class NestedRequirementExpr extends RequirementExpr, @nested_requirement {
|
||||
override string toString() { result = "requires ..." }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "NestedRequirementExpr" }
|
||||
@@ -163,7 +162,7 @@ class NestedRequirementExpr extends Expr, @nested_requirement {
|
||||
* then `C<int, 1>` is a concept id expression that refers to
|
||||
* the concept `C`.
|
||||
*/
|
||||
class ConceptIdExpr extends RequirementExpr, @concept_id {
|
||||
class ConceptIdExpr extends Expr, @concept_id {
|
||||
override string toString() {
|
||||
result = this.getConcept().getName() + "<...>"
|
||||
or
|
||||
|
||||
@@ -15,6 +15,13 @@ class StandardSsa extends SsaHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
* NOTE: If possible, prefer the SSA classes exposed by the new dataflow
|
||||
* library:
|
||||
* ```
|
||||
* import semmle.code.cpp.dataflow.new.DataFlow
|
||||
* // use `DataFlow::Ssa::Definition`
|
||||
* ```
|
||||
*
|
||||
* A definition of one or more SSA variables, including phi node definitions.
|
||||
* An _SSA variable_, as defined in the literature, is effectively the pair of
|
||||
* an `SsaDefinition d` and a `StackVariable v`, written `(d, v)` in this
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
private import cpp
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import semmle.code.cpp.ir.dataflow.DataFlow
|
||||
private import DataFlowPrivate
|
||||
private import DataFlowUtil
|
||||
private import DataFlowImplCommon as DataFlowImplCommon
|
||||
@@ -60,7 +59,7 @@ private module VirtualDispatch {
|
||||
* `resolve` predicate to stitch that information together and resolve the
|
||||
* call.
|
||||
*/
|
||||
abstract DataFlow::Node getDispatchValue();
|
||||
abstract Node getDispatchValue();
|
||||
|
||||
/** Gets a candidate target for this call. */
|
||||
abstract Function resolve();
|
||||
@@ -72,17 +71,13 @@ private module VirtualDispatch {
|
||||
* parameter is true when the search is allowed to continue backwards into
|
||||
* a parameter; non-recursive callers should pass `_` for `allowFromArg`.
|
||||
*/
|
||||
predicate flowsFrom(DataFlow::Node src, boolean allowFromArg) {
|
||||
predicate flowsFrom(Node src, boolean allowFromArg) {
|
||||
src = this.getDispatchValue() and allowFromArg = true
|
||||
or
|
||||
exists(DataFlow::Node other, boolean allowOtherFromArg |
|
||||
this.flowsFrom(other, allowOtherFromArg)
|
||||
|
|
||||
exists(Node other, boolean allowOtherFromArg | this.flowsFrom(other, allowOtherFromArg) |
|
||||
// Call argument
|
||||
exists(DataFlowCall call, Position i |
|
||||
other
|
||||
.(DataFlow::ParameterNode)
|
||||
.isParameterOf(pragma[only_bind_into](call).getStaticCallTarget(), i) and
|
||||
other.(ParameterNode).isParameterOf(pragma[only_bind_into](call).getStaticCallTarget(), i) and
|
||||
src.(ArgumentNode).argumentOf(call, pragma[only_bind_into](pragma[only_bind_out](i)))
|
||||
) and
|
||||
allowOtherFromArg = true and
|
||||
@@ -96,7 +91,7 @@ private module VirtualDispatch {
|
||||
allowFromArg = false
|
||||
or
|
||||
// Local flow
|
||||
DataFlow::localFlowStep(src, other) and
|
||||
localFlowStep(src, other) and
|
||||
allowFromArg = allowOtherFromArg
|
||||
or
|
||||
// Flow from global variable to load.
|
||||
@@ -159,11 +154,11 @@ private module VirtualDispatch {
|
||||
private class DataSensitiveExprCall extends DataSensitiveCall {
|
||||
DataSensitiveExprCall() { not exists(this.getStaticCallTarget()) }
|
||||
|
||||
override DataFlow::Node getDispatchValue() { result.asOperand() = this.getCallTargetOperand() }
|
||||
override Node getDispatchValue() { result.asOperand() = this.getCallTargetOperand() }
|
||||
|
||||
override Function resolve() {
|
||||
exists(FunctionInstruction fi |
|
||||
this.flowsFrom(DataFlow::instructionNode(fi), _) and
|
||||
this.flowsFrom(instructionNode(fi), _) and
|
||||
result = fi.getFunctionSymbol()
|
||||
) and
|
||||
(
|
||||
@@ -186,7 +181,7 @@ private module VirtualDispatch {
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getDispatchValue() { result.asInstruction() = this.getArgument(-1) }
|
||||
override Node getDispatchValue() { result.asInstruction() = this.getArgument(-1) }
|
||||
|
||||
override MemberFunction resolve() {
|
||||
exists(Class overridingClass |
|
||||
@@ -213,7 +208,7 @@ private module VirtualDispatch {
|
||||
pragma[noinline]
|
||||
private predicate hasFlowFromCastFrom(Class derivedClass) {
|
||||
exists(ConvertToBaseInstruction toBase |
|
||||
this.flowsFrom(DataFlow::instructionNode(toBase), _) and
|
||||
this.flowsFrom(instructionNode(toBase), _) and
|
||||
derivedClass = toBase.getDerivedClass()
|
||||
)
|
||||
}
|
||||
@@ -270,7 +265,7 @@ private predicate mayBenefitFromCallContext(
|
||||
exists(InitializeParameterInstruction init |
|
||||
not exists(call.getStaticCallTarget()) and
|
||||
init.getEnclosingFunction() = f.getUnderlyingCallable() and
|
||||
call.flowsFrom(DataFlow::instructionNode(init), _) and
|
||||
call.flowsFrom(instructionNode(init), _) and
|
||||
init.getParameter().getIndex() = arg
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ private import semmle.code.cpp.ir.IR
|
||||
private import DataFlowDispatch
|
||||
private import semmle.code.cpp.ir.internal.IRCppLanguage
|
||||
private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
private import SsaInternals as Ssa
|
||||
private import SsaImpl as Ssa
|
||||
private import DataFlowImplCommon as DataFlowImplCommon
|
||||
private import codeql.util.Unit
|
||||
private import Node0ToString
|
||||
@@ -1382,16 +1382,89 @@ predicate neverSkipInPathGraph(Node n) {
|
||||
exists(n.asIndirectDefinition())
|
||||
}
|
||||
|
||||
class LambdaCallKind = Unit;
|
||||
private newtype TLambdaCallKind =
|
||||
TFunctionPointer() or
|
||||
TFunctor()
|
||||
|
||||
class LambdaCallKind extends TLambdaCallKind {
|
||||
predicate isFunctionPointer() { this = TFunctionPointer() }
|
||||
|
||||
predicate isFunctor() { this = TFunctor() }
|
||||
|
||||
string toString() {
|
||||
this.isFunctionPointer() and
|
||||
result = "Function pointer kind"
|
||||
or
|
||||
this.isFunctor() and
|
||||
result = "Functor kind"
|
||||
}
|
||||
}
|
||||
|
||||
private class ConstructorCallInstruction extends CallInstruction {
|
||||
Cpp::Class constructedType;
|
||||
|
||||
ConstructorCallInstruction() {
|
||||
this.getStaticCallTarget().(Cpp::Constructor).getDeclaringType() = constructedType
|
||||
}
|
||||
|
||||
Cpp::Class getConstructedType() { result = constructedType }
|
||||
}
|
||||
|
||||
private class OperatorCall extends Cpp::MemberFunction {
|
||||
OperatorCall() { this.hasName("operator()") }
|
||||
}
|
||||
|
||||
private predicate isFunctorCreationWithoutConstructor(Node creation, OperatorCall operator) {
|
||||
exists(UninitializedInstruction init, Instruction dest |
|
||||
// A construction of an object with no constructor. In this case we use
|
||||
// the `UninitializedInstruction` as the creation node.
|
||||
init = creation.asInstruction() and
|
||||
dest = init.getDestinationAddress() and
|
||||
not any(ConstructorCallInstruction constructorCall).getThisArgument() = dest and
|
||||
operator.getDeclaringType() = init.getResultType()
|
||||
)
|
||||
or
|
||||
// Workaround for an extractor bug. In this snippet:
|
||||
// ```
|
||||
// struct S { };
|
||||
// void f(S);
|
||||
// f(S());
|
||||
// ```
|
||||
// The expression `S()` is represented as a 0 literal in the database.
|
||||
exists(ConstantValueInstruction constant |
|
||||
constant.getValue() = "0" and
|
||||
creation.asInstruction() = constant and
|
||||
constant.getResultType() = operator.getDeclaringType()
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isFunctorCreationWithConstructor(Node creation, OperatorCall operator) {
|
||||
exists(DataFlowCall constructorCall, IndirectionPosition pos |
|
||||
// A construction of an object with a constructor. In this case we use
|
||||
// the post-update node of the qualifier
|
||||
pos.getArgumentIndex() = -1 and
|
||||
isArgumentNode(creation.(PostUpdateNode).getPreUpdateNode(), constructorCall, pos) and
|
||||
operator.getDeclaringType() =
|
||||
constructorCall.asCallInstruction().(ConstructorCallInstruction).getConstructedType()
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `creation` is an expression that creates a lambda of kind `kind` for `c`. */
|
||||
predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c) {
|
||||
creation.asInstruction().(FunctionAddressInstruction).getFunctionSymbol() = c.asSourceCallable() and
|
||||
exists(kind)
|
||||
kind.isFunctionPointer() and
|
||||
creation.asInstruction().(FunctionAddressInstruction).getFunctionSymbol() = c.asSourceCallable()
|
||||
or
|
||||
kind.isFunctor() and
|
||||
exists(OperatorCall operator | operator = c.asSourceCallable() |
|
||||
isFunctorCreationWithoutConstructor(creation, operator)
|
||||
or
|
||||
isFunctorCreationWithConstructor(creation, operator)
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */
|
||||
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
|
||||
kind.isFunctionPointer() and
|
||||
(
|
||||
call.(SummaryCall).getReceiver() = receiver.(FlowSummaryNode).getSummaryNode()
|
||||
or
|
||||
@@ -1400,8 +1473,15 @@ predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
|
||||
// has a result for `getStaticCallTarget`.
|
||||
not exists(call.getStaticCallTarget()) and
|
||||
call.asCallInstruction().getCallTargetOperand() = receiver.asOperand()
|
||||
) and
|
||||
exists(kind)
|
||||
)
|
||||
or
|
||||
kind.isFunctor() and
|
||||
(
|
||||
call.(SummaryCall).getReceiver() = receiver.(FlowSummaryNode).getSummaryNode()
|
||||
or
|
||||
not exists(call.getStaticCallTarget()) and
|
||||
call.asCallInstruction().getThisArgumentOperand() = receiver.asOperand()
|
||||
)
|
||||
}
|
||||
|
||||
/** Extra data-flow steps needed for lambda flow analysis. */
|
||||
@@ -1902,19 +1982,23 @@ module IteratorFlow {
|
||||
|
||||
predicate allowFlowIntoUncertainDef(IteratorSsa::UncertainWriteDefinition def) { any() }
|
||||
|
||||
class GuardValue = Void;
|
||||
|
||||
class Guard extends Void {
|
||||
predicate hasBranchEdge(SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch) {
|
||||
predicate hasValueBranchEdge(
|
||||
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue val
|
||||
) {
|
||||
none()
|
||||
}
|
||||
|
||||
predicate controlsBranchEdge(
|
||||
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch
|
||||
predicate valueControlsBranchEdge(
|
||||
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue val
|
||||
) {
|
||||
none()
|
||||
}
|
||||
}
|
||||
|
||||
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
|
||||
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, GuardValue val) {
|
||||
none()
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ private import semmle.code.cpp.models.interfaces.DataFlow
|
||||
private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
private import DataFlowPrivate
|
||||
private import ModelUtil
|
||||
private import SsaInternals as Ssa
|
||||
private import SsaImpl as SsaImpl
|
||||
private import DataFlowImplCommon as DataFlowImplCommon
|
||||
private import codeql.util.Unit
|
||||
private import Node0ToString
|
||||
@@ -39,38 +39,39 @@ private newtype TIRDataFlowNode =
|
||||
TNode0(Node0Impl node) { DataFlowImplCommon::forceCachingInSameStage() } or
|
||||
TGlobalLikeVariableNode(GlobalLikeVariable var, int indirectionIndex) {
|
||||
indirectionIndex =
|
||||
[getMinIndirectionsForType(var.getUnspecifiedType()) .. Ssa::getMaxIndirectionsForType(var.getUnspecifiedType())]
|
||||
[getMinIndirectionsForType(var.getUnspecifiedType()) .. SsaImpl::getMaxIndirectionsForType(var.getUnspecifiedType())]
|
||||
} or
|
||||
TPostUpdateNodeImpl(Operand operand, int indirectionIndex) {
|
||||
operand = any(FieldAddress fa).getObjectAddressOperand() and
|
||||
indirectionIndex = [0 .. Ssa::countIndirectionsForCppType(Ssa::getLanguageType(operand))]
|
||||
indirectionIndex =
|
||||
[0 .. SsaImpl::countIndirectionsForCppType(SsaImpl::getLanguageType(operand))]
|
||||
or
|
||||
Ssa::isModifiableByCall(operand, indirectionIndex)
|
||||
SsaImpl::isModifiableByCall(operand, indirectionIndex)
|
||||
} or
|
||||
TSsaSynthNode(Ssa::SynthNode n) or
|
||||
TSsaSynthNode(SsaImpl::SynthNode n) or
|
||||
TSsaIteratorNode(IteratorFlow::IteratorFlowNode n) or
|
||||
TRawIndirectOperand0(Node0Impl node, int indirectionIndex) {
|
||||
Ssa::hasRawIndirectOperand(node.asOperand(), indirectionIndex)
|
||||
SsaImpl::hasRawIndirectOperand(node.asOperand(), indirectionIndex)
|
||||
} or
|
||||
TRawIndirectInstruction0(Node0Impl node, int indirectionIndex) {
|
||||
not exists(node.asOperand()) and
|
||||
Ssa::hasRawIndirectInstruction(node.asInstruction(), indirectionIndex)
|
||||
SsaImpl::hasRawIndirectInstruction(node.asInstruction(), indirectionIndex)
|
||||
} or
|
||||
TFinalParameterNode(Parameter p, int indirectionIndex) {
|
||||
exists(Ssa::FinalParameterUse use |
|
||||
exists(SsaImpl::FinalParameterUse use |
|
||||
use.getParameter() = p and
|
||||
use.getIndirectionIndex() = indirectionIndex
|
||||
)
|
||||
} or
|
||||
TFinalGlobalValue(Ssa::GlobalUse globalUse) or
|
||||
TInitialGlobalValue(Ssa::GlobalDef globalUse) or
|
||||
TFinalGlobalValue(SsaImpl::GlobalUse globalUse) or
|
||||
TInitialGlobalValue(SsaImpl::GlobalDef globalUse) or
|
||||
TBodyLessParameterNodeImpl(Parameter p, int indirectionIndex) {
|
||||
// Rule out parameters of catch blocks.
|
||||
not exists(p.getCatchBlock()) and
|
||||
// We subtract one because `getMaxIndirectionsForType` returns the maximum
|
||||
// indirection for a glvalue of a given type, and this doesn't apply to
|
||||
// parameters.
|
||||
indirectionIndex = [0 .. Ssa::getMaxIndirectionsForType(p.getUnspecifiedType()) - 1] and
|
||||
indirectionIndex = [0 .. SsaImpl::getMaxIndirectionsForType(p.getUnspecifiedType()) - 1] and
|
||||
not any(InitializeParameterInstruction init).getParameter() = p
|
||||
} or
|
||||
TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn)
|
||||
@@ -81,7 +82,7 @@ private newtype TIRDataFlowNode =
|
||||
class FieldAddress extends Operand {
|
||||
FieldAddressInstruction fai;
|
||||
|
||||
FieldAddress() { fai = this.getDef() and not Ssa::ignoreOperand(this) }
|
||||
FieldAddress() { fai = this.getDef() and not SsaImpl::ignoreOperand(this) }
|
||||
|
||||
/** Gets the field associated with this instruction. */
|
||||
Field getField() { result = fai.getField() }
|
||||
@@ -126,7 +127,7 @@ predicate conversionFlow(
|
||||
)
|
||||
or
|
||||
additional = true and
|
||||
Ssa::isAdditionalConversionFlow(opFrom, instrTo)
|
||||
SsaImpl::isAdditionalConversionFlow(opFrom, instrTo)
|
||||
)
|
||||
or
|
||||
isPointerArith = true and
|
||||
@@ -183,7 +184,7 @@ class Node extends TIRDataFlowNode {
|
||||
or
|
||||
this.asOperand().getUse() = block.getInstruction(i)
|
||||
or
|
||||
exists(Ssa::SynthNode ssaNode |
|
||||
exists(SsaImpl::SynthNode ssaNode |
|
||||
this.(SsaSynthNode).getSynthNode() = ssaNode and
|
||||
ssaNode.getBasicBlock() = block and
|
||||
ssaNode.getIndex() = i
|
||||
@@ -364,10 +365,10 @@ class Node extends TIRDataFlowNode {
|
||||
* pointed to by `p`.
|
||||
*/
|
||||
Expr asDefinition(boolean uncertain) {
|
||||
exists(StoreInstruction store, Ssa::Definition def |
|
||||
exists(StoreInstruction store, SsaImpl::Definition def |
|
||||
store = this.asInstruction() and
|
||||
result = asDefinitionImpl(store) and
|
||||
Ssa::defToNode(this, def, _) and
|
||||
SsaImpl::defToNode(this, def, _) and
|
||||
if def.isCertain() then uncertain = false else uncertain = true
|
||||
)
|
||||
}
|
||||
@@ -488,6 +489,23 @@ class Node extends TIRDataFlowNode {
|
||||
result = this.(IndirectParameterNode).getParameter()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this node represents the `indirectionIndex`'th indirection of
|
||||
* the value of an output parameter `p` just before reaching the end of a function.
|
||||
*/
|
||||
predicate isFinalValueOfParameter(Parameter p, int indirectionIndex) {
|
||||
exists(FinalParameterNode n | n = this |
|
||||
p = n.getParameter() and
|
||||
indirectionIndex = n.getIndirectionIndex()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this node represents the value of an output parameter `p`
|
||||
* just before reaching the end of a function.
|
||||
*/
|
||||
predicate isFinalValueOfParameter(Parameter p) { this.isFinalValueOfParameter(p, _) }
|
||||
|
||||
/**
|
||||
* Gets the variable corresponding to this node, if any. This can be used for
|
||||
* modeling flow in and out of global variables.
|
||||
@@ -610,7 +628,7 @@ class OperandNode extends Node, Node0 {
|
||||
* For example, `stripPointers(int*&)` is `int*` and `stripPointers(int*)` is `int`.
|
||||
*/
|
||||
Type stripPointer(Type t) {
|
||||
result = any(Ssa::Indirection ind | ind.getType() = t).getBaseType()
|
||||
result = any(SsaImpl::Indirection ind | ind.getType() = t).getBaseType()
|
||||
or
|
||||
result = t.(PointerToMemberType).getBaseType()
|
||||
or
|
||||
@@ -677,12 +695,12 @@ class PostFieldUpdateNode extends PostUpdateNodeImpl {
|
||||
* in a data flow graph.
|
||||
*/
|
||||
class SsaSynthNode extends Node, TSsaSynthNode {
|
||||
Ssa::SynthNode node;
|
||||
SsaImpl::SynthNode node;
|
||||
|
||||
SsaSynthNode() { this = TSsaSynthNode(node) }
|
||||
|
||||
/** Gets the synthesized SSA node associated with this node. */
|
||||
Ssa::SynthNode getSynthNode() { result = node }
|
||||
SsaImpl::SynthNode getSynthNode() { result = node }
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() {
|
||||
result.asSourceCallable() = this.getFunction()
|
||||
@@ -765,12 +783,12 @@ class SideEffectOperandNode extends Node instanceof IndirectOperand {
|
||||
* from a function body.
|
||||
*/
|
||||
class FinalGlobalValue extends Node, TFinalGlobalValue {
|
||||
Ssa::GlobalUse globalUse;
|
||||
SsaImpl::GlobalUse globalUse;
|
||||
|
||||
FinalGlobalValue() { this = TFinalGlobalValue(globalUse) }
|
||||
|
||||
/** Gets the underlying SSA use. */
|
||||
Ssa::GlobalUse getGlobalUse() { result = globalUse }
|
||||
SsaImpl::GlobalUse getGlobalUse() { result = globalUse }
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() {
|
||||
result.asSourceCallable() = this.getFunction()
|
||||
@@ -797,12 +815,12 @@ class FinalGlobalValue extends Node, TFinalGlobalValue {
|
||||
* a function body.
|
||||
*/
|
||||
class InitialGlobalValue extends Node, TInitialGlobalValue {
|
||||
Ssa::GlobalDef globalDef;
|
||||
SsaImpl::GlobalDef globalDef;
|
||||
|
||||
InitialGlobalValue() { this = TInitialGlobalValue(globalDef) }
|
||||
|
||||
/** Gets the underlying SSA definition. */
|
||||
Ssa::GlobalDef getGlobalDef() { result = globalDef }
|
||||
SsaImpl::GlobalDef getGlobalDef() { result = globalDef }
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() {
|
||||
result.asSourceCallable() = this.getFunction()
|
||||
@@ -1225,7 +1243,7 @@ import RawIndirectNodes
|
||||
/**
|
||||
* INTERNAL: do not use.
|
||||
*
|
||||
* A node representing the value of an update parameter
|
||||
* A node representing the value of an output parameter
|
||||
* just before reaching the end of a function.
|
||||
*/
|
||||
class FinalParameterNode extends Node, TFinalParameterNode {
|
||||
@@ -1271,11 +1289,11 @@ class UninitializedNode extends Node {
|
||||
LocalVariable v;
|
||||
|
||||
UninitializedNode() {
|
||||
exists(Ssa::Definition def, Ssa::SourceVariable sv |
|
||||
exists(SsaImpl::Definition def, SsaImpl::SourceVariable sv |
|
||||
def.getIndirectionIndex() = 0 and
|
||||
def.getValue().asInstruction() instanceof UninitializedInstruction and
|
||||
Ssa::defToNode(this, def, sv) and
|
||||
v = sv.getBaseVariable().(Ssa::BaseIRVariable).getIRVariable().getAst()
|
||||
SsaImpl::defToNode(this, def, sv) and
|
||||
v = sv.getBaseVariable().(SsaImpl::BaseIRVariable).getIRVariable().getAst()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1705,7 +1723,7 @@ private module Cached {
|
||||
cached
|
||||
predicate flowsToBackEdge(Node n) {
|
||||
exists(Node succ, IRBlock bb1, IRBlock bb2 |
|
||||
Ssa::ssaFlow(n, succ) and
|
||||
SsaImpl::ssaFlow(n, succ) and
|
||||
bb1 = n.getBasicBlock() and
|
||||
bb2 = succ.getBasicBlock() and
|
||||
bb1 != bb2 and
|
||||
@@ -1803,7 +1821,7 @@ private module Cached {
|
||||
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo, string model) {
|
||||
(
|
||||
// Def-use/Use-use flow
|
||||
Ssa::ssaFlow(nodeFrom, nodeTo)
|
||||
SsaImpl::ssaFlow(nodeFrom, nodeTo)
|
||||
or
|
||||
IteratorFlow::localFlowStep(nodeFrom, nodeTo)
|
||||
or
|
||||
@@ -1816,7 +1834,7 @@ private module Cached {
|
||||
|
|
||||
simpleOperandLocalFlowStep(iFrom, opTo) and
|
||||
// Omit when the instruction node also represents the operand.
|
||||
not iFrom = Ssa::getIRRepresentationOfOperand(opTo)
|
||||
not iFrom = SsaImpl::getIRRepresentationOfOperand(opTo)
|
||||
)
|
||||
or
|
||||
// Indirect operand -> (indirect) instruction flow
|
||||
@@ -1889,7 +1907,7 @@ private module Cached {
|
||||
// We also want a write coming out of an `OutNode` to flow `nodeTo`.
|
||||
// This is different from `reverseFlowInstruction` since `nodeFrom` can never
|
||||
// be an `OutNode` when it's defined by an instruction.
|
||||
Ssa::outNodeHasAddressAndIndex(nodeFrom, address, indirectionIndex)
|
||||
SsaImpl::outNodeHasAddressAndIndex(nodeFrom, address, indirectionIndex)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2082,7 +2100,7 @@ private newtype TContent =
|
||||
TFieldContent(Field f, int indirectionIndex) {
|
||||
// the indirection index for field content starts at 1 (because `TFieldContent` is thought of as
|
||||
// the address of the field, `FieldAddress` in the IR).
|
||||
indirectionIndex = [1 .. Ssa::getMaxIndirectionsForType(f.getUnspecifiedType())] and
|
||||
indirectionIndex = [1 .. SsaImpl::getMaxIndirectionsForType(f.getUnspecifiedType())] and
|
||||
// Reads and writes of union fields are tracked using `UnionContent`.
|
||||
not f.getDeclaringType() instanceof Union
|
||||
} or
|
||||
@@ -2094,7 +2112,9 @@ private newtype TContent =
|
||||
// field can be read by any read of the union's fields. Again, the indirection index
|
||||
// is 1-based (because 0 is considered the address).
|
||||
indirectionIndex =
|
||||
[1 .. max(Ssa::getMaxIndirectionsForType(getAFieldWithSize(u, bytes).getUnspecifiedType()))]
|
||||
[1 .. max(SsaImpl::getMaxIndirectionsForType(getAFieldWithSize(u, bytes)
|
||||
.getUnspecifiedType())
|
||||
)]
|
||||
)
|
||||
} or
|
||||
TElementContent(int indirectionIndex) {
|
||||
@@ -2337,7 +2357,7 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
controls(g, result, edge)
|
||||
)
|
||||
or
|
||||
result = Ssa::BarrierGuard<guardChecksNode/3>::getABarrierNode()
|
||||
result = SsaImpl::BarrierGuard<guardChecksNode/3>::getABarrierNode()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2436,7 +2456,7 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
)
|
||||
or
|
||||
result =
|
||||
Ssa::BarrierGuardWithIntParam<guardChecksIndirectNode/4>::getABarrierNode(indirectionIndex)
|
||||
SsaImpl::BarrierGuardWithIntParam<guardChecksIndirectNode/4>::getABarrierNode(indirectionIndex)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2473,7 +2493,7 @@ module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardCheck
|
||||
controls(g, result, edge)
|
||||
)
|
||||
or
|
||||
result = Ssa::BarrierGuard<guardChecksNode/3>::getABarrierNode()
|
||||
result = SsaImpl::BarrierGuard<guardChecksNode/3>::getABarrierNode()
|
||||
}
|
||||
|
||||
bindingset[value, n]
|
||||
@@ -2503,7 +2523,7 @@ module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardCheck
|
||||
)
|
||||
or
|
||||
result =
|
||||
Ssa::BarrierGuardWithIntParam<guardChecksIndirectNode/4>::getABarrierNode(indirectionIndex)
|
||||
SsaImpl::BarrierGuardWithIntParam<guardChecksIndirectNode/4>::getABarrierNode(indirectionIndex)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2559,3 +2579,16 @@ Function getARuntimeTarget(Call call) {
|
||||
result = DataFlowImplCommon::viableCallableLambda(dfCall, _).asSourceCallable()
|
||||
)
|
||||
}
|
||||
|
||||
/** A module that provides static single assignment (SSA) information. */
|
||||
module Ssa {
|
||||
class Definition = SsaImpl::Definition;
|
||||
|
||||
class ExplicitDefinition = SsaImpl::ExplicitDefinition;
|
||||
|
||||
class DirectExplicitDefinition = SsaImpl::DirectExplicitDefinition;
|
||||
|
||||
class IndirectExplicitDefinition = SsaImpl::IndirectExplicitDefinition;
|
||||
|
||||
class PhiNode = SsaImpl::PhiNode;
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ private module Cached {
|
||||
)
|
||||
or
|
||||
// Similarly for `i++` and `++i` we pretend that the generated
|
||||
// `StoreInstruction` is contains the result of the expression even though
|
||||
// `StoreInstruction` contains the result of the expression even though
|
||||
// this isn't totally aligned with the C/C++ standard.
|
||||
exists(TranslatedCrementOperation tco |
|
||||
store = tco.getInstruction(CrementStoreTag()) and
|
||||
|
||||
@@ -4,15 +4,15 @@
|
||||
*/
|
||||
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import semmle.code.cpp.ir.dataflow.DataFlow
|
||||
private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs
|
||||
private import DataFlowUtil
|
||||
private import DataFlowPrivate
|
||||
private import SsaInternals as Ssa
|
||||
private import SsaImpl as Ssa
|
||||
|
||||
/**
|
||||
* Gets the instruction that goes into `input` for `call`.
|
||||
*/
|
||||
DataFlow::Node callInput(CallInstruction call, FunctionInput input) {
|
||||
Node callInput(CallInstruction call, FunctionInput input) {
|
||||
// An argument or qualifier
|
||||
exists(int index |
|
||||
result.asOperand() = call.getArgumentOperand(index) and
|
||||
@@ -62,8 +62,8 @@ Node callOutput(CallInstruction call, FunctionOutput output) {
|
||||
result = callOutputWithIndirectionIndex(call, output, _)
|
||||
}
|
||||
|
||||
DataFlow::Node callInput(CallInstruction call, FunctionInput input, int d) {
|
||||
exists(DataFlow::Node n | n = callInput(call, input) and d > 0 |
|
||||
Node callInput(CallInstruction call, FunctionInput input, int d) {
|
||||
exists(Node n | n = callInput(call, input) and d > 0 |
|
||||
// An argument or qualifier
|
||||
hasOperandAndIndex(result, n.asOperand(), d)
|
||||
or
|
||||
@@ -85,7 +85,7 @@ private IndirectReturnOutNode getIndirectReturnOutNode(CallInstruction call, int
|
||||
*/
|
||||
bindingset[d]
|
||||
Node callOutput(CallInstruction call, FunctionOutput output, int d) {
|
||||
exists(DataFlow::Node n, int indirectionIndex |
|
||||
exists(Node n, int indirectionIndex |
|
||||
n = callOutputWithIndirectionIndex(call, output, indirectionIndex) and d > 0
|
||||
|
|
||||
// The return value
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
private import cpp
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import SsaInternals as Ssa
|
||||
private import SsaImpl as Ssa
|
||||
|
||||
/**
|
||||
* A property provider that hides all instructions and operands that are not relevant for IR dataflow.
|
||||
|
||||
@@ -2,7 +2,7 @@ private import cpp
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
|
||||
private import SsaInternals as Ssa
|
||||
private import SsaImpl as Ssa
|
||||
private import PrintIRUtilities
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
private import codeql.ssa.Ssa as SsaImplCommon
|
||||
private import codeql.ssa.Ssa as Ssa
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import DataFlowUtil
|
||||
private import DataFlowImplCommon as DataFlowImplCommon
|
||||
@@ -12,7 +12,7 @@ private import semmle.code.cpp.ir.internal.IRCppLanguage
|
||||
private import semmle.code.cpp.ir.dataflow.internal.ModelUtil
|
||||
private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedInitialization
|
||||
private import DataFlowPrivate
|
||||
import SsaInternalsCommon
|
||||
import SsaImplCommon
|
||||
|
||||
private module SourceVariables {
|
||||
cached
|
||||
@@ -153,6 +153,10 @@ private predicate isGlobalDefImpl(
|
||||
GlobalLikeVariable v, IRFunction f, int indirection, int indirectionIndex
|
||||
) {
|
||||
exists(VariableAddressInstruction vai |
|
||||
// The right-hand side of an initialization of a global variable
|
||||
// creates its own `IRFunction`. We don't want flow into that `IRFunction`
|
||||
// since the variable is only initialized once.
|
||||
not vai.getEnclosingFunction() = v and
|
||||
vai.getEnclosingIRFunction() = f and
|
||||
vai.getAstVariable() = v and
|
||||
isUse(_, _, vai, indirection, indirectionIndex) and
|
||||
@@ -880,7 +884,7 @@ private predicate baseSourceVariableIsGlobal(
|
||||
)
|
||||
}
|
||||
|
||||
private module SsaInput implements SsaImplCommon::InputSig<Location> {
|
||||
private module SsaInput implements Ssa::InputSig<Location> {
|
||||
import InputSigCommon
|
||||
import SourceVariables
|
||||
|
||||
@@ -954,9 +958,11 @@ class GlobalDef extends Definition {
|
||||
GlobalLikeVariable getVariable() { result = impl.getVariable() }
|
||||
}
|
||||
|
||||
private module SsaImpl = SsaImplCommon::Make<Location, SsaInput>;
|
||||
private module SsaImpl = Ssa::Make<Location, SsaInput>;
|
||||
|
||||
private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationInputSig {
|
||||
private import codeql.util.Boolean
|
||||
|
||||
class Expr extends Instruction {
|
||||
Expr() {
|
||||
exists(IRBlock bb, int i |
|
||||
@@ -988,10 +994,14 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI
|
||||
result instanceof FalseEdge
|
||||
}
|
||||
|
||||
class GuardValue = Boolean;
|
||||
|
||||
class Guard instanceof IRGuards::IRGuardCondition {
|
||||
string toString() { result = super.toString() }
|
||||
|
||||
predicate hasBranchEdge(SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch) {
|
||||
predicate hasValueBranchEdge(
|
||||
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue branch
|
||||
) {
|
||||
exists(EdgeKind kind |
|
||||
super.getBlock() = bb1 and
|
||||
kind = getConditionalEdge(branch) and
|
||||
@@ -999,12 +1009,14 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI
|
||||
)
|
||||
}
|
||||
|
||||
predicate controlsBranchEdge(SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch) {
|
||||
this.hasBranchEdge(bb1, bb2, branch)
|
||||
predicate valueControlsBranchEdge(
|
||||
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue branch
|
||||
) {
|
||||
this.hasValueBranchEdge(bb1, bb2, branch)
|
||||
}
|
||||
}
|
||||
|
||||
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
|
||||
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, GuardValue branch) {
|
||||
guard.(IRGuards::IRGuardCondition).controls(bb, branch)
|
||||
}
|
||||
|
||||
@@ -1033,7 +1045,8 @@ module BarrierGuardWithIntParam<guardChecksNodeSig/4 guardChecksNode> {
|
||||
}
|
||||
|
||||
private predicate guardChecks(
|
||||
DataFlowIntegrationInput::Guard g, SsaImpl::Definition def, boolean branch, int indirectionIndex
|
||||
DataFlowIntegrationInput::Guard g, SsaImpl::Definition def,
|
||||
DataFlowIntegrationInput::GuardValue branch, int indirectionIndex
|
||||
) {
|
||||
exists(UseImpl use |
|
||||
guardChecksNode(g, use.getNode(), branch, indirectionIndex) and
|
||||
@@ -1112,9 +1125,11 @@ class PhiNode extends Definition instanceof SsaImpl::PhiNode {
|
||||
|
||||
/** An static single assignment (SSA) definition. */
|
||||
class Definition extends SsaImpl::Definition {
|
||||
// TODO: Include prior definitions of uncertain writes or rename predicate
|
||||
// i.e. the disjunct `SsaImpl::uncertainWriteDefinitionInput(this, result)`
|
||||
private Definition getAPhiInputOrPriorDefinition() { result = this.(PhiNode).getAnInput() }
|
||||
private Definition getAPhiInputOrPriorDefinition() {
|
||||
result = this.(PhiNode).getAnInput()
|
||||
or
|
||||
SsaImpl::uncertainWriteDefinitionInput(this, result)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a definition that ultimately defines this SSA definition and is
|
||||
@@ -1125,6 +1140,36 @@ class Definition extends SsaImpl::Definition {
|
||||
not result instanceof PhiNode
|
||||
}
|
||||
|
||||
/** Gets an `Operand` that represents a use of this definition. */
|
||||
Operand getAUse() {
|
||||
exists(SourceVariable sv, IRBlock bb, int i, UseImpl use |
|
||||
ssaDefReachesRead(sv, this, bb, i) and
|
||||
use.hasIndexInBlock(bb, i, sv) and
|
||||
result = use.getNode().asOperand()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an `Operand` that represents an indirect use of this definition.
|
||||
*
|
||||
* The use is indirect because the operand represents a pointer that points
|
||||
* to the value written by this definition. For example in:
|
||||
* ```cpp
|
||||
* 1. int x = 42;
|
||||
* 2. int* p = &x;
|
||||
* ```
|
||||
* There is an `ExplicitDefinition` corresponding to `x = 42` on line 1 and
|
||||
* the definition has an indirect use on line 2 because `&x` points to the
|
||||
* value that was defined by the definition.
|
||||
*/
|
||||
Operand getAnIndirectUse(int indirectionIndex) {
|
||||
exists(SourceVariable sv, IRBlock bb, int i, UseImpl use |
|
||||
ssaDefReachesRead(sv, this, bb, i) and
|
||||
use.hasIndexInBlock(bb, i, sv) and
|
||||
result = use.getNode().asIndirectOperand(indirectionIndex)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
@@ -1157,4 +1202,63 @@ class Definition extends SsaImpl::Definition {
|
||||
Type getUnspecifiedType() { result = this.getUnderlyingType().getUnspecifiedType() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An SSA definition that corresponds to an explicit definition.
|
||||
*/
|
||||
class ExplicitDefinition extends Definition, SsaImpl::WriteDefinition {
|
||||
DefImpl def;
|
||||
|
||||
ExplicitDefinition() {
|
||||
exists(IRBlock bb, int i, SourceVariable sv |
|
||||
this.definesAt(sv, bb, i) and
|
||||
def.hasIndexInBlock(sv, bb, i)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `Instruction` computing the value that is written to the
|
||||
* associated SSA variable by this SSA definition.
|
||||
*
|
||||
* If `this.getIndirectionIndex() = 0` (i.e., if `this` is an instance of
|
||||
* `DirectExplicitDefinition`) then the SSA variable is present in the source
|
||||
* code.
|
||||
* However, if `this.getIndirectionIndex() > 0` (i.e., if `this` is an
|
||||
* instance of `IndirectExplicitDefinition`) then the SSA variable associated
|
||||
* with this definition represents the memory pointed to by a variable in the
|
||||
* source code.
|
||||
*/
|
||||
Instruction getAssignedInstruction() { result = def.getValue().asInstruction() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An explicit SSA definition that writes an indirect value to a pointer.
|
||||
*
|
||||
* For example in:
|
||||
* ```cpp
|
||||
* int x = 42; // (1)
|
||||
* int* p = &x; // (2)
|
||||
* ```
|
||||
* There are three `ExplicitDefinition`:
|
||||
* 1. A `DirectExplicitDefinition` at (1) which writes `42` to the SSA variable
|
||||
* corresponding to `x`.
|
||||
* 2. A `DirectExplicitDefinition` at (2) which writes `&x` to the SSA variable
|
||||
* corresponding to `p`.
|
||||
* 3. A `IndirectExplicitDefinition` at (2) which writes `*&x` (i.e., `x`) to
|
||||
* the SSA variable corresponding to `*p`.
|
||||
*/
|
||||
class IndirectExplicitDefinition extends ExplicitDefinition {
|
||||
IndirectExplicitDefinition() { this.getIndirectionIndex() > 0 }
|
||||
}
|
||||
|
||||
/**
|
||||
* An SSA definition that corresponds to an explicit definition.
|
||||
*
|
||||
* Unlike `ExplicitDefinition` this class does not include indirect
|
||||
* explicit definition. See `IndirectExplicitDefinition` if you want to include
|
||||
* those.
|
||||
*/
|
||||
class DirectExplicitDefinition extends ExplicitDefinition {
|
||||
DirectExplicitDefinition() { this.getIndirectionIndex() = 0 }
|
||||
}
|
||||
|
||||
import SsaCached
|
||||
@@ -5,7 +5,7 @@ private import semmle.code.cpp.models.interfaces.DataFlow
|
||||
private import semmle.code.cpp.models.interfaces.SideEffect
|
||||
private import DataFlowUtil
|
||||
private import DataFlowPrivate
|
||||
private import SsaInternals as Ssa
|
||||
private import SsaImpl as Ssa
|
||||
private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
private import semmle.code.cpp.ir.dataflow.FlowSteps
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ private newtype TOpcode =
|
||||
TCompareGT() or
|
||||
TCompareLE() or
|
||||
TCompareGE() or
|
||||
TSpaceship() or
|
||||
TPointerAdd() or
|
||||
TPointerSub() or
|
||||
TPointerDiff() or
|
||||
@@ -92,7 +93,9 @@ private newtype TOpcode =
|
||||
TUninitializedGroup() or
|
||||
TInlineAsm() or
|
||||
TUnreached() or
|
||||
TNewObj()
|
||||
TNewObj() or
|
||||
TTypeidExpr() or
|
||||
TTypeidType()
|
||||
|
||||
/**
|
||||
* An opcode that specifies the operation performed by an `Instruction`.
|
||||
@@ -763,6 +766,15 @@ module Opcode {
|
||||
final override string toString() { result = "CompareGE" }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `Opcode` for a `SpaceshipInstruction`.
|
||||
*
|
||||
* See the `SpaceshipInstruction` documentation for more details.
|
||||
*/
|
||||
class Spaceship extends BinaryOpcode, TSpaceship {
|
||||
final override string toString() { result = "Spaceship" }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `Opcode` for a `PointerAddInstruction`.
|
||||
*
|
||||
@@ -1281,4 +1293,29 @@ module Opcode {
|
||||
class NewObj extends Opcode, TNewObj {
|
||||
final override string toString() { result = "NewObj" }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `Opcode` for a `TypeidInstruction`.
|
||||
*
|
||||
* See the `TypeidInstruction` documentation for more details.
|
||||
*/
|
||||
abstract class Typeid extends Opcode { }
|
||||
|
||||
/**
|
||||
* The `Opcode` for a `TypeidExprInstruction`.
|
||||
*
|
||||
* See the `TypeidExprInstruction` documentation for more details.
|
||||
*/
|
||||
class TypeidExpr extends Typeid, UnaryOpcode, TTypeidExpr {
|
||||
final override string toString() { result = "TypeidExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `Opcode` for a `TypeidTypeInstruction`.
|
||||
*
|
||||
* See the `TypeidTypeInstruction` documentation for more details.
|
||||
*/
|
||||
class TypeidType extends Typeid, TTypeidType {
|
||||
final override string toString() { result = "TypeidType" }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -725,6 +725,20 @@ class UninitializedInstruction extends VariableInstruction {
|
||||
* Gets the variable that is uninitialized.
|
||||
*/
|
||||
final Language::Variable getLocalVariable() { result = var.(IRUserVariable).getVariable() }
|
||||
|
||||
/**
|
||||
* Gets the operand that provides the address of the location to which the
|
||||
* uninitialized value will be stored.
|
||||
*/
|
||||
final AddressOperand getDestinationAddressOperand() { result = this.getAnOperand() }
|
||||
|
||||
/**
|
||||
* Gets the instruction whose result provides the address of the location to
|
||||
* which the value will be stored, if an exact definition is available.
|
||||
*/
|
||||
final Instruction getDestinationAddress() {
|
||||
result = this.getDestinationAddressOperand().getDef()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1590,6 +1604,13 @@ class CompareGEInstruction extends RelationalInstruction {
|
||||
override predicate isStrict() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that represents a three-way comparison operator.
|
||||
*/
|
||||
class SpaceshipInstruction extends BinaryInstruction {
|
||||
SpaceshipInstruction() { this.getOpcode() instanceof Opcode::Spaceship }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that branches to one of multiple successor instructions based on the value of an
|
||||
* integer operand.
|
||||
@@ -2279,3 +2300,26 @@ class NextVarArgInstruction extends UnaryInstruction {
|
||||
class NewObjInstruction extends Instruction {
|
||||
NewObjInstruction() { this.getOpcode() instanceof Opcode::NewObj }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that returns the type info for its operand.
|
||||
*/
|
||||
class TypeidInstruction extends Instruction {
|
||||
TypeidInstruction() { this.getOpcode() instanceof Opcode::Typeid }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that returns the type info for its operand, where the
|
||||
* operand occurs as an expression in the AST.
|
||||
*/
|
||||
class TypeidExprInstruction extends TypeidInstruction, UnaryInstruction {
|
||||
TypeidExprInstruction() { this.getOpcode() instanceof Opcode::TypeidExpr }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that returns the type info for its operand, where the
|
||||
* operand occurs as a type in the AST.
|
||||
*/
|
||||
class TypeidTypeInstruction extends TypeidInstruction {
|
||||
TypeidTypeInstruction() { this.getOpcode() instanceof Opcode::TypeidType }
|
||||
}
|
||||
|
||||
@@ -725,6 +725,20 @@ class UninitializedInstruction extends VariableInstruction {
|
||||
* Gets the variable that is uninitialized.
|
||||
*/
|
||||
final Language::Variable getLocalVariable() { result = var.(IRUserVariable).getVariable() }
|
||||
|
||||
/**
|
||||
* Gets the operand that provides the address of the location to which the
|
||||
* uninitialized value will be stored.
|
||||
*/
|
||||
final AddressOperand getDestinationAddressOperand() { result = this.getAnOperand() }
|
||||
|
||||
/**
|
||||
* Gets the instruction whose result provides the address of the location to
|
||||
* which the value will be stored, if an exact definition is available.
|
||||
*/
|
||||
final Instruction getDestinationAddress() {
|
||||
result = this.getDestinationAddressOperand().getDef()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1590,6 +1604,13 @@ class CompareGEInstruction extends RelationalInstruction {
|
||||
override predicate isStrict() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that represents a three-way comparison operator.
|
||||
*/
|
||||
class SpaceshipInstruction extends BinaryInstruction {
|
||||
SpaceshipInstruction() { this.getOpcode() instanceof Opcode::Spaceship }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that branches to one of multiple successor instructions based on the value of an
|
||||
* integer operand.
|
||||
@@ -2279,3 +2300,26 @@ class NextVarArgInstruction extends UnaryInstruction {
|
||||
class NewObjInstruction extends Instruction {
|
||||
NewObjInstruction() { this.getOpcode() instanceof Opcode::NewObj }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that returns the type info for its operand.
|
||||
*/
|
||||
class TypeidInstruction extends Instruction {
|
||||
TypeidInstruction() { this.getOpcode() instanceof Opcode::Typeid }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that returns the type info for its operand, where the
|
||||
* operand occurs as an expression in the AST.
|
||||
*/
|
||||
class TypeidExprInstruction extends TypeidInstruction, UnaryInstruction {
|
||||
TypeidExprInstruction() { this.getOpcode() instanceof Opcode::TypeidExpr }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that returns the type info for its operand, where the
|
||||
* operand occurs as a type in the AST.
|
||||
*/
|
||||
class TypeidTypeInstruction extends TypeidInstruction {
|
||||
TypeidTypeInstruction() { this.getOpcode() instanceof Opcode::TypeidType }
|
||||
}
|
||||
|
||||
@@ -1808,6 +1808,11 @@ private Opcode comparisonOpcode(ComparisonOperation expr) {
|
||||
expr instanceof GEExpr and result instanceof Opcode::CompareGE
|
||||
}
|
||||
|
||||
private Opcode spaceShipOpcode(SpaceshipExpr expr) {
|
||||
exists(expr) and
|
||||
result instanceof Opcode::Spaceship
|
||||
}
|
||||
|
||||
/**
|
||||
* IR translation of a simple binary operation.
|
||||
*/
|
||||
@@ -1867,7 +1872,8 @@ class TranslatedBinaryOperation extends TranslatedSingleInstructionExpr {
|
||||
override Opcode getOpcode() {
|
||||
result = binaryArithmeticOpcode(expr) or
|
||||
result = binaryBitwiseOpcode(expr) or
|
||||
result = comparisonOpcode(expr)
|
||||
result = comparisonOpcode(expr) or
|
||||
result = spaceShipOpcode(expr)
|
||||
}
|
||||
|
||||
override Type getExprType() {
|
||||
@@ -4146,7 +4152,8 @@ predicate exprNeedsCopyIfNotLoaded(Expr expr) {
|
||||
private predicate exprImmediatelyDiscarded(Expr expr) {
|
||||
exists(ExprStmt s |
|
||||
s = expr.getParent() and
|
||||
not exists(StmtExpr se | s = se.getStmt().(BlockStmt).getLastStmt())
|
||||
not exists(StmtExpr se | s = se.getStmt().(BlockStmt).getLastStmt()) and
|
||||
not exists(expr.getConversion())
|
||||
)
|
||||
or
|
||||
exists(CommaExpr c | c.getLeftOperand() = expr)
|
||||
@@ -4184,3 +4191,52 @@ class TranslatedAssumeExpr extends TranslatedSingleInstructionExpr {
|
||||
none()
|
||||
}
|
||||
}
|
||||
|
||||
class TranslatedTypeidExpr extends TranslatedSingleInstructionExpr {
|
||||
override TypeidOperator expr;
|
||||
|
||||
final override Opcode getOpcode() {
|
||||
exists(this.getOperand()) and
|
||||
result instanceof Opcode::TypeidExpr
|
||||
or
|
||||
not exists(this.getOperand()) and
|
||||
result instanceof Opcode::TypeidType
|
||||
}
|
||||
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getOperand().getFirstInstruction(kind)
|
||||
or
|
||||
not exists(this.getOperand()) and
|
||||
result = this.getInstruction(OnlyInstructionTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
final override TranslatedElement getChildInternal(int id) {
|
||||
id = 0 and result = this.getOperand()
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getOperand() and
|
||||
result = this.getInstruction(OnlyInstructionTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getOperand().getResult() and
|
||||
operandTag instanceof UnaryOperandTag
|
||||
}
|
||||
|
||||
private TranslatedExpr getOperand() {
|
||||
result = getTranslatedExpr(expr.getExpr().getFullyConverted())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -725,6 +725,20 @@ class UninitializedInstruction extends VariableInstruction {
|
||||
* Gets the variable that is uninitialized.
|
||||
*/
|
||||
final Language::Variable getLocalVariable() { result = var.(IRUserVariable).getVariable() }
|
||||
|
||||
/**
|
||||
* Gets the operand that provides the address of the location to which the
|
||||
* uninitialized value will be stored.
|
||||
*/
|
||||
final AddressOperand getDestinationAddressOperand() { result = this.getAnOperand() }
|
||||
|
||||
/**
|
||||
* Gets the instruction whose result provides the address of the location to
|
||||
* which the value will be stored, if an exact definition is available.
|
||||
*/
|
||||
final Instruction getDestinationAddress() {
|
||||
result = this.getDestinationAddressOperand().getDef()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1590,6 +1604,13 @@ class CompareGEInstruction extends RelationalInstruction {
|
||||
override predicate isStrict() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that represents a three-way comparison operator.
|
||||
*/
|
||||
class SpaceshipInstruction extends BinaryInstruction {
|
||||
SpaceshipInstruction() { this.getOpcode() instanceof Opcode::Spaceship }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that branches to one of multiple successor instructions based on the value of an
|
||||
* integer operand.
|
||||
@@ -2279,3 +2300,26 @@ class NextVarArgInstruction extends UnaryInstruction {
|
||||
class NewObjInstruction extends Instruction {
|
||||
NewObjInstruction() { this.getOpcode() instanceof Opcode::NewObj }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that returns the type info for its operand.
|
||||
*/
|
||||
class TypeidInstruction extends Instruction {
|
||||
TypeidInstruction() { this.getOpcode() instanceof Opcode::Typeid }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that returns the type info for its operand, where the
|
||||
* operand occurs as an expression in the AST.
|
||||
*/
|
||||
class TypeidExprInstruction extends TypeidInstruction, UnaryInstruction {
|
||||
TypeidExprInstruction() { this.getOpcode() instanceof Opcode::TypeidExpr }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that returns the type info for its operand, where the
|
||||
* operand occurs as a type in the AST.
|
||||
*/
|
||||
class TypeidTypeInstruction extends TypeidInstruction {
|
||||
TypeidTypeInstruction() { this.getOpcode() instanceof Opcode::TypeidType }
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
import cpp
|
||||
import PrintfLike
|
||||
private import semmle.code.cpp.ir.dataflow.ResolveCall
|
||||
|
||||
bindingset[index]
|
||||
private string toCause(Function func, int index) {
|
||||
@@ -37,9 +36,9 @@ private predicate wrapperFunctionStep(
|
||||
not target.isVirtual() and
|
||||
not source.isVirtual() and
|
||||
source.hasDefinition() and
|
||||
exists(Call call, Expr arg, Parameter sourceParam |
|
||||
exists(FunctionCall call, Expr arg, Parameter sourceParam |
|
||||
// there is a 'call' to 'target' with argument 'arg' at index 'targetParamIndex'
|
||||
target = resolveCall(call) and
|
||||
target = call.getTarget() and
|
||||
arg = call.getArgument(targetParamIndex) and
|
||||
// 'call' is enclosed in 'source'
|
||||
source = call.getEnclosingFunction() and
|
||||
@@ -154,8 +153,8 @@ abstract class FunctionWithWrappers extends Function {
|
||||
* Whether 'arg' is an argument in a call to an outermost wrapper function of 'this' function.
|
||||
*/
|
||||
predicate outermostWrapperFunctionCall(Expr arg, string callChain) {
|
||||
exists(Function targetFunc, Call call, int argIndex |
|
||||
targetFunc = resolveCall(call) and
|
||||
exists(Function targetFunc, FunctionCall call, int argIndex |
|
||||
targetFunc = call.getTarget() and
|
||||
this.wrapperFunction(targetFunc, argIndex, callChain) and
|
||||
(
|
||||
exists(Function sourceFunc | sourceFunc = call.getEnclosingFunction() |
|
||||
|
||||
@@ -53,44 +53,12 @@
|
||||
|
||||
private import cpp
|
||||
private import semmle.code.cpp.ir.dataflow.internal.ProductFlow
|
||||
private import semmle.code.cpp.security.ProductFlowUtils.ProductFlowUtils
|
||||
private import semmle.code.cpp.ir.ValueNumbering
|
||||
private import semmle.code.cpp.controlflow.IRGuards
|
||||
private import codeql.util.Unit
|
||||
private import semmle.code.cpp.rangeanalysis.new.RangeAnalysisUtil
|
||||
|
||||
private VariableAccess getAVariableAccess(Expr e) { e.getAChild*() = result }
|
||||
|
||||
/**
|
||||
* Gets a (sub)expression that may be the result of evaluating `size`.
|
||||
*
|
||||
* For example, `getASizeCandidate(a ? b : c)` gives `a ? b : c`, `b` and `c`.
|
||||
*/
|
||||
bindingset[size]
|
||||
pragma[inline_late]
|
||||
private Expr getASizeCandidate(Expr size) {
|
||||
result = size
|
||||
or
|
||||
result = [size.(ConditionalExpr).getThen(), size.(ConditionalExpr).getElse()]
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the `(n, state)` pair represents the source of flow for the size
|
||||
* expression associated with `alloc`.
|
||||
*/
|
||||
predicate hasSize(HeuristicAllocationExpr alloc, DataFlow::Node n, int state) {
|
||||
exists(VariableAccess va, Expr size, int delta, Expr s |
|
||||
size = alloc.getSizeExpr() and
|
||||
s = getASizeCandidate(size) and
|
||||
// Get the unique variable in a size expression like `x` in `malloc(x + 1)`.
|
||||
va = unique( | | getAVariableAccess(s)) and
|
||||
// Compute `delta` as the constant difference between `x` and `x + 1`.
|
||||
bounded1(any(Instruction instr | instr.getUnconvertedResultExpression() = s),
|
||||
any(LoadInstruction load | load.getUnconvertedResultExpression() = va), delta) and
|
||||
n.asExpr() = va and
|
||||
state = delta
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the virtual dispatch branching limit when calculating field flow while searching
|
||||
* for flow from an allocation to the construction of an out-of-bounds pointer.
|
||||
@@ -100,125 +68,6 @@ predicate hasSize(HeuristicAllocationExpr alloc, DataFlow::Node n, int state) {
|
||||
*/
|
||||
int allocationToInvalidPointerFieldFlowBranchLimit() { result = 0 }
|
||||
|
||||
/**
|
||||
* A module that encapsulates a barrier guard to remove false positives from flow like:
|
||||
* ```cpp
|
||||
* char *p = new char[size];
|
||||
* // ...
|
||||
* unsigned n = size;
|
||||
* // ...
|
||||
* if(n < size) {
|
||||
* use(*p[n]);
|
||||
* }
|
||||
* ```
|
||||
* In this case, the sink pair identified by the product flow library (without any additional barriers)
|
||||
* would be `(p, n)` (where `n` is the `n` in `p[n]`), because there exists a pointer-arithmetic
|
||||
* instruction `pai = a + b` such that:
|
||||
* 1. the allocation flows to `a`, and
|
||||
* 2. `b <= n` where `n` is the `n` in `p[n]`
|
||||
* but because there's a strict comparison that compares `n` against the size of the allocation this
|
||||
* snippet is fine.
|
||||
*/
|
||||
private module SizeBarrier {
|
||||
private module SizeBarrierConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
// The sources is the same as in the sources for the second
|
||||
// projection in the `AllocToInvalidPointerConfig` module.
|
||||
hasSize(_, source, _) and
|
||||
InterestingPointerAddInstruction::isInterestingSize(source)
|
||||
}
|
||||
|
||||
int fieldFlowBranchLimit() { result = allocationToInvalidPointerFieldFlowBranchLimit() }
|
||||
|
||||
/**
|
||||
* Holds if `small <= large + k` holds if `g` evaluates to `testIsTrue`.
|
||||
*/
|
||||
additional predicate isSink(
|
||||
DataFlow::Node small, DataFlow::Node large, IRGuardCondition g, int k, boolean testIsTrue
|
||||
) {
|
||||
// The sink is any "large" side of a relational comparison. i.e., the `large` expression
|
||||
// in a guard such as `small <= large + k`.
|
||||
g.comparesLt(small.asOperand(), large.asOperand(), k + 1, true, testIsTrue)
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { isSink(_, sink, _, _, _) }
|
||||
}
|
||||
|
||||
module SizeBarrierFlow = DataFlow::Global<SizeBarrierConfig>;
|
||||
|
||||
private int getASizeAddend(DataFlow::Node node) {
|
||||
exists(DataFlow::Node source |
|
||||
SizeBarrierFlow::flow(source, node) and
|
||||
hasSize(_, source, result)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `small <= large + k` holds if `g` evaluates to `edge`.
|
||||
*/
|
||||
private predicate operandGuardChecks(
|
||||
IRGuardCondition g, Operand small, DataFlow::Node large, int k, boolean edge
|
||||
) {
|
||||
SizeBarrierFlow::flowTo(large) and
|
||||
SizeBarrierConfig::isSink(DataFlow::operandNode(small), large, g, k, edge)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instruction `instr` that is guarded by a check such as `instr <= small + delta` where
|
||||
* `small <= _ + k` and `small` is the "small side" of of a relational comparison that checks
|
||||
* whether `small <= size` where `size` is the size of an allocation.
|
||||
*/
|
||||
Instruction getABarrierInstruction0(int delta, int k) {
|
||||
exists(
|
||||
IRGuardCondition g, ValueNumber value, Operand small, boolean edge, DataFlow::Node large
|
||||
|
|
||||
// We know:
|
||||
// 1. result <= value + delta (by `bounded`)
|
||||
// 2. value <= large + k (by `operandGuardChecks`).
|
||||
// So:
|
||||
// result <= value + delta (by 1.)
|
||||
// <= large + k + delta (by 2.)
|
||||
small = value.getAUse() and
|
||||
operandGuardChecks(pragma[only_bind_into](g), pragma[only_bind_into](small), large,
|
||||
pragma[only_bind_into](k), pragma[only_bind_into](edge)) and
|
||||
bounded(result, value.getAnInstruction(), delta) and
|
||||
g.controls(result.getBlock(), edge) and
|
||||
k < getASizeAddend(large)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instruction that is guarded by a guard condition which ensures that
|
||||
* the value of the instruction is upper-bounded by size of some allocation.
|
||||
*/
|
||||
bindingset[state]
|
||||
pragma[inline_late]
|
||||
Instruction getABarrierInstruction(int state) {
|
||||
exists(int delta, int k |
|
||||
state > k + delta and
|
||||
// result <= "size of allocation" + delta + k
|
||||
// < "size of allocation" + state
|
||||
result = getABarrierInstruction0(delta, k)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a `DataFlow::Node` that is guarded by a guard condition which ensures that
|
||||
* the value of the node is upper-bounded by size of some allocation.
|
||||
*/
|
||||
DataFlow::Node getABarrierNode(int state) {
|
||||
exists(DataFlow::Node source, int delta, int k |
|
||||
SizeBarrierFlow::flow(source, result) and
|
||||
hasSize(_, source, state) and
|
||||
result.asInstruction() = SizeBarrier::getABarrierInstruction0(delta, k) and
|
||||
state > k + delta
|
||||
// so now we have:
|
||||
// result <= "size of allocation" + delta + k
|
||||
// < "size of allocation" + state
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private module InterestingPointerAddInstruction {
|
||||
private module PointerAddInstructionConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
@@ -227,7 +76,7 @@ private module InterestingPointerAddInstruction {
|
||||
hasSize(source.asExpr(), _, _)
|
||||
}
|
||||
|
||||
int fieldFlowBranchLimit() { result = allocationToInvalidPointerFieldFlowBranchLimit() }
|
||||
predicate fieldFlowBranchLimit = allocationToInvalidPointerFieldFlowBranchLimit/0;
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
sink.asInstruction() = any(PointerAddInstruction pai).getLeft()
|
||||
@@ -263,6 +112,17 @@ private module InterestingPointerAddInstruction {
|
||||
}
|
||||
}
|
||||
|
||||
private module SizeBarrierInput implements SizeBarrierInputSig {
|
||||
predicate fieldFlowBranchLimit = allocationToInvalidPointerFieldFlowBranchLimit/0;
|
||||
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
// The sources is the same as in the sources for the second
|
||||
// projection in the `AllocToInvalidPointerConfig` module.
|
||||
hasSize(_, source, _) and
|
||||
InterestingPointerAddInstruction::isInterestingSize(source)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A product-flow configuration for flow from an `(allocation, size)` pair to a
|
||||
* pointer-arithmetic operation `pai` such that `pai <= allocation + size`.
|
||||
@@ -301,7 +161,7 @@ private module Config implements ProductFlow::StateConfigSig {
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
|
||||
|
||||
predicate isBarrier2(DataFlow::Node node, FlowState2 state) {
|
||||
node = SizeBarrier::getABarrierNode(state)
|
||||
node = SizeBarrier<SizeBarrierInput>::getABarrierNode(state)
|
||||
}
|
||||
|
||||
predicate isBarrier2(DataFlow::Node node) {
|
||||
@@ -357,8 +217,8 @@ private predicate pointerAddInstructionHasBounds0(
|
||||
sizeInstr = sizeSink.asInstruction() and
|
||||
// pai.getRight() <= sizeSink + delta
|
||||
bounded1(right, sizeInstr, delta) and
|
||||
not right = SizeBarrier::getABarrierInstruction(delta) and
|
||||
not sizeInstr = SizeBarrier::getABarrierInstruction(delta)
|
||||
not right = SizeBarrier<SizeBarrierInput>::getABarrierInstruction(delta) and
|
||||
not sizeInstr = SizeBarrier<SizeBarrierInput>::getABarrierInstruction(delta)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
/**
|
||||
* This file provides the `SizeBarrier` module which provides barriers for
|
||||
* both the `cpp/invalid-pointer-deref` query and the `cpp/overrun-write`
|
||||
* query.
|
||||
*/
|
||||
|
||||
private import cpp
|
||||
private import semmle.code.cpp.dataflow.new.DataFlow
|
||||
private import semmle.code.cpp.ir.ValueNumbering
|
||||
private import semmle.code.cpp.controlflow.IRGuards
|
||||
private import semmle.code.cpp.rangeanalysis.new.RangeAnalysisUtil
|
||||
|
||||
private VariableAccess getAVariableAccess(Expr e) { e.getAChild*() = result }
|
||||
|
||||
/**
|
||||
* Gets a (sub)expression that may be the result of evaluating `size`.
|
||||
*
|
||||
* For example, `getASizeCandidate(a ? b : c)` gives `a ? b : c`, `b` and `c`.
|
||||
*/
|
||||
bindingset[size]
|
||||
pragma[inline_late]
|
||||
private Expr getASizeCandidate(Expr size) {
|
||||
result = size
|
||||
or
|
||||
result = [size.(ConditionalExpr).getThen(), size.(ConditionalExpr).getElse()]
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the `(n, state)` pair represents the source of flow for the size
|
||||
* expression associated with `alloc`.
|
||||
*/
|
||||
predicate hasSize(HeuristicAllocationExpr alloc, DataFlow::Node n, int state) {
|
||||
exists(VariableAccess va, Expr size, int delta, Expr s |
|
||||
size = alloc.getSizeExpr() and
|
||||
s = getASizeCandidate(size) and
|
||||
// Get the unique variable in a size expression like `x` in `malloc(x + 1)`.
|
||||
va = unique( | | getAVariableAccess(s)) and
|
||||
// Compute `delta` as the constant difference between `x` and `x + 1`.
|
||||
bounded1(any(Instruction instr | instr.getUnconvertedResultExpression() = s),
|
||||
any(LoadInstruction load | load.getUnconvertedResultExpression() = va), delta) and
|
||||
n.asExpr() = va and
|
||||
state = delta
|
||||
)
|
||||
}
|
||||
|
||||
/** Provides the input specification of the `SizeBarrier` module. */
|
||||
signature module SizeBarrierInputSig {
|
||||
/** Gets the virtual dispatch branching limit when calculating field flow. */
|
||||
int fieldFlowBranchLimit();
|
||||
|
||||
/** Holds if `source` is a relevant data flow source. */
|
||||
predicate isSource(DataFlow::Node source);
|
||||
}
|
||||
|
||||
/**
|
||||
* A module that encapsulates a barrier guard to remove false positives from flow like:
|
||||
* ```cpp
|
||||
* char *p = new char[size];
|
||||
* // ...
|
||||
* unsigned n = size;
|
||||
* // ...
|
||||
* if(n < size) {
|
||||
* use(*p[n]);
|
||||
* }
|
||||
* ```
|
||||
* In this case, the sink pair identified by the product flow library (without any additional barriers)
|
||||
* would be `(p, n)` (where `n` is the `n` in `p[n]`), because there exists a pointer-arithmetic
|
||||
* instruction `pai = a + b` such that:
|
||||
* 1. the allocation flows to `a`, and
|
||||
* 2. `b <= n` where `n` is the `n` in `p[n]`
|
||||
* but because there's a strict comparison that compares `n` against the size of the allocation this
|
||||
* snippet is fine.
|
||||
*/
|
||||
module SizeBarrier<SizeBarrierInputSig Input> {
|
||||
private module SizeBarrierConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource = Input::isSource/1;
|
||||
|
||||
predicate fieldFlowBranchLimit = Input::fieldFlowBranchLimit/0;
|
||||
|
||||
/**
|
||||
* Holds if `small <= large + k` holds if `g` evaluates to `testIsTrue`.
|
||||
*/
|
||||
additional predicate isSink(
|
||||
DataFlow::Node small, DataFlow::Node large, IRGuardCondition g, int k, boolean testIsTrue
|
||||
) {
|
||||
// The sink is any "large" side of a relational comparison. i.e., the `large` expression
|
||||
// in a guard such as `small <= large + k`.
|
||||
g.comparesLt(small.asOperand(), large.asOperand(), k + 1, true, testIsTrue)
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { isSink(_, sink, _, _, _) }
|
||||
}
|
||||
|
||||
private module SizeBarrierFlow = DataFlow::Global<SizeBarrierConfig>;
|
||||
|
||||
private int getASizeAddend(DataFlow::Node node) {
|
||||
exists(DataFlow::Node source |
|
||||
SizeBarrierFlow::flow(source, node) and
|
||||
hasSize(_, source, result)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `small <= large + k` holds if `g` evaluates to `edge`.
|
||||
*/
|
||||
private predicate operandGuardChecks(
|
||||
IRGuardCondition g, Operand small, DataFlow::Node large, int k, boolean edge
|
||||
) {
|
||||
SizeBarrierFlow::flowTo(large) and
|
||||
SizeBarrierConfig::isSink(DataFlow::operandNode(small), large, g, k, edge)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instruction `instr` that is guarded by a check such as `instr <= small + delta` where
|
||||
* `small <= _ + k` and `small` is the "small side" of a relational comparison that checks
|
||||
* whether `small <= size` where `size` is the size of an allocation.
|
||||
*/
|
||||
private Instruction getABarrierInstruction0(int delta, int k) {
|
||||
exists(
|
||||
IRGuardCondition g, ValueNumber value, Operand small, boolean edge, DataFlow::Node large
|
||||
|
|
||||
// We know:
|
||||
// 1. result <= value + delta (by `bounded`)
|
||||
// 2. value <= large + k (by `operandGuardChecks`).
|
||||
// So:
|
||||
// result <= value + delta (by 1.)
|
||||
// <= large + k + delta (by 2.)
|
||||
small = value.getAUse() and
|
||||
operandGuardChecks(pragma[only_bind_into](g), pragma[only_bind_into](small), large,
|
||||
pragma[only_bind_into](k), pragma[only_bind_into](edge)) and
|
||||
bounded(result, value.getAnInstruction(), delta) and
|
||||
g.controls(result.getBlock(), edge) and
|
||||
k < getASizeAddend(large)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instruction that is guarded by a guard condition which ensures that
|
||||
* the value of the instruction is upper-bounded by size of some allocation.
|
||||
*/
|
||||
bindingset[state]
|
||||
pragma[inline_late]
|
||||
Instruction getABarrierInstruction(int state) {
|
||||
exists(int delta, int k |
|
||||
state > k + delta and
|
||||
// result <= "size of allocation" + delta + k
|
||||
// < "size of allocation" + state
|
||||
result = getABarrierInstruction0(delta, k)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a `DataFlow::Node` that is guarded by a guard condition which ensures that
|
||||
* the value of the node is upper-bounded by size of some allocation.
|
||||
*/
|
||||
DataFlow::Node getABarrierNode(int state) {
|
||||
exists(DataFlow::Node source, int delta, int k |
|
||||
SizeBarrierFlow::flow(source, result) and
|
||||
hasSize(_, source, state) and
|
||||
result.asInstruction() = getABarrierInstruction0(delta, k) and
|
||||
state > k + delta
|
||||
// so now we have:
|
||||
// result <= "size of allocation" + delta + k
|
||||
// < "size of allocation" + state
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,27 @@
|
||||
## 1.4.5
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The "Initialization code not run" query (`cpp/initialization-not-run`) no longer reports an alert on static global variables that have no dereference.
|
||||
|
||||
## 1.4.4
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Due to changes in the `FunctionWithWrappers` library (`semmle.code.cpp.security.FunctionWithWrappers`) the primary alert location generated by the queries `cpp/path-injection`, `cpp/sql-injection`, `cpp/tainted-format-string`, and `cpp/command-line-injection` may have changed.
|
||||
* Added flow models for the Win32 API functions `CreateThread`, `CreateRemoteThread`, and `CreateRemoteThreadEx`.
|
||||
* Improved support for dataflow through function objects and lambda expressions.
|
||||
* Added flow models for `pthread_create` and `std::thread`.
|
||||
* The `cpp/incorrect-string-type-conversion` query no longer alerts on incorrect type conversions that occur in unreachable code.
|
||||
* Added flow models for the GNU C Library.
|
||||
* Fixed a number of false positives and false negatives in `cpp/global-use-before-init`. Note that this query is not part of any of the default query suites.
|
||||
* The query `cpp/sql-injection` now can be extended using the `sql-injection` Models as Data (MaD) sink kind.
|
||||
|
||||
## 1.4.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added flow model for the following libraries: `madler/zlib`, `google/brotli`, `libidn/libidn2`, `libssh2/libssh2/`, `nghttp2/nghttp2`, `libuv/libuv/`, and `curl/curl`. This may result in more alerts when running queries on codebases that use these libraries.
|
||||
* Added flow models for the following libraries: `madler/zlib`, `google/brotli`, `libidn/libidn2`, `libssh2/libssh2`, `nghttp2/nghttp2`, `libuv/libuv`, and `curl/curl`. This may result in more alerts when running queries on codebases that use these libraries.
|
||||
|
||||
## 1.4.2
|
||||
|
||||
@@ -12,7 +31,7 @@ No user-facing changes.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added flow model for the `SQLite` and `OpenSSL` libraries. This may result in more alerts when running queries on codebases that use these libraries.
|
||||
* Added flow models for the `SQLite` and `OpenSSL` libraries. This may result in more alerts when running queries on codebases that use these libraries.
|
||||
|
||||
## 1.4.0
|
||||
|
||||
|
||||
@@ -32,9 +32,18 @@ predicate called(Function f) {
|
||||
exists(FunctionAccess fa | fa.getTarget() = f)
|
||||
}
|
||||
|
||||
predicate staticWithoutDereference(GlobalVariable v) {
|
||||
v.isStatic() and
|
||||
not exists(VariableAccess va |
|
||||
va = v.getAnAccess() and
|
||||
dereferenced(va)
|
||||
)
|
||||
}
|
||||
|
||||
from GlobalVariable v
|
||||
where
|
||||
global(v) and
|
||||
not staticWithoutDereference(v) and
|
||||
not exists(VariableAccess lval |
|
||||
v.getAnAccess() = lval and
|
||||
lval.isUsedAsLValue() and
|
||||
|
||||
@@ -49,21 +49,16 @@ need to be part of the class. (A classic example of this is the
|
||||
observes, there are at least two key problems with this approach:
|
||||
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
It may be possible to generalize some of the utility functions beyond the
|
||||
<i>1. It may be possible to generalize some of the utility functions beyond the
|
||||
narrow context of the class in question -- by bundling them with the class,
|
||||
the class author reduces the scope for functionality reuse.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
It's usually impossible for the class author to know every possible
|
||||
2. It's usually impossible for the class author to know every possible
|
||||
operation that the user might want to perform on the class, so the public
|
||||
interface will inherently be incomplete. New utility functions will end up
|
||||
having a different syntax to the privileged public functions in the class,
|
||||
negatively impacting on code consistency.
|
||||
</li>
|
||||
</ul>
|
||||
</i>
|
||||
|
||||
To refactor a class like this, simply move its utility functions elsewhere,
|
||||
paring its public interface down to the bare minimum.
|
||||
|
||||
@@ -46,21 +46,17 @@ need to be part of the class. (A classic example of this is the
|
||||
<code>std::string</code> class in the C++ Standard Library.) As [Sutter]
|
||||
observes, there are at least two key problems with this approach:
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
It may be possible to generalize some of the utility functions beyond the
|
||||
<i>
|
||||
1. It may be possible to generalize some of the utility functions beyond the
|
||||
narrow context of the class in question -- by bundling them with the class,
|
||||
the class author reduces the scope for functionality reuse.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
It's usually impossible for the class author to know every possible
|
||||
2. It's usually impossible for the class author to know every possible
|
||||
operation that the user might want to perform on the class, so the public
|
||||
interface will inherently be incomplete. New utility functions will end up
|
||||
having a different syntax to the privileged public functions in the class,
|
||||
negatively impacting on code consistency.
|
||||
</li>
|
||||
</ul>
|
||||
</i>
|
||||
|
||||
To refactor a class like this, simply move its utility functions elsewhere,
|
||||
paring its public interface down to the bare minimum.
|
||||
|
||||
@@ -23,7 +23,7 @@ predicate isProcessOperationExplanation(DataFlow::Node arg, string processOperat
|
||||
exists(int processOperationArg, FunctionCall call |
|
||||
isProcessOperationArgument(processOperation, processOperationArg) and
|
||||
call.getTarget().getName() = processOperation and
|
||||
call.getArgument(processOperationArg) = [arg.asExpr(), arg.asIndirectExpr()]
|
||||
call.getArgument(processOperationArg) = arg.asIndirectExpr()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import semmle.code.cpp.models.interfaces.Allocation
|
||||
import semmle.code.cpp.models.interfaces.ArrayFunction
|
||||
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysis
|
||||
import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific
|
||||
import semmle.code.cpp.security.ProductFlowUtils.ProductFlowUtils
|
||||
import semmle.code.cpp.rangeanalysis.new.RangeAnalysisUtil
|
||||
import StringSizeFlow::PathGraph1
|
||||
import codeql.util.Unit
|
||||
@@ -43,20 +44,28 @@ predicate hasSize(HeuristicAllocationExpr alloc, DataFlow::Node n, int state) {
|
||||
)
|
||||
}
|
||||
|
||||
predicate isSinkPairImpl(
|
||||
CallInstruction c, DataFlow::Node bufSink, DataFlow::Node sizeSink, int delta, Expr eBuf
|
||||
/**
|
||||
* Holds if `c` a call to an `ArrayFunction` with buffer argument `bufSink`,
|
||||
* and a size argument `sizeInstr` which satisfies `sizeInstr <= sizeBound + delta`.
|
||||
*
|
||||
* Furthermore, the `sizeSink` node is the dataflow node corresponding to
|
||||
* `sizeBound`, and the expression `eBuf` is the expression corresponding
|
||||
* to `bufInstr`.
|
||||
*/
|
||||
predicate isSinkPairImpl0(
|
||||
CallInstruction c, DataFlow::Node bufSink, DataFlow::Node sizeSink, int delta, Expr eBuf,
|
||||
Instruction sizeBound, Instruction sizeInstr
|
||||
) {
|
||||
exists(
|
||||
int bufIndex, int sizeIndex, Instruction sizeInstr, Instruction bufInstr, ArrayFunction func
|
||||
|
|
||||
exists(int bufIndex, int sizeIndex, Instruction bufInstr, ArrayFunction func |
|
||||
bufInstr = bufSink.asInstruction() and
|
||||
c.getArgument(bufIndex) = bufInstr and
|
||||
sizeInstr = sizeSink.asInstruction() and
|
||||
sizeBound = sizeSink.asInstruction() and
|
||||
c.getArgument(sizeIndex) = sizeInstr and
|
||||
c.getStaticCallTarget() = func and
|
||||
pragma[only_bind_into](func)
|
||||
.hasArrayWithVariableSize(pragma[only_bind_into](bufIndex),
|
||||
pragma[only_bind_into](sizeIndex)) and
|
||||
bounded(c.getArgument(sizeIndex), sizeInstr, delta) and
|
||||
bounded(sizeInstr, sizeBound, delta) and
|
||||
eBuf = bufInstr.getUnconvertedResultExpression()
|
||||
)
|
||||
}
|
||||
@@ -86,99 +95,39 @@ module ValidState {
|
||||
private module ValidStateConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { hasSize(_, source, _) }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { isSinkPairImpl(_, _, sink, _, _) }
|
||||
predicate isSink(DataFlow::Node sink) { isSinkPairImpl0(_, _, sink, _, _, _, _) }
|
||||
|
||||
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
isAdditionalFlowStep2(node1, node2, _)
|
||||
}
|
||||
|
||||
predicate includeHiddenNodes() { any() }
|
||||
predicate isBarrierOut(DataFlow::Node node) { DataFlow::flowsToBackEdge(node) }
|
||||
}
|
||||
|
||||
private import DataFlow::Global<ValidStateConfig>
|
||||
|
||||
private predicate inLoop(PathNode n) { n.getASuccessor+() = n }
|
||||
|
||||
/**
|
||||
* Holds if `value` is a possible offset for `n`.
|
||||
*
|
||||
* To ensure termination, we limit `value` to be in the
|
||||
* range `[-2, 2]` if the node is part of a loop. Without
|
||||
* this restriction we wouldn't terminate on an example like:
|
||||
* ```cpp
|
||||
* while(unknown()) { size++; }
|
||||
* ```
|
||||
*/
|
||||
private predicate validStateImpl(PathNode n, int value) {
|
||||
// If the dataflow node depends recursively on itself we restrict the range.
|
||||
(inLoop(n) implies value = [-2 .. 2]) and
|
||||
(
|
||||
// For the dataflow source we have an allocation such as `malloc(size + k)`,
|
||||
// and the value of the flow-state is then `k`.
|
||||
hasSize(_, n.getNode(), value)
|
||||
or
|
||||
// For a dataflow sink any `value` that is strictly smaller than the delta
|
||||
// needs to be a valid flow-state. That is, for a snippet like:
|
||||
// ```
|
||||
// p = b ? new char[size] : new char[size + 1];
|
||||
// memset(p, 0, size + 2);
|
||||
// ```
|
||||
// the valid flow-states at the `memset` must include the set `{0, 1}` since the
|
||||
// flow-state at `new char[size]` is `0`, and the flow-state at `new char[size + 1]`
|
||||
// is `1`.
|
||||
//
|
||||
// So we find a valid flow-state at the sink's predecessor, and use the definition
|
||||
// of our sink predicate to compute the valid flow-states at the sink.
|
||||
exists(int delta, PathNode n0 |
|
||||
n0.getASuccessor() = n and
|
||||
validStateImpl(n0, value) and
|
||||
isSinkPairImpl(_, _, n.getNode(), delta, _) and
|
||||
delta > value
|
||||
)
|
||||
or
|
||||
// For a non-source and non-sink node there is two cases to consider.
|
||||
// 1. A node where we have to update the flow-state, or
|
||||
// 2. A node that doesn't update the flow-state.
|
||||
//
|
||||
// For case 1, we compute the new flow-state by adding the constant operand of the
|
||||
// `AddInstruction` to the flow-state of any predecessor node.
|
||||
// For case 2 we simply propagate the valid flow-states from the predecessor node to
|
||||
// the next one.
|
||||
exists(PathNode n0, DataFlow::Node node0, DataFlow::Node node, int value0 |
|
||||
n0.getASuccessor() = n and
|
||||
validStateImpl(n0, value0) and
|
||||
node = n.getNode() and
|
||||
node0 = n0.getNode()
|
||||
|
|
||||
exists(int delta |
|
||||
isAdditionalFlowStep2(node0, node, delta) and
|
||||
value0 = value + delta
|
||||
)
|
||||
or
|
||||
not isAdditionalFlowStep2(node0, node, _) and
|
||||
value = value0
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
predicate validState(DataFlow::Node n, int value) {
|
||||
validStateImpl(any(PathNode pn | pn.getNode() = n), value)
|
||||
predicate validState(DataFlow::Node source, DataFlow::Node sink, int value) {
|
||||
hasSize(_, source, value) and
|
||||
flow(source, sink)
|
||||
}
|
||||
}
|
||||
|
||||
import ValidState
|
||||
|
||||
/**
|
||||
* Holds if `node2` is a dataflow node that represents an addition of two operands `op1`
|
||||
* and `op2` such that:
|
||||
* 1. `node1` is the dataflow node that represents `op1`, and
|
||||
* 2. the value of `op2` can be upper bounded by `delta.`
|
||||
*/
|
||||
predicate isAdditionalFlowStep2(DataFlow::Node node1, DataFlow::Node node2, int delta) {
|
||||
exists(AddInstruction add, Operand op |
|
||||
add.hasOperands(node1.asOperand(), op) and
|
||||
semBounded(getSemanticExpr(op.getDef()), any(SemZeroBound zero), delta, true, _) and
|
||||
node2.asInstruction() = add
|
||||
module SizeBarrierInput implements SizeBarrierInputSig {
|
||||
int fieldFlowBranchLimit() { result = 2 }
|
||||
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
exists(int state |
|
||||
hasSize(_, source, state) and
|
||||
validState(source, _, state)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
predicate isSinkPairImpl(
|
||||
CallInstruction c, DataFlow::Node bufSink, DataFlow::Node sizeSink, int delta, Expr eBuf
|
||||
) {
|
||||
exists(Instruction sizeBound, Instruction sizeInstr |
|
||||
isSinkPairImpl0(c, bufSink, sizeSink, delta, eBuf, sizeBound, sizeInstr) and
|
||||
not sizeBound = SizeBarrier<SizeBarrierInput>::getABarrierInstruction(delta) and
|
||||
not sizeInstr = SizeBarrier<SizeBarrierInput>::getABarrierInstruction(delta)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -198,14 +147,14 @@ module StringSizeConfig implements ProductFlow::StateConfigSig {
|
||||
// to the size of the allocation. This state is then checked in `isSinkPair`.
|
||||
exists(state1) and
|
||||
hasSize(bufSource.asExpr(), sizeSource, state2) and
|
||||
validState(sizeSource, state2)
|
||||
validState(sizeSource, _, state2)
|
||||
}
|
||||
|
||||
predicate isSinkPair(
|
||||
DataFlow::Node bufSink, FlowState1 state1, DataFlow::Node sizeSink, FlowState2 state2
|
||||
) {
|
||||
exists(state1) and
|
||||
validState(sizeSink, state2) and
|
||||
validState(_, sizeSink, state2) and
|
||||
exists(int delta |
|
||||
isSinkPairImpl(_, bufSink, sizeSink, delta, _) and
|
||||
delta > state2
|
||||
@@ -214,14 +163,8 @@ module StringSizeConfig implements ProductFlow::StateConfigSig {
|
||||
|
||||
predicate isBarrierOut2(DataFlow::Node node) { DataFlow::flowsToBackEdge(node) }
|
||||
|
||||
predicate isAdditionalFlowStep2(
|
||||
DataFlow::Node node1, FlowState2 state1, DataFlow::Node node2, FlowState2 state2
|
||||
) {
|
||||
validState(node2, state2) and
|
||||
exists(int delta |
|
||||
isAdditionalFlowStep2(node1, node2, delta) and
|
||||
state1 = state2 + delta
|
||||
)
|
||||
predicate isBarrier2(DataFlow::Node node, FlowState2 state) {
|
||||
node = SizeBarrier<SizeBarrierInput>::getABarrierNode(state)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.controlflow.Guards
|
||||
import semmle.code.cpp.ir.IR
|
||||
|
||||
class WideCharPointerType extends PointerType {
|
||||
WideCharPointerType() { this.getBaseType() instanceof WideCharType }
|
||||
@@ -108,7 +109,9 @@ where
|
||||
// Avoid cases where the cast is guarded by a check to determine if
|
||||
// unicode encoding is enabled in such a way to disallow the dangerous cast
|
||||
// at runtime.
|
||||
not isLikelyDynamicallyChecked(e1)
|
||||
not isLikelyDynamicallyChecked(e1) and
|
||||
// Avoid cases in unreachable blocks.
|
||||
any(EnterFunctionInstruction e).getASuccessor+().getAst() = e1
|
||||
select e1,
|
||||
"Conversion from " + e1.getType().toString() + " to " + e2.getType().toString() +
|
||||
". Use of invalid string can lead to undefined behavior."
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The query `cpp/sql-injection` now can be extended using the `sql-injection` Models as Data (MaD) sink kind.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Fixed a number of false positives and false negatives in `cpp/global-use-before-init`. Note that this query is not part of any of the default query suites.
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added flow model for the `SQLite` and `OpenSSL` libraries. This may result in more alerts when running queries on codebases that use these libraries.
|
||||
* Added flow models for the `SQLite` and `OpenSSL` libraries. This may result in more alerts when running queries on codebases that use these libraries.
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added flow model for the following libraries: `madler/zlib`, `google/brotli`, `libidn/libidn2`, `libssh2/libssh2/`, `nghttp2/nghttp2`, `libuv/libuv/`, and `curl/curl`. This may result in more alerts when running queries on codebases that use these libraries.
|
||||
* Added flow models for the following libraries: `madler/zlib`, `google/brotli`, `libidn/libidn2`, `libssh2/libssh2`, `nghttp2/nghttp2`, `libuv/libuv`, and `curl/curl`. This may result in more alerts when running queries on codebases that use these libraries.
|
||||
|
||||
12
cpp/ql/src/change-notes/released/1.4.4.md
Normal file
12
cpp/ql/src/change-notes/released/1.4.4.md
Normal file
@@ -0,0 +1,12 @@
|
||||
## 1.4.4
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Due to changes in the `FunctionWithWrappers` library (`semmle.code.cpp.security.FunctionWithWrappers`) the primary alert location generated by the queries `cpp/path-injection`, `cpp/sql-injection`, `cpp/tainted-format-string`, and `cpp/command-line-injection` may have changed.
|
||||
* Added flow models for the Win32 API functions `CreateThread`, `CreateRemoteThread`, and `CreateRemoteThreadEx`.
|
||||
* Improved support for dataflow through function objects and lambda expressions.
|
||||
* Added flow models for `pthread_create` and `std::thread`.
|
||||
* The `cpp/incorrect-string-type-conversion` query no longer alerts on incorrect type conversions that occur in unreachable code.
|
||||
* Added flow models for the GNU C Library.
|
||||
* Fixed a number of false positives and false negatives in `cpp/global-use-before-init`. Note that this query is not part of any of the default query suites.
|
||||
* The query `cpp/sql-injection` now can be extended using the `sql-injection` Models as Data (MaD) sink kind.
|
||||
5
cpp/ql/src/change-notes/released/1.4.5.md
Normal file
5
cpp/ql/src/change-notes/released/1.4.5.md
Normal file
@@ -0,0 +1,5 @@
|
||||
## 1.4.5
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The "Initialization code not run" query (`cpp/initialization-not-run`) no longer reports an alert on static global variables that have no dereference.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.4.3
|
||||
lastReleaseVersion: 1.4.5
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 1.4.4-dev
|
||||
version: 1.4.5
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
@@ -37,4 +37,21 @@ void test_aggregate_literal() {
|
||||
|
||||
int xs[] = {1, 2, 3}; // $ asExpr=1 asExpr=2 asExpr=3 asExpr={...}
|
||||
const int ys[] = {[0] = 4, [1] = 5, [0] = 6}; // $ asExpr=4 asExpr=5 asExpr=6 asExpr={...}
|
||||
}
|
||||
}
|
||||
|
||||
void test_postfix_crement(int *p, int q) {
|
||||
p++; // $ asExpr="... ++" asIndirectExpr="... ++" asExpr=p asIndirectExpr=p
|
||||
q++; // $ asExpr="... ++" asExpr=q
|
||||
(p++); // $ asExpr="... ++" asIndirectExpr="... ++" asExpr="p(... ++)" asIndirectExpr="p(*... ++)"
|
||||
(q++); // $ asExpr="... ++" asExpr="q(... ++)"
|
||||
(void)(p++); // $ asExpr="p(... ++)" asIndirectExpr="p(*... ++)"
|
||||
(void)(q++); // $ asExpr="q(... ++)"
|
||||
(void)p++; // $ asExpr="p(... ++)" asIndirectExpr="p(*... ++)"
|
||||
(void)q++; // $ asExpr="q(... ++)"
|
||||
int *p1 = p++; // $ asExpr="... ++" asIndirectExpr="... ++" asExpr="p(... ++)" asIndirectExpr="p(*... ++)"
|
||||
int q1 = q++; // $ asExpr="... ++" asExpr="q(... ++)"
|
||||
(int*)(p++); // $ asExpr="... ++" asIndirectExpr="... ++" asExpr="p(... ++)" asIndirectExpr="p(*... ++)"
|
||||
(int)(q++); // $ asExpr="... ++" asExpr="q(... ++)"
|
||||
int *p2 = (int*)(p++); // $ asExpr="... ++" asIndirectExpr="... ++" asExpr="p(... ++)" asIndirectExpr="p(*... ++)"
|
||||
int q2 = (int)(q++); // $ asExpr="... ++" asExpr="q(... ++)"
|
||||
}
|
||||
|
||||
@@ -6,9 +6,15 @@ uniqueEnclosingCallable
|
||||
| test.cpp:1126:33:1129:1 | {...} | Node should have one enclosing callable but has 0. |
|
||||
| test.cpp:1127:3:1127:13 | reads_input | Node should have one enclosing callable but has 0. |
|
||||
| test.cpp:1128:3:1128:21 | not_does_read_input | Node should have one enclosing callable but has 0. |
|
||||
| test.cpp:1158:18:1158:21 | call to sink | Node should have one enclosing callable but has 0. |
|
||||
| test.cpp:1158:18:1158:42 | ... , ... | Node should have one enclosing callable but has 0. |
|
||||
| test.cpp:1158:23:1158:31 | recursion | Node should have one enclosing callable but has 0. |
|
||||
| test.cpp:1158:35:1158:40 | call to source | Node should have one enclosing callable but has 0. |
|
||||
uniqueCallEnclosingCallable
|
||||
| test.cpp:864:47:864:54 | call to source | Call should have one enclosing callable but has 0. |
|
||||
| test.cpp:872:46:872:51 | call to source | Call should have one enclosing callable but has 0. |
|
||||
| test.cpp:1158:18:1158:21 | call to sink | Call should have one enclosing callable but has 0. |
|
||||
| test.cpp:1158:35:1158:40 | call to source | Call should have one enclosing callable but has 0. |
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
|
||||
@@ -24,10 +24,9 @@ module AstTest {
|
||||
|
||||
module IRTest {
|
||||
private import semmle.code.cpp.ir.dataflow.DataFlow
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
|
||||
|
||||
private string stars(int k) {
|
||||
k = [0 .. max(FinalParameterNode n | | n.getIndirectionIndex())] and
|
||||
k = [0 .. max(DataFlow::Node n, int i | n.isFinalValueOfParameter(_, i) | i)] and
|
||||
(if k = 0 then result = "" else result = "*" + stars(k - 1))
|
||||
}
|
||||
|
||||
@@ -35,14 +34,14 @@ module IRTest {
|
||||
string getARelevantTag() { result = "ir-def" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(Function f, Parameter p, FinalParameterNode n |
|
||||
exists(Function f, Parameter p, DataFlow::Node n, int i |
|
||||
p.isNamed() and
|
||||
n.getParameter() = p and
|
||||
n.isFinalValueOfParameter(p, i) and
|
||||
n.getFunction() = f and
|
||||
location = f.getLocation() and
|
||||
element = p.toString() and
|
||||
tag = "ir-def" and
|
||||
value = stars(n.getIndirectionIndex()) + p.getName()
|
||||
value = stars(i) + p.getName()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1153,4 +1153,6 @@ namespace conflation_regression {
|
||||
*p = source(0);
|
||||
read_deref_deref(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int recursion = (sink(recursion), source()); // clean
|
||||
@@ -17,13 +17,26 @@ models
|
||||
| 16 | Source: ; ; false; ymlSource; ; ; ReturnValue; local; manual |
|
||||
| 17 | Source: boost::asio; ; false; read_until; ; ; Argument[*1]; remote; manual |
|
||||
| 18 | Summary: ; ; false; CommandLineToArgvA; ; ; Argument[*0]; ReturnValue[**]; taint; manual |
|
||||
| 19 | Summary: ; ; false; ReadFileEx; ; ; Argument[*3].Field[@hEvent]; Argument[4].Parameter[*2].Field[@hEvent]; value; manual |
|
||||
| 20 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated |
|
||||
| 21 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||
| 22 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||
| 23 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual |
|
||||
| 19 | Summary: ; ; false; CreateRemoteThread; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual |
|
||||
| 20 | Summary: ; ; false; CreateRemoteThreadEx; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual |
|
||||
| 21 | Summary: ; ; false; CreateThread; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
|
||||
| 22 | Summary: ; ; false; ReadFileEx; ; ; Argument[*3].Field[@hEvent]; Argument[4].Parameter[*2].Field[@hEvent]; value; manual |
|
||||
| 23 | Summary: ; ; false; RtlCopyDeviceMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 24 | Summary: ; ; false; RtlCopyMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 25 | Summary: ; ; false; RtlCopyMemoryNonTemporal; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 26 | Summary: ; ; false; RtlCopyUnicodeString; ; ; Argument[*1].Field[*Buffer]; Argument[*0].Field[*Buffer]; value; manual |
|
||||
| 27 | Summary: ; ; false; RtlCopyVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 28 | Summary: ; ; false; RtlInitUnicodeString; ; ; Argument[*1]; Argument[*0].Field[*Buffer]; value; manual |
|
||||
| 29 | Summary: ; ; false; RtlMoveMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 30 | Summary: ; ; false; RtlMoveVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 31 | Summary: ; ; false; callWithArgument; ; ; Argument[1]; Argument[0].Parameter[0]; value; manual |
|
||||
| 32 | Summary: ; ; false; pthread_create; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
|
||||
| 33 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated |
|
||||
| 34 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||
| 35 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||
| 36 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual |
|
||||
edges
|
||||
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:23 |
|
||||
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:36 |
|
||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:91:7:91:17 | recv_buffer | provenance | Src:MaD:17 |
|
||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:93:29:93:39 | *recv_buffer | provenance | Src:MaD:17 Sink:MaD:2 |
|
||||
| asio_streams.cpp:97:37:97:44 | call to source | asio_streams.cpp:98:7:98:14 | send_str | provenance | TaintFunction |
|
||||
@@ -32,10 +45,10 @@ edges
|
||||
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:101:7:101:17 | send_buffer | provenance | |
|
||||
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:2 |
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | |
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:23 |
|
||||
| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | provenance | MaD:21 |
|
||||
| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | provenance | MaD:20 |
|
||||
| test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | provenance | MaD:22 |
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:36 |
|
||||
| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | provenance | MaD:34 |
|
||||
| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | provenance | MaD:33 |
|
||||
| test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | provenance | MaD:35 |
|
||||
| test.cpp:7:47:7:52 | value2 | test.cpp:7:64:7:69 | value2 | provenance | |
|
||||
| test.cpp:7:64:7:69 | value2 | test.cpp:7:5:7:30 | *ymlStepGenerated_with_body | provenance | |
|
||||
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:10:10:10:18 | call to ymlSource | provenance | Src:MaD:16 |
|
||||
@@ -47,19 +60,49 @@ edges
|
||||
| test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | |
|
||||
| test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:18:10:18:10 | y | provenance | Sink:MaD:1 |
|
||||
| test.cpp:17:24:17:24 | x | test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | provenance | |
|
||||
| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | MaD:21 |
|
||||
| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | MaD:34 |
|
||||
| test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | |
|
||||
| test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:22:10:22:10 | z | provenance | Sink:MaD:1 |
|
||||
| test.cpp:21:27:21:27 | x | test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | provenance | |
|
||||
| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | MaD:20 |
|
||||
| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | MaD:33 |
|
||||
| test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | |
|
||||
| test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:26:10:26:11 | y2 | provenance | Sink:MaD:1 |
|
||||
| test.cpp:25:35:25:35 | x | test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | provenance | |
|
||||
| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | MaD:22 |
|
||||
| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | MaD:35 |
|
||||
| test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | provenance | |
|
||||
| test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:33:10:33:11 | z2 | provenance | Sink:MaD:1 |
|
||||
| test.cpp:32:41:32:41 | x | test.cpp:7:47:7:52 | value2 | provenance | |
|
||||
| test.cpp:32:41:32:41 | x | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | provenance | |
|
||||
| test.cpp:46:30:46:32 | *arg [x] | test.cpp:47:12:47:19 | *arg [x] | provenance | |
|
||||
| test.cpp:47:12:47:19 | *arg [x] | test.cpp:48:13:48:13 | *s [x] | provenance | |
|
||||
| test.cpp:48:13:48:13 | *s [x] | test.cpp:48:16:48:16 | x | provenance | Sink:MaD:1 |
|
||||
| test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | test.cpp:52:5:52:18 | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] | provenance | MaD:32 |
|
||||
| test.cpp:52:5:52:18 | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] | test.cpp:46:30:46:32 | *arg [x] | provenance | |
|
||||
| test.cpp:56:2:56:2 | *s [post update] [x] | test.cpp:59:55:59:64 | *& ... [x] | provenance | |
|
||||
| test.cpp:56:2:56:18 | ... = ... | test.cpp:56:2:56:2 | *s [post update] [x] | provenance | |
|
||||
| test.cpp:56:8:56:16 | call to ymlSource | test.cpp:56:2:56:18 | ... = ... | provenance | Src:MaD:16 |
|
||||
| test.cpp:59:55:59:64 | *& ... [x] | test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | provenance | |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:31 |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:31 |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:31 |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:31 |
|
||||
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:68:22:68:22 | y | provenance | |
|
||||
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:74:22:74:22 | y | provenance | |
|
||||
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:82:22:82:22 | y | provenance | |
|
||||
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:88:22:88:22 | y | provenance | |
|
||||
| test.cpp:68:22:68:22 | y | test.cpp:69:11:69:11 | y | provenance | Sink:MaD:1 |
|
||||
| test.cpp:74:22:74:22 | y | test.cpp:75:11:75:11 | y | provenance | Sink:MaD:1 |
|
||||
| test.cpp:82:22:82:22 | y | test.cpp:83:11:83:11 | y | provenance | Sink:MaD:1 |
|
||||
| test.cpp:88:22:88:22 | y | test.cpp:89:11:89:11 | y | provenance | Sink:MaD:1 |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:94:10:94:18 | call to ymlSource | provenance | Src:MaD:16 |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:97:26:97:26 | x | provenance | |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:101:26:101:26 | x | provenance | |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:103:63:103:63 | x | provenance | |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:104:62:104:62 | x | provenance | |
|
||||
| test.cpp:97:26:97:26 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
|
||||
| test.cpp:101:26:101:26 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
|
||||
| test.cpp:103:63:103:63 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
|
||||
| test.cpp:104:62:104:62 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
|
||||
| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | provenance | MaD:18 |
|
||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:22:15:22:29 | *call to GetCommandLineA | provenance | Src:MaD:3 |
|
||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:24:8:24:11 | * ... | provenance | |
|
||||
@@ -73,8 +116,8 @@ edges
|
||||
| windows.cpp:39:36:39:38 | GetEnvironmentVariableA output argument | windows.cpp:41:10:41:13 | * ... | provenance | Src:MaD:5 |
|
||||
| windows.cpp:90:6:90:15 | [summary param] *3 in ReadFileEx [*hEvent] | windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | provenance | |
|
||||
| windows.cpp:90:6:90:15 | [summary param] *3 in ReadFileEx [hEvent] | windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | provenance | |
|
||||
| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | provenance | MaD:19 |
|
||||
| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx | provenance | MaD:19 |
|
||||
| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | provenance | MaD:22 |
|
||||
| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx | provenance | MaD:22 |
|
||||
| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] | windows.cpp:147:16:147:27 | *lpOverlapped [*hEvent] | provenance | |
|
||||
| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [hEvent] | windows.cpp:157:16:157:27 | *lpOverlapped [hEvent] | provenance | |
|
||||
| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] | provenance | |
|
||||
@@ -122,6 +165,82 @@ edges
|
||||
| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | provenance | Src:MaD:12 |
|
||||
| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | windows.cpp:333:20:333:52 | *pMapView | provenance | |
|
||||
| windows.cpp:333:20:333:52 | *pMapView | windows.cpp:335:10:335:16 | * ... | provenance | |
|
||||
| windows.cpp:349:8:349:19 | [summary param] *3 in CreateThread [x] | windows.cpp:349:8:349:19 | [summary] to write: Argument[2].Parameter[*0] in CreateThread [x] | provenance | MaD:21 |
|
||||
| windows.cpp:349:8:349:19 | [summary] to write: Argument[2].Parameter[*0] in CreateThread [x] | windows.cpp:403:26:403:36 | *lpParameter [x] | provenance | |
|
||||
| windows.cpp:357:8:357:25 | [summary param] *4 in CreateRemoteThread [x] | windows.cpp:357:8:357:25 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThread [x] | provenance | MaD:19 |
|
||||
| windows.cpp:357:8:357:25 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThread [x] | windows.cpp:410:26:410:36 | *lpParameter [x] | provenance | |
|
||||
| windows.cpp:387:8:387:27 | [summary param] *4 in CreateRemoteThreadEx [x] | windows.cpp:387:8:387:27 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThreadEx [x] | provenance | MaD:20 |
|
||||
| windows.cpp:387:8:387:27 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThreadEx [x] | windows.cpp:417:26:417:36 | *lpParameter [x] | provenance | |
|
||||
| windows.cpp:403:26:403:36 | *lpParameter [x] | windows.cpp:405:10:405:25 | *lpParameter [x] | provenance | |
|
||||
| windows.cpp:405:10:405:25 | *lpParameter [x] | windows.cpp:406:8:406:8 | *s [x] | provenance | |
|
||||
| windows.cpp:406:8:406:8 | *s [x] | windows.cpp:406:8:406:11 | x | provenance | |
|
||||
| windows.cpp:410:26:410:36 | *lpParameter [x] | windows.cpp:412:10:412:25 | *lpParameter [x] | provenance | |
|
||||
| windows.cpp:412:10:412:25 | *lpParameter [x] | windows.cpp:413:8:413:8 | *s [x] | provenance | |
|
||||
| windows.cpp:413:8:413:8 | *s [x] | windows.cpp:413:8:413:11 | x | provenance | |
|
||||
| windows.cpp:417:26:417:36 | *lpParameter [x] | windows.cpp:419:10:419:25 | *lpParameter [x] | provenance | |
|
||||
| windows.cpp:419:10:419:25 | *lpParameter [x] | windows.cpp:420:8:420:8 | *s [x] | provenance | |
|
||||
| windows.cpp:420:8:420:8 | *s [x] | windows.cpp:420:8:420:11 | x | provenance | |
|
||||
| windows.cpp:431:3:431:3 | *s [post update] [x] | windows.cpp:439:7:439:8 | *& ... [x] | provenance | |
|
||||
| windows.cpp:431:3:431:3 | *s [post update] [x] | windows.cpp:451:7:451:8 | *& ... [x] | provenance | |
|
||||
| windows.cpp:431:3:431:3 | *s [post update] [x] | windows.cpp:464:7:464:8 | *& ... [x] | provenance | |
|
||||
| windows.cpp:431:3:431:16 | ... = ... | windows.cpp:431:3:431:3 | *s [post update] [x] | provenance | |
|
||||
| windows.cpp:431:9:431:14 | call to source | windows.cpp:431:3:431:16 | ... = ... | provenance | |
|
||||
| windows.cpp:439:7:439:8 | *& ... [x] | windows.cpp:349:8:349:19 | [summary param] *3 in CreateThread [x] | provenance | |
|
||||
| windows.cpp:451:7:451:8 | *& ... [x] | windows.cpp:357:8:357:25 | [summary param] *4 in CreateRemoteThread [x] | provenance | |
|
||||
| windows.cpp:464:7:464:8 | *& ... [x] | windows.cpp:387:8:387:27 | [summary param] *4 in CreateRemoteThreadEx [x] | provenance | |
|
||||
| windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | windows.cpp:473:17:473:37 | [summary param] *0 in RtlCopyVolatileMemory [Return] | provenance | MaD:27 |
|
||||
| windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | windows.cpp:479:17:479:35 | [summary param] *0 in RtlCopyDeviceMemory [Return] | provenance | MaD:23 |
|
||||
| windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | windows.cpp:485:6:485:18 | [summary param] *0 in RtlCopyMemory [Return] | provenance | MaD:24 |
|
||||
| windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | windows.cpp:493:6:493:29 | [summary param] *0 in RtlCopyMemoryNonTemporal [Return] | provenance | MaD:25 |
|
||||
| windows.cpp:510:6:510:25 | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | windows.cpp:510:6:510:25 | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString | provenance | |
|
||||
| windows.cpp:510:6:510:25 | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString | windows.cpp:510:6:510:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString | provenance | MaD:26 |
|
||||
| windows.cpp:510:6:510:25 | [summary] to write: Argument[*0] in RtlCopyUnicodeString [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *0 in RtlCopyUnicodeString [Return] [*Buffer] | provenance | |
|
||||
| windows.cpp:510:6:510:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString | windows.cpp:510:6:510:25 | [summary] to write: Argument[*0] in RtlCopyUnicodeString [*Buffer] | provenance | |
|
||||
| windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | windows.cpp:515:6:515:18 | [summary param] *0 in RtlMoveMemory [Return] | provenance | MaD:29 |
|
||||
| windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | windows.cpp:521:17:521:37 | [summary param] *0 in RtlMoveVolatileMemory [Return] | provenance | MaD:30 |
|
||||
| windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | windows.cpp:527:6:527:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString | provenance | MaD:28 |
|
||||
| windows.cpp:527:6:527:25 | [summary] to write: Argument[*0] in RtlInitUnicodeString [*Buffer] | windows.cpp:527:6:527:25 | [summary param] *0 in RtlInitUnicodeString [Return] [*Buffer] | provenance | |
|
||||
| windows.cpp:527:6:527:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString | windows.cpp:527:6:527:25 | [summary] to write: Argument[*0] in RtlInitUnicodeString [*Buffer] | provenance | |
|
||||
| windows.cpp:533:11:533:16 | call to source | windows.cpp:533:11:533:16 | call to source | provenance | |
|
||||
| windows.cpp:533:11:533:16 | call to source | windows.cpp:537:40:537:41 | *& ... | provenance | |
|
||||
| windows.cpp:533:11:533:16 | call to source | windows.cpp:542:38:542:39 | *& ... | provenance | |
|
||||
| windows.cpp:533:11:533:16 | call to source | windows.cpp:547:32:547:33 | *& ... | provenance | |
|
||||
| windows.cpp:533:11:533:16 | call to source | windows.cpp:552:43:552:44 | *& ... | provenance | |
|
||||
| windows.cpp:533:11:533:16 | call to source | windows.cpp:568:32:568:33 | *& ... | provenance | |
|
||||
| windows.cpp:533:11:533:16 | call to source | windows.cpp:573:40:573:41 | *& ... | provenance | |
|
||||
| windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | windows.cpp:538:10:538:23 | access to array | provenance | |
|
||||
| windows.cpp:537:40:537:41 | *& ... | windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | provenance | |
|
||||
| windows.cpp:537:40:537:41 | *& ... | windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | provenance | MaD:27 |
|
||||
| windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | windows.cpp:543:10:543:23 | access to array | provenance | |
|
||||
| windows.cpp:542:38:542:39 | *& ... | windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | provenance | |
|
||||
| windows.cpp:542:38:542:39 | *& ... | windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | provenance | MaD:23 |
|
||||
| windows.cpp:547:19:547:29 | RtlCopyMemory output argument | windows.cpp:548:10:548:23 | access to array | provenance | |
|
||||
| windows.cpp:547:32:547:33 | *& ... | windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | provenance | |
|
||||
| windows.cpp:547:32:547:33 | *& ... | windows.cpp:547:19:547:29 | RtlCopyMemory output argument | provenance | MaD:24 |
|
||||
| windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument | windows.cpp:553:10:553:23 | access to array | provenance | |
|
||||
| windows.cpp:552:43:552:44 | *& ... | windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | provenance | |
|
||||
| windows.cpp:552:43:552:44 | *& ... | windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument | provenance | MaD:25 |
|
||||
| windows.cpp:559:5:559:24 | ... = ... | windows.cpp:561:39:561:44 | *buffer | provenance | |
|
||||
| windows.cpp:559:17:559:24 | call to source | windows.cpp:559:5:559:24 | ... = ... | provenance | |
|
||||
| windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | windows.cpp:562:10:562:19 | *src_string [*Buffer] | provenance | |
|
||||
| windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | windows.cpp:563:40:563:50 | *& ... [*Buffer] | provenance | |
|
||||
| windows.cpp:561:39:561:44 | *buffer | windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | provenance | |
|
||||
| windows.cpp:561:39:561:44 | *buffer | windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | provenance | MaD:28 |
|
||||
| windows.cpp:562:10:562:19 | *src_string [*Buffer] | windows.cpp:562:10:562:29 | access to array | provenance | |
|
||||
| windows.cpp:562:10:562:19 | *src_string [*Buffer] | windows.cpp:562:21:562:26 | *Buffer | provenance | |
|
||||
| windows.cpp:562:21:562:26 | *Buffer | windows.cpp:562:10:562:29 | access to array | provenance | |
|
||||
| windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] | windows.cpp:564:10:564:20 | *dest_string [*Buffer] | provenance | |
|
||||
| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | provenance | |
|
||||
| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] | provenance | MaD:26 |
|
||||
| windows.cpp:564:10:564:20 | *dest_string [*Buffer] | windows.cpp:564:10:564:30 | access to array | provenance | |
|
||||
| windows.cpp:564:10:564:20 | *dest_string [*Buffer] | windows.cpp:564:22:564:27 | *Buffer | provenance | |
|
||||
| windows.cpp:564:22:564:27 | *Buffer | windows.cpp:564:10:564:30 | access to array | provenance | |
|
||||
| windows.cpp:568:19:568:29 | RtlMoveMemory output argument | windows.cpp:569:10:569:23 | access to array | provenance | |
|
||||
| windows.cpp:568:32:568:33 | *& ... | windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | provenance | |
|
||||
| windows.cpp:568:32:568:33 | *& ... | windows.cpp:568:19:568:29 | RtlMoveMemory output argument | provenance | MaD:29 |
|
||||
| windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | windows.cpp:574:10:574:23 | access to array | provenance | |
|
||||
| windows.cpp:573:40:573:41 | *& ... | windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | provenance | |
|
||||
| windows.cpp:573:40:573:41 | *& ... | windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | provenance | MaD:30 |
|
||||
nodes
|
||||
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | semmle.label | [summary param] *0 in buffer |
|
||||
| asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | semmle.label | [summary] to write: ReturnValue in buffer |
|
||||
@@ -163,6 +282,38 @@ nodes
|
||||
| test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | semmle.label | call to ymlStepGenerated_with_body |
|
||||
| test.cpp:32:41:32:41 | x | semmle.label | x |
|
||||
| test.cpp:33:10:33:11 | z2 | semmle.label | z2 |
|
||||
| test.cpp:46:30:46:32 | *arg [x] | semmle.label | *arg [x] |
|
||||
| test.cpp:47:12:47:19 | *arg [x] | semmle.label | *arg [x] |
|
||||
| test.cpp:48:13:48:13 | *s [x] | semmle.label | *s [x] |
|
||||
| test.cpp:48:16:48:16 | x | semmle.label | x |
|
||||
| test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | semmle.label | [summary param] *3 in pthread_create [x] |
|
||||
| test.cpp:52:5:52:18 | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] | semmle.label | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] |
|
||||
| test.cpp:56:2:56:2 | *s [post update] [x] | semmle.label | *s [post update] [x] |
|
||||
| test.cpp:56:2:56:18 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:56:8:56:16 | call to ymlSource | semmle.label | call to ymlSource |
|
||||
| test.cpp:59:55:59:64 | *& ... [x] | semmle.label | *& ... [x] |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | semmle.label | [summary param] 1 in callWithArgument |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | semmle.label | [summary param] 1 in callWithArgument |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | semmle.label | [summary param] 1 in callWithArgument |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | semmle.label | [summary param] 1 in callWithArgument |
|
||||
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | semmle.label | [summary] to write: Argument[0].Parameter[0] in callWithArgument |
|
||||
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | semmle.label | [summary] to write: Argument[0].Parameter[0] in callWithArgument |
|
||||
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | semmle.label | [summary] to write: Argument[0].Parameter[0] in callWithArgument |
|
||||
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | semmle.label | [summary] to write: Argument[0].Parameter[0] in callWithArgument |
|
||||
| test.cpp:68:22:68:22 | y | semmle.label | y |
|
||||
| test.cpp:69:11:69:11 | y | semmle.label | y |
|
||||
| test.cpp:74:22:74:22 | y | semmle.label | y |
|
||||
| test.cpp:75:11:75:11 | y | semmle.label | y |
|
||||
| test.cpp:82:22:82:22 | y | semmle.label | y |
|
||||
| test.cpp:83:11:83:11 | y | semmle.label | y |
|
||||
| test.cpp:88:22:88:22 | y | semmle.label | y |
|
||||
| test.cpp:89:11:89:11 | y | semmle.label | y |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||
| test.cpp:97:26:97:26 | x | semmle.label | x |
|
||||
| test.cpp:101:26:101:26 | x | semmle.label | x |
|
||||
| test.cpp:103:63:103:63 | x | semmle.label | x |
|
||||
| test.cpp:104:62:104:62 | x | semmle.label | x |
|
||||
| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | semmle.label | [summary param] *0 in CommandLineToArgvA |
|
||||
| windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | semmle.label | [summary] to write: ReturnValue[**] in CommandLineToArgvA |
|
||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | semmle.label | *call to GetCommandLineA |
|
||||
@@ -238,6 +389,83 @@ nodes
|
||||
| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | semmle.label | *call to MapViewOfFileNuma2 |
|
||||
| windows.cpp:333:20:333:52 | *pMapView | semmle.label | *pMapView |
|
||||
| windows.cpp:335:10:335:16 | * ... | semmle.label | * ... |
|
||||
| windows.cpp:349:8:349:19 | [summary param] *3 in CreateThread [x] | semmle.label | [summary param] *3 in CreateThread [x] |
|
||||
| windows.cpp:349:8:349:19 | [summary] to write: Argument[2].Parameter[*0] in CreateThread [x] | semmle.label | [summary] to write: Argument[2].Parameter[*0] in CreateThread [x] |
|
||||
| windows.cpp:357:8:357:25 | [summary param] *4 in CreateRemoteThread [x] | semmle.label | [summary param] *4 in CreateRemoteThread [x] |
|
||||
| windows.cpp:357:8:357:25 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThread [x] | semmle.label | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThread [x] |
|
||||
| windows.cpp:387:8:387:27 | [summary param] *4 in CreateRemoteThreadEx [x] | semmle.label | [summary param] *4 in CreateRemoteThreadEx [x] |
|
||||
| windows.cpp:387:8:387:27 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThreadEx [x] | semmle.label | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThreadEx [x] |
|
||||
| windows.cpp:403:26:403:36 | *lpParameter [x] | semmle.label | *lpParameter [x] |
|
||||
| windows.cpp:405:10:405:25 | *lpParameter [x] | semmle.label | *lpParameter [x] |
|
||||
| windows.cpp:406:8:406:8 | *s [x] | semmle.label | *s [x] |
|
||||
| windows.cpp:406:8:406:11 | x | semmle.label | x |
|
||||
| windows.cpp:410:26:410:36 | *lpParameter [x] | semmle.label | *lpParameter [x] |
|
||||
| windows.cpp:412:10:412:25 | *lpParameter [x] | semmle.label | *lpParameter [x] |
|
||||
| windows.cpp:413:8:413:8 | *s [x] | semmle.label | *s [x] |
|
||||
| windows.cpp:413:8:413:11 | x | semmle.label | x |
|
||||
| windows.cpp:417:26:417:36 | *lpParameter [x] | semmle.label | *lpParameter [x] |
|
||||
| windows.cpp:419:10:419:25 | *lpParameter [x] | semmle.label | *lpParameter [x] |
|
||||
| windows.cpp:420:8:420:8 | *s [x] | semmle.label | *s [x] |
|
||||
| windows.cpp:420:8:420:11 | x | semmle.label | x |
|
||||
| windows.cpp:431:3:431:3 | *s [post update] [x] | semmle.label | *s [post update] [x] |
|
||||
| windows.cpp:431:3:431:16 | ... = ... | semmle.label | ... = ... |
|
||||
| windows.cpp:431:9:431:14 | call to source | semmle.label | call to source |
|
||||
| windows.cpp:439:7:439:8 | *& ... [x] | semmle.label | *& ... [x] |
|
||||
| windows.cpp:451:7:451:8 | *& ... [x] | semmle.label | *& ... [x] |
|
||||
| windows.cpp:464:7:464:8 | *& ... [x] | semmle.label | *& ... [x] |
|
||||
| windows.cpp:473:17:473:37 | [summary param] *0 in RtlCopyVolatileMemory [Return] | semmle.label | [summary param] *0 in RtlCopyVolatileMemory [Return] |
|
||||
| windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | semmle.label | [summary param] *1 in RtlCopyVolatileMemory |
|
||||
| windows.cpp:479:17:479:35 | [summary param] *0 in RtlCopyDeviceMemory [Return] | semmle.label | [summary param] *0 in RtlCopyDeviceMemory [Return] |
|
||||
| windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | semmle.label | [summary param] *1 in RtlCopyDeviceMemory |
|
||||
| windows.cpp:485:6:485:18 | [summary param] *0 in RtlCopyMemory [Return] | semmle.label | [summary param] *0 in RtlCopyMemory [Return] |
|
||||
| windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | semmle.label | [summary param] *1 in RtlCopyMemory |
|
||||
| windows.cpp:493:6:493:29 | [summary param] *0 in RtlCopyMemoryNonTemporal [Return] | semmle.label | [summary param] *0 in RtlCopyMemoryNonTemporal [Return] |
|
||||
| windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | semmle.label | [summary param] *1 in RtlCopyMemoryNonTemporal |
|
||||
| windows.cpp:510:6:510:25 | [summary param] *0 in RtlCopyUnicodeString [Return] [*Buffer] | semmle.label | [summary param] *0 in RtlCopyUnicodeString [Return] [*Buffer] |
|
||||
| windows.cpp:510:6:510:25 | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | semmle.label | [summary param] *1 in RtlCopyUnicodeString [*Buffer] |
|
||||
| windows.cpp:510:6:510:25 | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString | semmle.label | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString |
|
||||
| windows.cpp:510:6:510:25 | [summary] to write: Argument[*0] in RtlCopyUnicodeString [*Buffer] | semmle.label | [summary] to write: Argument[*0] in RtlCopyUnicodeString [*Buffer] |
|
||||
| windows.cpp:510:6:510:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString | semmle.label | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString |
|
||||
| windows.cpp:515:6:515:18 | [summary param] *0 in RtlMoveMemory [Return] | semmle.label | [summary param] *0 in RtlMoveMemory [Return] |
|
||||
| windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | semmle.label | [summary param] *1 in RtlMoveMemory |
|
||||
| windows.cpp:521:17:521:37 | [summary param] *0 in RtlMoveVolatileMemory [Return] | semmle.label | [summary param] *0 in RtlMoveVolatileMemory [Return] |
|
||||
| windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | semmle.label | [summary param] *1 in RtlMoveVolatileMemory |
|
||||
| windows.cpp:527:6:527:25 | [summary param] *0 in RtlInitUnicodeString [Return] [*Buffer] | semmle.label | [summary param] *0 in RtlInitUnicodeString [Return] [*Buffer] |
|
||||
| windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | semmle.label | [summary param] *1 in RtlInitUnicodeString |
|
||||
| windows.cpp:527:6:527:25 | [summary] to write: Argument[*0] in RtlInitUnicodeString [*Buffer] | semmle.label | [summary] to write: Argument[*0] in RtlInitUnicodeString [*Buffer] |
|
||||
| windows.cpp:527:6:527:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString | semmle.label | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString |
|
||||
| windows.cpp:533:11:533:16 | call to source | semmle.label | call to source |
|
||||
| windows.cpp:533:11:533:16 | call to source | semmle.label | call to source |
|
||||
| windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | semmle.label | RtlCopyVolatileMemory output argument |
|
||||
| windows.cpp:537:40:537:41 | *& ... | semmle.label | *& ... |
|
||||
| windows.cpp:538:10:538:23 | access to array | semmle.label | access to array |
|
||||
| windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | semmle.label | RtlCopyDeviceMemory output argument |
|
||||
| windows.cpp:542:38:542:39 | *& ... | semmle.label | *& ... |
|
||||
| windows.cpp:543:10:543:23 | access to array | semmle.label | access to array |
|
||||
| windows.cpp:547:19:547:29 | RtlCopyMemory output argument | semmle.label | RtlCopyMemory output argument |
|
||||
| windows.cpp:547:32:547:33 | *& ... | semmle.label | *& ... |
|
||||
| windows.cpp:548:10:548:23 | access to array | semmle.label | access to array |
|
||||
| windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument | semmle.label | RtlCopyMemoryNonTemporal output argument |
|
||||
| windows.cpp:552:43:552:44 | *& ... | semmle.label | *& ... |
|
||||
| windows.cpp:553:10:553:23 | access to array | semmle.label | access to array |
|
||||
| windows.cpp:559:5:559:24 | ... = ... | semmle.label | ... = ... |
|
||||
| windows.cpp:559:17:559:24 | call to source | semmle.label | call to source |
|
||||
| windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | semmle.label | RtlInitUnicodeString output argument [*Buffer] |
|
||||
| windows.cpp:561:39:561:44 | *buffer | semmle.label | *buffer |
|
||||
| windows.cpp:562:10:562:19 | *src_string [*Buffer] | semmle.label | *src_string [*Buffer] |
|
||||
| windows.cpp:562:10:562:29 | access to array | semmle.label | access to array |
|
||||
| windows.cpp:562:21:562:26 | *Buffer | semmle.label | *Buffer |
|
||||
| windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] | semmle.label | RtlCopyUnicodeString output argument [*Buffer] |
|
||||
| windows.cpp:563:40:563:50 | *& ... [*Buffer] | semmle.label | *& ... [*Buffer] |
|
||||
| windows.cpp:564:10:564:20 | *dest_string [*Buffer] | semmle.label | *dest_string [*Buffer] |
|
||||
| windows.cpp:564:10:564:30 | access to array | semmle.label | access to array |
|
||||
| windows.cpp:564:22:564:27 | *Buffer | semmle.label | *Buffer |
|
||||
| windows.cpp:568:19:568:29 | RtlMoveMemory output argument | semmle.label | RtlMoveMemory output argument |
|
||||
| windows.cpp:568:32:568:33 | *& ... | semmle.label | *& ... |
|
||||
| windows.cpp:569:10:569:23 | access to array | semmle.label | access to array |
|
||||
| windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | semmle.label | RtlMoveVolatileMemory output argument |
|
||||
| windows.cpp:573:40:573:41 | *& ... | semmle.label | *& ... |
|
||||
| windows.cpp:574:10:574:23 | access to array | semmle.label | access to array |
|
||||
subpaths
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | asio_streams.cpp:100:44:100:62 | call to buffer |
|
||||
| test.cpp:17:24:17:24 | x | test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | test.cpp:17:10:17:22 | call to ymlStepManual |
|
||||
@@ -245,4 +473,12 @@ subpaths
|
||||
| test.cpp:25:35:25:35 | x | test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | test.cpp:25:11:25:33 | call to ymlStepManual_with_body |
|
||||
| test.cpp:32:41:32:41 | x | test.cpp:7:47:7:52 | value2 | test.cpp:7:5:7:30 | *ymlStepGenerated_with_body | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body |
|
||||
| windows.cpp:27:36:27:38 | *cmd | windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA |
|
||||
| windows.cpp:537:40:537:41 | *& ... | windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | windows.cpp:473:17:473:37 | [summary param] *0 in RtlCopyVolatileMemory [Return] | windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument |
|
||||
| windows.cpp:542:38:542:39 | *& ... | windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | windows.cpp:479:17:479:35 | [summary param] *0 in RtlCopyDeviceMemory [Return] | windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument |
|
||||
| windows.cpp:547:32:547:33 | *& ... | windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | windows.cpp:485:6:485:18 | [summary param] *0 in RtlCopyMemory [Return] | windows.cpp:547:19:547:29 | RtlCopyMemory output argument |
|
||||
| windows.cpp:552:43:552:44 | *& ... | windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | windows.cpp:493:6:493:29 | [summary param] *0 in RtlCopyMemoryNonTemporal [Return] | windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument |
|
||||
| windows.cpp:561:39:561:44 | *buffer | windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | windows.cpp:527:6:527:25 | [summary param] *0 in RtlInitUnicodeString [Return] [*Buffer] | windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] |
|
||||
| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *0 in RtlCopyUnicodeString [Return] [*Buffer] | windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] |
|
||||
| windows.cpp:568:32:568:33 | *& ... | windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | windows.cpp:515:6:515:18 | [summary param] *0 in RtlMoveMemory [Return] | windows.cpp:568:19:568:29 | RtlMoveMemory output argument |
|
||||
| windows.cpp:573:40:573:41 | *& ... | windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | windows.cpp:521:17:521:37 | [summary param] *0 in RtlMoveVolatileMemory [Return] | windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument |
|
||||
testFailures
|
||||
|
||||
@@ -16,4 +16,5 @@ extensions:
|
||||
- ["", "", False, "ymlStepManual", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["", "", False, "ymlStepGenerated", "", "", "Argument[0]", "ReturnValue", "taint", "df-generated"]
|
||||
- ["", "", False, "ymlStepManual_with_body", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["", "", False, "ymlStepGenerated_with_body", "", "", "Argument[0]", "ReturnValue", "taint", "df-generated"]
|
||||
- ["", "", False, "ymlStepGenerated_with_body", "", "", "Argument[0]", "ReturnValue", "taint", "df-generated"]
|
||||
- ["", "", False, "callWithArgument", "", "", "Argument[1]", "Argument[0].Parameter[0]", "value", "manual"]
|
||||
@@ -8,3 +8,8 @@
|
||||
| test.cpp:29:10:29:11 | y3 | test-sink |
|
||||
| test.cpp:33:10:33:11 | z2 | test-sink |
|
||||
| test.cpp:36:10:36:11 | z3 | test-sink |
|
||||
| test.cpp:48:16:48:16 | x | test-sink |
|
||||
| test.cpp:69:11:69:11 | y | test-sink |
|
||||
| test.cpp:75:11:75:11 | y | test-sink |
|
||||
| test.cpp:83:11:83:11 | y | test-sink |
|
||||
| test.cpp:89:11:89:11 | y | test-sink |
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | remote |
|
||||
| test.cpp:10:10:10:18 | call to ymlSource | local |
|
||||
| test.cpp:56:8:56:16 | call to ymlSource | local |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | local |
|
||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | local |
|
||||
| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | local |
|
||||
| windows.cpp:39:36:39:38 | GetEnvironmentVariableA output argument | local |
|
||||
|
||||
@@ -35,3 +35,71 @@ void test() {
|
||||
int z3 = ymlStepGenerated_with_body(x, 0);
|
||||
ymlSink(z3); // clean
|
||||
}
|
||||
|
||||
struct S {
|
||||
int x;
|
||||
};
|
||||
|
||||
using pthread_t = unsigned long;
|
||||
using pthread_attr_t = void*;
|
||||
|
||||
void *myThreadFunction(void *arg) {
|
||||
S* s = (S *)arg;
|
||||
ymlSink(s->x); // $ ir
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int pthread_create(pthread_t *thread, const pthread_attr_t * attr, void *(*start_routine)(void*), void *arg);
|
||||
|
||||
int test_pthread_create() {
|
||||
S s;
|
||||
s.x = ymlSource();
|
||||
|
||||
pthread_t threadId;
|
||||
pthread_create(&threadId, nullptr, myThreadFunction, (void *)&s);
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
void callWithArgument(F f, int x);
|
||||
|
||||
struct StructWithOperatorCall_has_constructor {
|
||||
StructWithOperatorCall_has_constructor();
|
||||
|
||||
void operator()(int y) {
|
||||
ymlSink(y); // $ ir
|
||||
}
|
||||
};
|
||||
|
||||
struct StructWithOperatorCall_no_constructor {
|
||||
void operator()(int y) {
|
||||
ymlSink(y); // $ ir
|
||||
}
|
||||
};
|
||||
|
||||
struct StructWithOperatorCall_has_constructor_2 {
|
||||
StructWithOperatorCall_has_constructor_2();
|
||||
|
||||
void operator()(int y) {
|
||||
ymlSink(y); // $ ir
|
||||
}
|
||||
};
|
||||
|
||||
struct StructWithOperatorCall_no_constructor_2 {
|
||||
void operator()(int y) {
|
||||
ymlSink(y); // $ ir
|
||||
}
|
||||
};
|
||||
|
||||
void test_callWithArgument() {
|
||||
int x = ymlSource();
|
||||
{
|
||||
StructWithOperatorCall_has_constructor func;
|
||||
callWithArgument(func, x);
|
||||
}
|
||||
{
|
||||
StructWithOperatorCall_no_constructor func;
|
||||
callWithArgument(func, x);
|
||||
}
|
||||
callWithArgument(StructWithOperatorCall_has_constructor_2(), x);
|
||||
callWithArgument(StructWithOperatorCall_no_constructor_2(), x);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -335,3 +335,242 @@ void mapViewOfFile(HANDLE hMapFile) {
|
||||
sink(*buffer); // $ ir
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct _SECURITY_ATTRIBUTES
|
||||
{
|
||||
DWORD nLength;
|
||||
LPVOID lpSecurityDescriptor;
|
||||
BOOL bInheritHandle;
|
||||
} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
|
||||
|
||||
typedef DWORD (*LPTHREAD_START_ROUTINE)(
|
||||
LPVOID lpThreadParameter);
|
||||
|
||||
HANDLE CreateThread(
|
||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
SIZE_T dwStackSize,
|
||||
LPTHREAD_START_ROUTINE lpStartAddress,
|
||||
LPVOID lpParameter,
|
||||
DWORD dwCreationFlags,
|
||||
LPDWORD lpThreadId);
|
||||
|
||||
HANDLE CreateRemoteThread(
|
||||
HANDLE hProcess,
|
||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
SIZE_T dwStackSize,
|
||||
LPTHREAD_START_ROUTINE lpStartAddress,
|
||||
LPVOID lpParameter,
|
||||
DWORD dwCreationFlags,
|
||||
LPDWORD lpThreadId
|
||||
);
|
||||
|
||||
typedef ULONG_PTR DWORD_PTR;
|
||||
|
||||
typedef struct _PROC_THREAD_ATTRIBUTE_ENTRY
|
||||
{
|
||||
DWORD_PTR Attribute;
|
||||
SIZE_T cbSize;
|
||||
PVOID lpValue;
|
||||
} PROC_THREAD_ATTRIBUTE_ENTRY, *LPPROC_THREAD_ATTRIBUTE_ENTRY;
|
||||
|
||||
// This structure contains a list of attributes that have been added using UpdateProcThreadAttribute
|
||||
typedef struct _PROC_THREAD_ATTRIBUTE_LIST
|
||||
{
|
||||
DWORD dwFlags;
|
||||
ULONG Size;
|
||||
ULONG Count;
|
||||
ULONG Reserved;
|
||||
PULONG Unknown;
|
||||
PROC_THREAD_ATTRIBUTE_ENTRY Entries[1];
|
||||
} PROC_THREAD_ATTRIBUTE_LIST, *LPPROC_THREAD_ATTRIBUTE_LIST;
|
||||
|
||||
HANDLE CreateRemoteThreadEx(
|
||||
HANDLE hProcess,
|
||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
SIZE_T dwStackSize,
|
||||
LPTHREAD_START_ROUTINE lpStartAddress,
|
||||
LPVOID lpParameter,
|
||||
DWORD dwCreationFlags,
|
||||
LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList,
|
||||
LPDWORD lpThreadId
|
||||
);
|
||||
|
||||
struct S
|
||||
{
|
||||
int x;
|
||||
};
|
||||
|
||||
DWORD ThreadProc1(LPVOID lpParameter)
|
||||
{
|
||||
S *s = (S *)lpParameter;
|
||||
sink(s->x); // $ ir
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD ThreadProc2(LPVOID lpParameter)
|
||||
{
|
||||
S *s = (S *)lpParameter;
|
||||
sink(s->x); // $ ir
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD ThreadProc3(LPVOID lpParameter)
|
||||
{
|
||||
S *s = (S *)lpParameter;
|
||||
sink(s->x); // $ ir
|
||||
return 0;
|
||||
}
|
||||
|
||||
int source();
|
||||
|
||||
void test_create_thread()
|
||||
{
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
|
||||
S s;
|
||||
s.x = source();
|
||||
|
||||
{
|
||||
DWORD threadId;
|
||||
HANDLE threadHandle = CreateThread(
|
||||
&sa,
|
||||
0,
|
||||
ThreadProc1,
|
||||
&s,
|
||||
0,
|
||||
&threadId);
|
||||
}
|
||||
|
||||
{
|
||||
DWORD threadId;
|
||||
HANDLE threadHandle = CreateRemoteThread(
|
||||
nullptr,
|
||||
&sa,
|
||||
0,
|
||||
ThreadProc2,
|
||||
&s,
|
||||
0,
|
||||
&threadId);
|
||||
}
|
||||
|
||||
{
|
||||
DWORD threadId;
|
||||
PROC_THREAD_ATTRIBUTE_LIST attrList;
|
||||
HANDLE threadHandle = CreateRemoteThreadEx(
|
||||
nullptr,
|
||||
&sa,
|
||||
0,
|
||||
ThreadProc3,
|
||||
&s,
|
||||
0,
|
||||
&attrList,
|
||||
&threadId);
|
||||
}
|
||||
}
|
||||
|
||||
using size_t = decltype(sizeof(0));
|
||||
|
||||
volatile void * RtlCopyVolatileMemory(
|
||||
volatile void *Destination,
|
||||
volatile const void *Source,
|
||||
size_t Length
|
||||
);
|
||||
|
||||
volatile void * RtlCopyDeviceMemory(
|
||||
volatile void *Destination,
|
||||
volatile const void *Source,
|
||||
size_t Length
|
||||
);
|
||||
|
||||
void RtlCopyMemory(
|
||||
void* Destination,
|
||||
const void* Source,
|
||||
size_t Length
|
||||
);
|
||||
|
||||
using VOID = void;
|
||||
|
||||
VOID RtlCopyMemoryNonTemporal(
|
||||
VOID *Destination,
|
||||
const VOID *Source,
|
||||
SIZE_T Length
|
||||
);
|
||||
|
||||
using USHORT = unsigned short;
|
||||
using PWSTR = wchar_t*;
|
||||
using PCWSTR = const wchar_t*;
|
||||
using PCUNICODE_STRING = const struct _UNICODE_STRING*;
|
||||
|
||||
typedef struct _UNICODE_STRING {
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
PWSTR Buffer;
|
||||
} UNICODE_STRING, *PUNICODE_STRING;
|
||||
|
||||
VOID RtlCopyUnicodeString(
|
||||
PUNICODE_STRING DestinationString,
|
||||
PCUNICODE_STRING SourceString
|
||||
);
|
||||
|
||||
void RtlMoveMemory(
|
||||
void* Destination,
|
||||
const void* Source,
|
||||
size_t Length
|
||||
);
|
||||
|
||||
volatile void * RtlMoveVolatileMemory(
|
||||
volatile void *Destination,
|
||||
volatile const void *Source,
|
||||
size_t Length
|
||||
);
|
||||
|
||||
void RtlInitUnicodeString(
|
||||
PUNICODE_STRING DestinationString,
|
||||
PCWSTR SourceString
|
||||
);
|
||||
|
||||
void test_copy_and_move_memory() {
|
||||
int x = source();
|
||||
|
||||
{
|
||||
char dest_buffer[1024];
|
||||
RtlCopyVolatileMemory(dest_buffer, &x, sizeof(x));
|
||||
sink(dest_buffer[0]); // $ ir
|
||||
}
|
||||
{
|
||||
char dest_buffer[1024];
|
||||
RtlCopyDeviceMemory(dest_buffer, &x, sizeof(x));
|
||||
sink(dest_buffer[0]); // $ ir
|
||||
}
|
||||
{
|
||||
char dest_buffer[1024];
|
||||
RtlCopyMemory(dest_buffer, &x, sizeof(x));
|
||||
sink(dest_buffer[0]); // $ ir
|
||||
}
|
||||
{
|
||||
char dest_buffer[1024];
|
||||
RtlCopyMemoryNonTemporal(dest_buffer, &x, sizeof(x));
|
||||
sink(dest_buffer[0]); // $ ir
|
||||
}
|
||||
{
|
||||
UNICODE_STRING dest_string;
|
||||
UNICODE_STRING src_string;
|
||||
wchar_t buffer[1024];
|
||||
buffer[0] = source();
|
||||
|
||||
RtlInitUnicodeString(&src_string, buffer);
|
||||
sink(src_string.Buffer[0]); // $ ir
|
||||
RtlCopyUnicodeString(&dest_string, &src_string);
|
||||
sink(dest_string.Buffer[0]); // $ ir
|
||||
}
|
||||
{
|
||||
char dest_buffer[1024];
|
||||
RtlMoveMemory(dest_buffer, &x, sizeof(x));
|
||||
sink(dest_buffer[0]); // $ ir
|
||||
}
|
||||
{
|
||||
volatile char dest_buffer[1024];
|
||||
RtlMoveVolatileMemory(dest_buffer, &x, sizeof(x));
|
||||
sink(dest_buffer[0]); // $ ir
|
||||
}
|
||||
}
|
||||
@@ -7767,6 +7767,34 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future
|
||||
| taint.cpp:830:20:830:34 | call to indirect_source | taint.cpp:832:23:832:24 | in | |
|
||||
| taint.cpp:831:15:831:17 | out | taint.cpp:832:18:832:20 | out | |
|
||||
| taint.cpp:831:15:831:17 | out | taint.cpp:833:8:833:10 | out | |
|
||||
| thread.cpp:10:27:10:27 | s | thread.cpp:10:27:10:27 | s | |
|
||||
| thread.cpp:10:27:10:27 | s | thread.cpp:11:8:11:8 | s | |
|
||||
| thread.cpp:14:26:14:26 | s | thread.cpp:15:8:15:8 | s | |
|
||||
| thread.cpp:18:27:18:27 | s | thread.cpp:18:27:18:27 | s | |
|
||||
| thread.cpp:18:27:18:27 | s | thread.cpp:19:8:19:8 | s | |
|
||||
| thread.cpp:18:34:18:34 | y | thread.cpp:20:8:20:8 | y | |
|
||||
| thread.cpp:24:5:24:5 | s | thread.cpp:25:3:25:3 | s | |
|
||||
| thread.cpp:24:5:24:5 | s | thread.cpp:26:38:26:38 | s | |
|
||||
| thread.cpp:24:5:24:5 | s | thread.cpp:27:37:27:37 | s | |
|
||||
| thread.cpp:24:5:24:5 | s | thread.cpp:28:38:28:38 | s | |
|
||||
| thread.cpp:24:5:24:5 | s | thread.cpp:32:7:32:7 | s | |
|
||||
| thread.cpp:25:3:25:3 | s [post update] | thread.cpp:26:38:26:38 | s | |
|
||||
| thread.cpp:25:3:25:3 | s [post update] | thread.cpp:27:37:27:37 | s | |
|
||||
| thread.cpp:25:3:25:3 | s [post update] | thread.cpp:28:38:28:38 | s | |
|
||||
| thread.cpp:25:3:25:3 | s [post update] | thread.cpp:32:7:32:7 | s | |
|
||||
| thread.cpp:25:3:25:16 | ... = ... | thread.cpp:25:5:25:5 | x [post update] | |
|
||||
| thread.cpp:25:9:25:14 | call to source | thread.cpp:25:3:25:16 | ... = ... | |
|
||||
| thread.cpp:26:18:26:39 | call to thread | thread.cpp:33:1:33:1 | t1 | |
|
||||
| thread.cpp:26:38:26:38 | s | thread.cpp:26:37:26:38 | & ... | |
|
||||
| thread.cpp:27:18:27:38 | call to thread | thread.cpp:33:1:33:1 | t2 | |
|
||||
| thread.cpp:27:37:27:37 | ref arg s | thread.cpp:28:38:28:38 | s | |
|
||||
| thread.cpp:27:37:27:37 | ref arg s | thread.cpp:32:7:32:7 | s | |
|
||||
| thread.cpp:28:18:28:43 | call to thread | thread.cpp:33:1:33:1 | t3 | |
|
||||
| thread.cpp:28:38:28:38 | s | thread.cpp:28:37:28:38 | & ... | |
|
||||
| thread.cpp:30:18:32:8 | call to thread | thread.cpp:33:1:33:1 | t4 | |
|
||||
| thread.cpp:30:24:30:24 | p | thread.cpp:30:24:30:24 | p | |
|
||||
| thread.cpp:30:24:30:24 | p | thread.cpp:31:10:31:10 | p | |
|
||||
| thread.cpp:32:7:32:7 | s | thread.cpp:32:6:32:7 | & ... | |
|
||||
| vector.cpp:16:43:16:49 | source1 | vector.cpp:17:26:17:32 | source1 | |
|
||||
| vector.cpp:16:43:16:49 | source1 | vector.cpp:31:38:31:44 | source1 | |
|
||||
| vector.cpp:17:21:17:33 | call to vector | vector.cpp:19:14:19:14 | v | |
|
||||
|
||||
@@ -681,4 +681,17 @@ namespace std {
|
||||
// the model for `format`.
|
||||
template <typename... Args>
|
||||
int same_signature_as_format_but_different_name(format_string, Args &&...args);
|
||||
}
|
||||
|
||||
namespace std {
|
||||
class thread {
|
||||
public:
|
||||
template<class F, class... Args>
|
||||
explicit thread(F&&, Args&&...);
|
||||
|
||||
~thread();
|
||||
|
||||
void join();
|
||||
void detach();
|
||||
};
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
33
cpp/ql/test/library-tests/dataflow/taint-tests/thread.cpp
Normal file
33
cpp/ql/test/library-tests/dataflow/taint-tests/thread.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#include "stl.h"
|
||||
|
||||
int source();
|
||||
void sink(int);
|
||||
|
||||
struct S {
|
||||
int x;
|
||||
};
|
||||
|
||||
void thread_function_1(S* s) {
|
||||
sink(s->x); // $ ir
|
||||
}
|
||||
|
||||
void thread_function_2(S s) {
|
||||
sink(s.x); // $ ir
|
||||
}
|
||||
|
||||
void thread_function_3(S* s, int y) {
|
||||
sink(s->x); // $ ir
|
||||
sink(y); // clean
|
||||
}
|
||||
|
||||
void test_thread() {
|
||||
S s;
|
||||
s.x = source();
|
||||
std::thread t1(thread_function_1, &s);
|
||||
std::thread t2(thread_function_2, s);
|
||||
std::thread t3(thread_function_3, &s, 42);
|
||||
|
||||
std::thread t4([](S* p) {
|
||||
sink(p->x); // $ ir
|
||||
}, &s);
|
||||
}
|
||||
@@ -24262,6 +24262,281 @@ ir.cpp:
|
||||
# 2725| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 2725| Type = [PlainCharType] char
|
||||
# 2725| ValueCategory = prvalue(load)
|
||||
# 2728| [TopLevelFunction] void test_postfix_crement(int*, int)
|
||||
# 2728| <params>:
|
||||
# 2728| getParameter(0): [Parameter] p
|
||||
# 2728| Type = [IntPointerType] int *
|
||||
# 2728| getParameter(1): [Parameter] q
|
||||
# 2728| Type = [IntType] int
|
||||
# 2728| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2729| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 2729| getExpr(): [PostfixIncrExpr] ... ++
|
||||
# 2729| Type = [IntPointerType] int *
|
||||
# 2729| ValueCategory = prvalue
|
||||
# 2729| getOperand(): [VariableAccess] p
|
||||
# 2729| Type = [IntPointerType] int *
|
||||
# 2729| ValueCategory = lvalue
|
||||
# 2730| getStmt(1): [ExprStmt] ExprStmt
|
||||
# 2730| getExpr(): [PostfixIncrExpr] ... ++
|
||||
# 2730| Type = [IntType] int
|
||||
# 2730| ValueCategory = prvalue
|
||||
# 2730| getOperand(): [VariableAccess] q
|
||||
# 2730| Type = [IntType] int
|
||||
# 2730| ValueCategory = lvalue
|
||||
# 2731| getStmt(2): [ExprStmt] ExprStmt
|
||||
# 2731| getExpr(): [PostfixIncrExpr] ... ++
|
||||
# 2731| Type = [IntPointerType] int *
|
||||
# 2731| ValueCategory = prvalue
|
||||
# 2731| getOperand(): [VariableAccess] p
|
||||
# 2731| Type = [IntPointerType] int *
|
||||
# 2731| ValueCategory = lvalue
|
||||
# 2731| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2731| Type = [IntPointerType] int *
|
||||
# 2731| ValueCategory = prvalue
|
||||
# 2732| getStmt(3): [ExprStmt] ExprStmt
|
||||
# 2732| getExpr(): [PostfixIncrExpr] ... ++
|
||||
# 2732| Type = [IntType] int
|
||||
# 2732| ValueCategory = prvalue
|
||||
# 2732| getOperand(): [VariableAccess] q
|
||||
# 2732| Type = [IntType] int
|
||||
# 2732| ValueCategory = lvalue
|
||||
# 2732| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2732| Type = [IntType] int
|
||||
# 2732| ValueCategory = prvalue
|
||||
# 2733| getStmt(4): [ExprStmt] ExprStmt
|
||||
# 2733| getExpr(): [PostfixIncrExpr] ... ++
|
||||
# 2733| Type = [IntPointerType] int *
|
||||
# 2733| ValueCategory = prvalue
|
||||
# 2733| getOperand(): [VariableAccess] p
|
||||
# 2733| Type = [IntPointerType] int *
|
||||
# 2733| ValueCategory = lvalue
|
||||
# 2733| getExpr().getFullyConverted(): [CStyleCast] (void)...
|
||||
# 2733| Conversion = [VoidConversion] conversion to void
|
||||
# 2733| Type = [VoidType] void
|
||||
# 2733| ValueCategory = prvalue
|
||||
# 2733| getExpr(): [ParenthesisExpr] (...)
|
||||
# 2733| Type = [IntPointerType] int *
|
||||
# 2733| ValueCategory = prvalue
|
||||
# 2734| getStmt(5): [ExprStmt] ExprStmt
|
||||
# 2734| getExpr(): [PostfixIncrExpr] ... ++
|
||||
# 2734| Type = [IntType] int
|
||||
# 2734| ValueCategory = prvalue
|
||||
# 2734| getOperand(): [VariableAccess] q
|
||||
# 2734| Type = [IntType] int
|
||||
# 2734| ValueCategory = lvalue
|
||||
# 2734| getExpr().getFullyConverted(): [CStyleCast] (void)...
|
||||
# 2734| Conversion = [VoidConversion] conversion to void
|
||||
# 2734| Type = [VoidType] void
|
||||
# 2734| ValueCategory = prvalue
|
||||
# 2734| getExpr(): [ParenthesisExpr] (...)
|
||||
# 2734| Type = [IntType] int
|
||||
# 2734| ValueCategory = prvalue
|
||||
# 2735| getStmt(6): [ExprStmt] ExprStmt
|
||||
# 2735| getExpr(): [PostfixIncrExpr] ... ++
|
||||
# 2735| Type = [IntPointerType] int *
|
||||
# 2735| ValueCategory = prvalue
|
||||
# 2735| getOperand(): [VariableAccess] p
|
||||
# 2735| Type = [IntPointerType] int *
|
||||
# 2735| ValueCategory = lvalue
|
||||
# 2735| getExpr().getFullyConverted(): [CStyleCast] (void)...
|
||||
# 2735| Conversion = [VoidConversion] conversion to void
|
||||
# 2735| Type = [VoidType] void
|
||||
# 2735| ValueCategory = prvalue
|
||||
# 2736| getStmt(7): [ExprStmt] ExprStmt
|
||||
# 2736| getExpr(): [PostfixIncrExpr] ... ++
|
||||
# 2736| Type = [IntType] int
|
||||
# 2736| ValueCategory = prvalue
|
||||
# 2736| getOperand(): [VariableAccess] q
|
||||
# 2736| Type = [IntType] int
|
||||
# 2736| ValueCategory = lvalue
|
||||
# 2736| getExpr().getFullyConverted(): [CStyleCast] (void)...
|
||||
# 2736| Conversion = [VoidConversion] conversion to void
|
||||
# 2736| Type = [VoidType] void
|
||||
# 2736| ValueCategory = prvalue
|
||||
# 2737| getStmt(8): [DeclStmt] declaration
|
||||
# 2737| getDeclarationEntry(0): [VariableDeclarationEntry] definition of p1
|
||||
# 2737| Type = [IntPointerType] int *
|
||||
# 2737| getVariable().getInitializer(): [Initializer] initializer for p1
|
||||
# 2737| getExpr(): [PostfixIncrExpr] ... ++
|
||||
# 2737| Type = [IntPointerType] int *
|
||||
# 2737| ValueCategory = prvalue
|
||||
# 2737| getOperand(): [VariableAccess] p
|
||||
# 2737| Type = [IntPointerType] int *
|
||||
# 2737| ValueCategory = lvalue
|
||||
# 2738| getStmt(9): [DeclStmt] declaration
|
||||
# 2738| getDeclarationEntry(0): [VariableDeclarationEntry] definition of q1
|
||||
# 2738| Type = [IntType] int
|
||||
# 2738| getVariable().getInitializer(): [Initializer] initializer for q1
|
||||
# 2738| getExpr(): [PostfixIncrExpr] ... ++
|
||||
# 2738| Type = [IntType] int
|
||||
# 2738| ValueCategory = prvalue
|
||||
# 2738| getOperand(): [VariableAccess] q
|
||||
# 2738| Type = [IntType] int
|
||||
# 2738| ValueCategory = lvalue
|
||||
# 2739| getStmt(10): [ExprStmt] ExprStmt
|
||||
# 2739| getExpr(): [PostfixIncrExpr] ... ++
|
||||
# 2739| Type = [IntPointerType] int *
|
||||
# 2739| ValueCategory = prvalue
|
||||
# 2739| getOperand(): [VariableAccess] p
|
||||
# 2739| Type = [IntPointerType] int *
|
||||
# 2739| ValueCategory = lvalue
|
||||
# 2739| getExpr().getFullyConverted(): [CStyleCast] (int *)...
|
||||
# 2739| Conversion = [PointerConversion] pointer conversion
|
||||
# 2739| Type = [IntPointerType] int *
|
||||
# 2739| ValueCategory = prvalue
|
||||
# 2739| getExpr(): [ParenthesisExpr] (...)
|
||||
# 2739| Type = [IntPointerType] int *
|
||||
# 2739| ValueCategory = prvalue
|
||||
# 2740| getStmt(11): [ExprStmt] ExprStmt
|
||||
# 2740| getExpr(): [PostfixIncrExpr] ... ++
|
||||
# 2740| Type = [IntType] int
|
||||
# 2740| ValueCategory = prvalue
|
||||
# 2740| getOperand(): [VariableAccess] q
|
||||
# 2740| Type = [IntType] int
|
||||
# 2740| ValueCategory = lvalue
|
||||
# 2740| getExpr().getFullyConverted(): [CStyleCast] (int)...
|
||||
# 2740| Conversion = [IntegralConversion] integral conversion
|
||||
# 2740| Type = [IntType] int
|
||||
# 2740| ValueCategory = prvalue
|
||||
# 2740| getExpr(): [ParenthesisExpr] (...)
|
||||
# 2740| Type = [IntType] int
|
||||
# 2740| ValueCategory = prvalue
|
||||
# 2741| getStmt(12): [DeclStmt] declaration
|
||||
# 2741| getDeclarationEntry(0): [VariableDeclarationEntry] definition of p2
|
||||
# 2741| Type = [IntPointerType] int *
|
||||
# 2741| getVariable().getInitializer(): [Initializer] initializer for p2
|
||||
# 2741| getExpr(): [PostfixIncrExpr] ... ++
|
||||
# 2741| Type = [IntPointerType] int *
|
||||
# 2741| ValueCategory = prvalue
|
||||
# 2741| getOperand(): [VariableAccess] p
|
||||
# 2741| Type = [IntPointerType] int *
|
||||
# 2741| ValueCategory = lvalue
|
||||
# 2741| getExpr().getFullyConverted(): [CStyleCast] (int *)...
|
||||
# 2741| Conversion = [PointerConversion] pointer conversion
|
||||
# 2741| Type = [IntPointerType] int *
|
||||
# 2741| ValueCategory = prvalue
|
||||
# 2741| getExpr(): [ParenthesisExpr] (...)
|
||||
# 2741| Type = [IntPointerType] int *
|
||||
# 2741| ValueCategory = prvalue
|
||||
# 2742| getStmt(13): [DeclStmt] declaration
|
||||
# 2742| getDeclarationEntry(0): [VariableDeclarationEntry] definition of q2
|
||||
# 2742| Type = [IntType] int
|
||||
# 2742| getVariable().getInitializer(): [Initializer] initializer for q2
|
||||
# 2742| getExpr(): [PostfixIncrExpr] ... ++
|
||||
# 2742| Type = [IntType] int
|
||||
# 2742| ValueCategory = prvalue
|
||||
# 2742| getOperand(): [VariableAccess] q
|
||||
# 2742| Type = [IntType] int
|
||||
# 2742| ValueCategory = lvalue
|
||||
# 2742| getExpr().getFullyConverted(): [CStyleCast] (int)...
|
||||
# 2742| Conversion = [IntegralConversion] integral conversion
|
||||
# 2742| Type = [IntType] int
|
||||
# 2742| ValueCategory = prvalue
|
||||
# 2742| getExpr(): [ParenthesisExpr] (...)
|
||||
# 2742| Type = [IntType] int
|
||||
# 2742| ValueCategory = prvalue
|
||||
# 2743| getStmt(14): [ReturnStmt] return ...
|
||||
# 2747| [CopyAssignmentOperator] std::strong_ordering& std::strong_ordering::operator=(std::strong_ordering const&)
|
||||
# 2747| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const strong_ordering &
|
||||
# 2747| [MoveAssignmentOperator] std::strong_ordering& std::strong_ordering::operator=(std::strong_ordering&&)
|
||||
# 2747| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] strong_ordering &&
|
||||
# 2747| [CopyConstructor] void std::strong_ordering::strong_ordering(std::strong_ordering const&)
|
||||
# 2747| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const strong_ordering &
|
||||
# 2747| [MoveConstructor] void std::strong_ordering::strong_ordering(std::strong_ordering&&)
|
||||
# 2747| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] strong_ordering &&
|
||||
# 2747| <initializations>:
|
||||
# 2747| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2747| getStmt(0): [ReturnStmt] return ...
|
||||
# 2748| [Constructor] void std::strong_ordering::strong_ordering(std::_Order)
|
||||
# 2748| <params>:
|
||||
# 2748| getParameter(0): [Parameter] v
|
||||
# 2748| Type = [ScopedEnum] _Order
|
||||
# 2748| <initializations>:
|
||||
# 2748| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2748| getStmt(0): [ReturnStmt] return ...
|
||||
# 2763| [CopyAssignmentOperator] ThreeWay& ThreeWay::operator=(ThreeWay const&)
|
||||
# 2763| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const ThreeWay &
|
||||
# 2763| [MoveAssignmentOperator] ThreeWay& ThreeWay::operator=(ThreeWay&&)
|
||||
# 2763| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] ThreeWay &&
|
||||
# 2763| [Constructor] void ThreeWay::ThreeWay()
|
||||
# 2763| <params>:
|
||||
# 2766| [MemberFunction] std::strong_ordering ThreeWay::operator<=>(ThreeWay&)
|
||||
# 2766| <params>:
|
||||
# 2766| getParameter(0): [Parameter] y
|
||||
# 2766| Type = [LValueReferenceType] ThreeWay &
|
||||
# 2766| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2766| getStmt(0): [ReturnStmt] return ...
|
||||
# 2766| getExpr(): [SpaceshipExpr] ... <=> ...
|
||||
# 2766| Type = [Class] strong_ordering
|
||||
# 2766| ValueCategory = prvalue
|
||||
# 2766| getChild(0): [PointerFieldAccess] x
|
||||
# 2766| Type = [IntType] int
|
||||
# 2766| ValueCategory = prvalue(load)
|
||||
# 2766| getQualifier(): [ThisExpr] this
|
||||
# 2766| Type = [PointerType] ThreeWay *
|
||||
# 2766| ValueCategory = prvalue(load)
|
||||
# 2766| getChild(1): [ReferenceFieldAccess] x
|
||||
# 2766| Type = [IntType] int
|
||||
# 2766| ValueCategory = prvalue(load)
|
||||
# 2766| getQualifier(): [VariableAccess] y
|
||||
# 2766| Type = [LValueReferenceType] ThreeWay &
|
||||
# 2766| ValueCategory = prvalue(load)
|
||||
# 2766| getQualifier().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 2766| Type = [Class] ThreeWay
|
||||
# 2766| ValueCategory = lvalue
|
||||
# 2769| [TopLevelFunction] void test_three_way(int, int, ThreeWay, ThreeWay)
|
||||
# 2769| <params>:
|
||||
# 2769| getParameter(0): [Parameter] a
|
||||
# 2769| Type = [IntType] int
|
||||
# 2769| getParameter(1): [Parameter] b
|
||||
# 2769| Type = [IntType] int
|
||||
# 2769| getParameter(2): [Parameter] c
|
||||
# 2769| Type = [Class] ThreeWay
|
||||
# 2769| getParameter(3): [Parameter] d
|
||||
# 2769| Type = [Class] ThreeWay
|
||||
# 2769| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2770| getStmt(0): [DeclStmt] declaration
|
||||
# 2770| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x
|
||||
# 2770| Type = [Class] strong_ordering
|
||||
# 2770| getVariable().getInitializer(): [Initializer] initializer for x
|
||||
# 2770| getExpr(): [SpaceshipExpr] ... <=> ...
|
||||
# 2770| Type = [Class] strong_ordering
|
||||
# 2770| ValueCategory = prvalue
|
||||
# 2770| getChild(0): [VariableAccess] a
|
||||
# 2770| Type = [IntType] int
|
||||
# 2770| ValueCategory = prvalue(load)
|
||||
# 2770| getChild(1): [VariableAccess] b
|
||||
# 2770| Type = [IntType] int
|
||||
# 2770| ValueCategory = prvalue(load)
|
||||
# 2771| getStmt(1): [DeclStmt] declaration
|
||||
# 2771| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y
|
||||
# 2771| Type = [Class] strong_ordering
|
||||
# 2771| getVariable().getInitializer(): [Initializer] initializer for y
|
||||
# 2771| getExpr(): [FunctionCall] call to operator<=>
|
||||
# 2771| Type = [Class] strong_ordering
|
||||
# 2771| ValueCategory = prvalue
|
||||
# 2771| getQualifier(): [VariableAccess] c
|
||||
# 2771| Type = [Class] ThreeWay
|
||||
# 2771| ValueCategory = lvalue
|
||||
# 2771| getArgument(0): [VariableAccess] d
|
||||
# 2771| Type = [Class] ThreeWay
|
||||
# 2771| ValueCategory = lvalue
|
||||
# 2771| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 2771| Type = [LValueReferenceType] ThreeWay &
|
||||
# 2771| ValueCategory = prvalue
|
||||
# 2772| getStmt(2): [ReturnStmt] return ...
|
||||
ir23.cpp:
|
||||
# 1| [TopLevelFunction] bool consteval_1()
|
||||
# 1| <params>:
|
||||
@@ -50000,3 +50275,42 @@ try_except.cpp:
|
||||
# 52| Type = [IntType] int
|
||||
# 52| ValueCategory = prvalue(load)
|
||||
# 54| getStmt(2): [ReturnStmt] return ...
|
||||
type_info_test.cpp:
|
||||
# 3| [TopLevelFunction] void type_info_test(int)
|
||||
# 3| <params>:
|
||||
# 3| getParameter(0): [Parameter] x
|
||||
# 3| Type = [IntType] int
|
||||
# 3| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 4| getStmt(0): [DeclStmt] declaration
|
||||
# 4| getDeclarationEntry(0): [VariableDeclarationEntry] definition of t1
|
||||
# 4| Type = [LValueReferenceType] const type_info &
|
||||
# 4| getVariable().getInitializer(): [Initializer] initializer for t1
|
||||
# 4| getExpr(): [TypeidOperator] typeid ...
|
||||
# 4| Type = [SpecifiedType] const type_info
|
||||
# 4| ValueCategory = lvalue
|
||||
# 4| getExpr(): [VariableAccess] x
|
||||
# 4| Type = [IntType] int
|
||||
# 4| ValueCategory = lvalue
|
||||
# 4| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 4| Type = [LValueReferenceType] const type_info &
|
||||
# 4| ValueCategory = prvalue
|
||||
# 5| getStmt(1): [DeclStmt] declaration
|
||||
# 5| getDeclarationEntry(0): [VariableDeclarationEntry] definition of t2
|
||||
# 5| Type = [LValueReferenceType] const type_info &
|
||||
# 5| getVariable().getInitializer(): [Initializer] initializer for t2
|
||||
# 5| getExpr(): [TypeidOperator] typeid ...
|
||||
# 5| Type = [SpecifiedType] const type_info
|
||||
# 5| ValueCategory = lvalue
|
||||
# 5| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 5| Type = [LValueReferenceType] const type_info &
|
||||
# 5| ValueCategory = prvalue
|
||||
# 6| getStmt(2): [ReturnStmt] return ...
|
||||
typeinfo:
|
||||
# 4| [CopyAssignmentOperator] std::type_info& std::type_info::operator=(std::type_info const&)
|
||||
# 4| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const type_info &
|
||||
# 4| [MoveAssignmentOperator] std::type_info& std::type_info::operator=(std::type_info&&)
|
||||
# 4| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] type_info &&
|
||||
|
||||
@@ -20156,6 +20156,236 @@ ir.cpp:
|
||||
# 2724| v2724_12(void) = AliasedUse : ~m2725_8
|
||||
# 2724| v2724_13(void) = ExitFunction :
|
||||
|
||||
# 2728| void test_postfix_crement(int*, int)
|
||||
# 2728| Block 0
|
||||
# 2728| v2728_1(void) = EnterFunction :
|
||||
# 2728| m2728_2(unknown) = AliasedDefinition :
|
||||
# 2728| m2728_3(unknown) = InitializeNonLocal :
|
||||
# 2728| m2728_4(unknown) = Chi : total:m2728_2, partial:m2728_3
|
||||
# 2728| r2728_5(glval<int *>) = VariableAddress[p] :
|
||||
# 2728| m2728_6(int *) = InitializeParameter[p] : &:r2728_5
|
||||
# 2728| r2728_7(int *) = Load[p] : &:r2728_5, m2728_6
|
||||
# 2728| m2728_8(unknown) = InitializeIndirection[p] : &:r2728_7
|
||||
# 2728| m2728_9(unknown) = Chi : total:m2728_4, partial:m2728_8
|
||||
# 2728| r2728_10(glval<int>) = VariableAddress[q] :
|
||||
# 2728| m2728_11(int) = InitializeParameter[q] : &:r2728_10
|
||||
# 2729| r2729_1(glval<int *>) = VariableAddress[p] :
|
||||
# 2729| r2729_2(int *) = Load[p] : &:r2729_1, m2728_6
|
||||
# 2729| r2729_3(int) = Constant[1] :
|
||||
# 2729| r2729_4(int *) = PointerAdd[4] : r2729_2, r2729_3
|
||||
# 2729| m2729_5(int *) = Store[p] : &:r2729_1, r2729_4
|
||||
# 2730| r2730_1(glval<int>) = VariableAddress[q] :
|
||||
# 2730| r2730_2(int) = Load[q] : &:r2730_1, m2728_11
|
||||
# 2730| r2730_3(int) = Constant[1] :
|
||||
# 2730| r2730_4(int) = Add : r2730_2, r2730_3
|
||||
# 2730| m2730_5(int) = Store[q] : &:r2730_1, r2730_4
|
||||
# 2731| r2731_1(glval<int *>) = VariableAddress[p] :
|
||||
# 2731| r2731_2(int *) = Load[p] : &:r2731_1, m2729_5
|
||||
# 2731| r2731_3(int) = Constant[1] :
|
||||
# 2731| r2731_4(int *) = PointerAdd[4] : r2731_2, r2731_3
|
||||
# 2731| m2731_5(int *) = Store[p] : &:r2731_1, r2731_4
|
||||
# 2731| r2731_6(int *) = CopyValue : r2731_2
|
||||
# 2732| r2732_1(glval<int>) = VariableAddress[q] :
|
||||
# 2732| r2732_2(int) = Load[q] : &:r2732_1, m2730_5
|
||||
# 2732| r2732_3(int) = Constant[1] :
|
||||
# 2732| r2732_4(int) = Add : r2732_2, r2732_3
|
||||
# 2732| m2732_5(int) = Store[q] : &:r2732_1, r2732_4
|
||||
# 2732| r2732_6(int) = CopyValue : r2732_2
|
||||
# 2733| r2733_1(glval<int *>) = VariableAddress[p] :
|
||||
# 2733| r2733_2(int *) = Load[p] : &:r2733_1, m2731_5
|
||||
# 2733| r2733_3(int) = Constant[1] :
|
||||
# 2733| r2733_4(int *) = PointerAdd[4] : r2733_2, r2733_3
|
||||
# 2733| m2733_5(int *) = Store[p] : &:r2733_1, r2733_4
|
||||
# 2733| r2733_6(int *) = CopyValue : r2733_2
|
||||
# 2733| v2733_7(void) = Convert : r2733_6
|
||||
# 2734| r2734_1(glval<int>) = VariableAddress[q] :
|
||||
# 2734| r2734_2(int) = Load[q] : &:r2734_1, m2732_5
|
||||
# 2734| r2734_3(int) = Constant[1] :
|
||||
# 2734| r2734_4(int) = Add : r2734_2, r2734_3
|
||||
# 2734| m2734_5(int) = Store[q] : &:r2734_1, r2734_4
|
||||
# 2734| r2734_6(int) = CopyValue : r2734_2
|
||||
# 2734| v2734_7(void) = Convert : r2734_6
|
||||
# 2735| r2735_1(glval<int *>) = VariableAddress[p] :
|
||||
# 2735| r2735_2(int *) = Load[p] : &:r2735_1, m2733_5
|
||||
# 2735| r2735_3(int) = Constant[1] :
|
||||
# 2735| r2735_4(int *) = PointerAdd[4] : r2735_2, r2735_3
|
||||
# 2735| m2735_5(int *) = Store[p] : &:r2735_1, r2735_4
|
||||
# 2735| r2735_6(int *) = CopyValue : r2735_2
|
||||
# 2735| v2735_7(void) = Convert : r2735_6
|
||||
# 2736| r2736_1(glval<int>) = VariableAddress[q] :
|
||||
# 2736| r2736_2(int) = Load[q] : &:r2736_1, m2734_5
|
||||
# 2736| r2736_3(int) = Constant[1] :
|
||||
# 2736| r2736_4(int) = Add : r2736_2, r2736_3
|
||||
# 2736| m2736_5(int) = Store[q] : &:r2736_1, r2736_4
|
||||
# 2736| r2736_6(int) = CopyValue : r2736_2
|
||||
# 2736| v2736_7(void) = Convert : r2736_6
|
||||
# 2737| r2737_1(glval<int *>) = VariableAddress[p1] :
|
||||
# 2737| r2737_2(glval<int *>) = VariableAddress[p] :
|
||||
# 2737| r2737_3(int *) = Load[p] : &:r2737_2, m2735_5
|
||||
# 2737| r2737_4(int) = Constant[1] :
|
||||
# 2737| r2737_5(int *) = PointerAdd[4] : r2737_3, r2737_4
|
||||
# 2737| m2737_6(int *) = Store[p] : &:r2737_2, r2737_5
|
||||
# 2737| r2737_7(int *) = CopyValue : r2737_3
|
||||
# 2737| m2737_8(int *) = Store[p1] : &:r2737_1, r2737_7
|
||||
# 2738| r2738_1(glval<int>) = VariableAddress[q1] :
|
||||
# 2738| r2738_2(glval<int>) = VariableAddress[q] :
|
||||
# 2738| r2738_3(int) = Load[q] : &:r2738_2, m2736_5
|
||||
# 2738| r2738_4(int) = Constant[1] :
|
||||
# 2738| r2738_5(int) = Add : r2738_3, r2738_4
|
||||
# 2738| m2738_6(int) = Store[q] : &:r2738_2, r2738_5
|
||||
# 2738| r2738_7(int) = CopyValue : r2738_3
|
||||
# 2738| m2738_8(int) = Store[q1] : &:r2738_1, r2738_7
|
||||
# 2739| r2739_1(glval<int *>) = VariableAddress[p] :
|
||||
# 2739| r2739_2(int *) = Load[p] : &:r2739_1, m2737_6
|
||||
# 2739| r2739_3(int) = Constant[1] :
|
||||
# 2739| r2739_4(int *) = PointerAdd[4] : r2739_2, r2739_3
|
||||
# 2739| m2739_5(int *) = Store[p] : &:r2739_1, r2739_4
|
||||
# 2739| r2739_6(int *) = CopyValue : r2739_2
|
||||
# 2739| r2739_7(int *) = Convert : r2739_6
|
||||
# 2740| r2740_1(glval<int>) = VariableAddress[q] :
|
||||
# 2740| r2740_2(int) = Load[q] : &:r2740_1, m2738_6
|
||||
# 2740| r2740_3(int) = Constant[1] :
|
||||
# 2740| r2740_4(int) = Add : r2740_2, r2740_3
|
||||
# 2740| m2740_5(int) = Store[q] : &:r2740_1, r2740_4
|
||||
# 2740| r2740_6(int) = CopyValue : r2740_2
|
||||
# 2740| r2740_7(int) = Convert : r2740_6
|
||||
# 2741| r2741_1(glval<int *>) = VariableAddress[p2] :
|
||||
# 2741| r2741_2(glval<int *>) = VariableAddress[p] :
|
||||
# 2741| r2741_3(int *) = Load[p] : &:r2741_2, m2739_5
|
||||
# 2741| r2741_4(int) = Constant[1] :
|
||||
# 2741| r2741_5(int *) = PointerAdd[4] : r2741_3, r2741_4
|
||||
# 2741| m2741_6(int *) = Store[p] : &:r2741_2, r2741_5
|
||||
# 2741| r2741_7(int *) = CopyValue : r2741_3
|
||||
# 2741| r2741_8(int *) = Convert : r2741_7
|
||||
# 2741| m2741_9(int *) = Store[p2] : &:r2741_1, r2741_8
|
||||
# 2742| r2742_1(glval<int>) = VariableAddress[q2] :
|
||||
# 2742| r2742_2(glval<int>) = VariableAddress[q] :
|
||||
# 2742| r2742_3(int) = Load[q] : &:r2742_2, m2740_5
|
||||
# 2742| r2742_4(int) = Constant[1] :
|
||||
# 2742| r2742_5(int) = Add : r2742_3, r2742_4
|
||||
# 2742| m2742_6(int) = Store[q] : &:r2742_2, r2742_5
|
||||
# 2742| r2742_7(int) = CopyValue : r2742_3
|
||||
# 2742| r2742_8(int) = Convert : r2742_7
|
||||
# 2742| m2742_9(int) = Store[q2] : &:r2742_1, r2742_8
|
||||
# 2743| v2743_1(void) = NoOp :
|
||||
# 2728| v2728_12(void) = ReturnIndirection[p] : &:r2728_7, m2728_8
|
||||
# 2728| v2728_13(void) = ReturnVoid :
|
||||
# 2728| v2728_14(void) = AliasedUse : ~m2728_9
|
||||
# 2728| v2728_15(void) = ExitFunction :
|
||||
|
||||
# 2747| void std::strong_ordering::strong_ordering(std::strong_ordering&&)
|
||||
# 2747| Block 0
|
||||
# 2747| v2747_1(void) = EnterFunction :
|
||||
# 2747| m2747_2(unknown) = AliasedDefinition :
|
||||
# 2747| m2747_3(unknown) = InitializeNonLocal :
|
||||
# 2747| m2747_4(unknown) = Chi : total:m2747_2, partial:m2747_3
|
||||
# 2747| r2747_5(glval<unknown>) = VariableAddress[#this] :
|
||||
# 2747| m2747_6(glval<strong_ordering>) = InitializeParameter[#this] : &:r2747_5
|
||||
# 2747| r2747_7(glval<strong_ordering>) = Load[#this] : &:r2747_5, m2747_6
|
||||
# 2747| m2747_8(strong_ordering) = InitializeIndirection[#this] : &:r2747_7
|
||||
#-----| r0_1(glval<strong_ordering &&>) = VariableAddress[(unnamed parameter 0)] :
|
||||
#-----| m0_2(strong_ordering &&) = InitializeParameter[(unnamed parameter 0)] : &:r0_1
|
||||
#-----| r0_3(strong_ordering &&) = Load[(unnamed parameter 0)] : &:r0_1, m0_2
|
||||
#-----| m0_4(unknown) = InitializeIndirection[(unnamed parameter 0)] : &:r0_3
|
||||
# 2747| v2747_9(void) = NoOp :
|
||||
# 2747| v2747_10(void) = ReturnIndirection[#this] : &:r2747_7, m2747_8
|
||||
#-----| v0_5(void) = ReturnIndirection[(unnamed parameter 0)] : &:r0_3, m0_4
|
||||
# 2747| v2747_11(void) = ReturnVoid :
|
||||
# 2747| v2747_12(void) = AliasedUse : m2747_3
|
||||
# 2747| v2747_13(void) = ExitFunction :
|
||||
|
||||
# 2748| void std::strong_ordering::strong_ordering(std::_Order)
|
||||
# 2748| Block 0
|
||||
# 2748| v2748_1(void) = EnterFunction :
|
||||
# 2748| m2748_2(unknown) = AliasedDefinition :
|
||||
# 2748| m2748_3(unknown) = InitializeNonLocal :
|
||||
# 2748| m2748_4(unknown) = Chi : total:m2748_2, partial:m2748_3
|
||||
# 2748| r2748_5(glval<unknown>) = VariableAddress[#this] :
|
||||
# 2748| m2748_6(glval<strong_ordering>) = InitializeParameter[#this] : &:r2748_5
|
||||
# 2748| r2748_7(glval<strong_ordering>) = Load[#this] : &:r2748_5, m2748_6
|
||||
# 2748| m2748_8(strong_ordering) = InitializeIndirection[#this] : &:r2748_7
|
||||
# 2748| r2748_9(glval<_Order>) = VariableAddress[v] :
|
||||
# 2748| m2748_10(_Order) = InitializeParameter[v] : &:r2748_9
|
||||
# 2748| v2748_11(void) = NoOp :
|
||||
# 2748| v2748_12(void) = ReturnIndirection[#this] : &:r2748_7, m2748_8
|
||||
# 2748| v2748_13(void) = ReturnVoid :
|
||||
# 2748| v2748_14(void) = AliasedUse : m2748_3
|
||||
# 2748| v2748_15(void) = ExitFunction :
|
||||
|
||||
# 2766| std::strong_ordering ThreeWay::operator<=>(ThreeWay&)
|
||||
# 2766| Block 0
|
||||
# 2766| v2766_1(void) = EnterFunction :
|
||||
# 2766| m2766_2(unknown) = AliasedDefinition :
|
||||
# 2766| m2766_3(unknown) = InitializeNonLocal :
|
||||
# 2766| m2766_4(unknown) = Chi : total:m2766_2, partial:m2766_3
|
||||
# 2766| r2766_5(glval<unknown>) = VariableAddress[#this] :
|
||||
# 2766| m2766_6(glval<ThreeWay>) = InitializeParameter[#this] : &:r2766_5
|
||||
# 2766| r2766_7(glval<ThreeWay>) = Load[#this] : &:r2766_5, m2766_6
|
||||
# 2766| m2766_8(ThreeWay) = InitializeIndirection[#this] : &:r2766_7
|
||||
# 2766| r2766_9(glval<ThreeWay &>) = VariableAddress[y] :
|
||||
# 2766| m2766_10(ThreeWay &) = InitializeParameter[y] : &:r2766_9
|
||||
# 2766| r2766_11(ThreeWay &) = Load[y] : &:r2766_9, m2766_10
|
||||
# 2766| m2766_12(unknown) = InitializeIndirection[y] : &:r2766_11
|
||||
# 2766| r2766_13(glval<strong_ordering>) = VariableAddress[#return] :
|
||||
# 2766| r2766_14(glval<unknown>) = VariableAddress[#this] :
|
||||
# 2766| r2766_15(ThreeWay *) = Load[#this] : &:r2766_14, m2766_6
|
||||
# 2766| r2766_16(glval<int>) = FieldAddress[x] : r2766_15
|
||||
# 2766| r2766_17(int) = Load[?] : &:r2766_16, ~m2766_8
|
||||
# 2766| r2766_18(glval<ThreeWay &>) = VariableAddress[y] :
|
||||
# 2766| r2766_19(ThreeWay &) = Load[y] : &:r2766_18, m2766_10
|
||||
# 2766| r2766_20(glval<ThreeWay>) = CopyValue : r2766_19
|
||||
# 2766| r2766_21(glval<int>) = FieldAddress[x] : r2766_20
|
||||
# 2766| r2766_22(int) = Load[?] : &:r2766_21, ~m2766_12
|
||||
# 2766| r2766_23(strong_ordering) = Spaceship : r2766_17, r2766_22
|
||||
# 2766| m2766_24(strong_ordering) = Store[#return] : &:r2766_13, r2766_23
|
||||
# 2766| v2766_25(void) = ReturnIndirection[#this] : &:r2766_7, m2766_8
|
||||
# 2766| v2766_26(void) = ReturnIndirection[y] : &:r2766_11, m2766_12
|
||||
# 2766| r2766_27(glval<strong_ordering>) = VariableAddress[#return] :
|
||||
# 2766| v2766_28(void) = ReturnValue : &:r2766_27, m2766_24
|
||||
# 2766| v2766_29(void) = AliasedUse : m2766_3
|
||||
# 2766| v2766_30(void) = ExitFunction :
|
||||
|
||||
# 2769| void test_three_way(int, int, ThreeWay, ThreeWay)
|
||||
# 2769| Block 0
|
||||
# 2769| v2769_1(void) = EnterFunction :
|
||||
# 2769| m2769_2(unknown) = AliasedDefinition :
|
||||
# 2769| m2769_3(unknown) = InitializeNonLocal :
|
||||
# 2769| m2769_4(unknown) = Chi : total:m2769_2, partial:m2769_3
|
||||
# 2769| r2769_5(glval<int>) = VariableAddress[a] :
|
||||
# 2769| m2769_6(int) = InitializeParameter[a] : &:r2769_5
|
||||
# 2769| r2769_7(glval<int>) = VariableAddress[b] :
|
||||
# 2769| m2769_8(int) = InitializeParameter[b] : &:r2769_7
|
||||
# 2769| r2769_9(glval<ThreeWay>) = VariableAddress[c] :
|
||||
# 2769| m2769_10(ThreeWay) = InitializeParameter[c] : &:r2769_9
|
||||
# 2769| r2769_11(glval<ThreeWay>) = VariableAddress[d] :
|
||||
# 2769| m2769_12(ThreeWay) = InitializeParameter[d] : &:r2769_11
|
||||
# 2770| r2770_1(glval<strong_ordering>) = VariableAddress[x] :
|
||||
# 2770| r2770_2(glval<int>) = VariableAddress[a] :
|
||||
# 2770| r2770_3(int) = Load[a] : &:r2770_2, m2769_6
|
||||
# 2770| r2770_4(glval<int>) = VariableAddress[b] :
|
||||
# 2770| r2770_5(int) = Load[b] : &:r2770_4, m2769_8
|
||||
# 2770| r2770_6(strong_ordering) = Spaceship : r2770_3, r2770_5
|
||||
# 2770| m2770_7(strong_ordering) = Store[x] : &:r2770_1, r2770_6
|
||||
# 2771| r2771_1(glval<strong_ordering>) = VariableAddress[y] :
|
||||
# 2771| r2771_2(glval<ThreeWay>) = VariableAddress[c] :
|
||||
# 2771| r2771_3(glval<unknown>) = FunctionAddress[operator<=>] :
|
||||
# 2771| r2771_4(glval<ThreeWay>) = VariableAddress[d] :
|
||||
# 2771| r2771_5(ThreeWay &) = CopyValue : r2771_4
|
||||
# 2771| r2771_6(strong_ordering) = Call[operator<=>] : func:r2771_3, this:r2771_2, 0:r2771_5
|
||||
# 2771| m2771_7(unknown) = ^CallSideEffect : ~m2769_4
|
||||
# 2771| m2771_8(unknown) = Chi : total:m2769_4, partial:m2771_7
|
||||
# 2771| v2771_9(void) = ^IndirectReadSideEffect[-1] : &:r2771_2, m2769_10
|
||||
# 2771| v2771_10(void) = ^BufferReadSideEffect[0] : &:r2771_5, ~m2769_12
|
||||
# 2771| m2771_11(ThreeWay) = ^IndirectMayWriteSideEffect[-1] : &:r2771_2
|
||||
# 2771| m2771_12(ThreeWay) = Chi : total:m2769_10, partial:m2771_11
|
||||
# 2771| m2771_13(unknown) = ^BufferMayWriteSideEffect[0] : &:r2771_5
|
||||
# 2771| m2771_14(ThreeWay) = Chi : total:m2769_12, partial:m2771_13
|
||||
# 2771| m2771_15(strong_ordering) = Store[y] : &:r2771_1, r2771_6
|
||||
# 2772| v2772_1(void) = NoOp :
|
||||
# 2769| v2769_13(void) = ReturnVoid :
|
||||
# 2769| v2769_14(void) = AliasedUse : ~m2771_8
|
||||
# 2769| v2769_15(void) = ExitFunction :
|
||||
|
||||
ir23.cpp:
|
||||
# 1| bool consteval_1()
|
||||
# 1| Block 0
|
||||
@@ -39856,3 +40086,27 @@ try_except.cpp:
|
||||
|
||||
# 44| Block 7
|
||||
# 44| v44_10(void) = Unreached :
|
||||
|
||||
type_info_test.cpp:
|
||||
# 3| void type_info_test(int)
|
||||
# 3| Block 0
|
||||
# 3| v3_1(void) = EnterFunction :
|
||||
# 3| m3_2(unknown) = AliasedDefinition :
|
||||
# 3| m3_3(unknown) = InitializeNonLocal :
|
||||
# 3| m3_4(unknown) = Chi : total:m3_2, partial:m3_3
|
||||
# 3| r3_5(glval<int>) = VariableAddress[x] :
|
||||
# 3| m3_6(int) = InitializeParameter[x] : &:r3_5
|
||||
# 3| m3_7(unknown) = Chi : total:m3_4, partial:m3_6
|
||||
# 4| r4_1(glval<type_info &>) = VariableAddress[t1] :
|
||||
# 4| r4_2(glval<int>) = VariableAddress[x] :
|
||||
# 4| r4_3(glval<type_info>) = TypeidExpr : r4_2
|
||||
# 4| r4_4(type_info &) = CopyValue : r4_3
|
||||
# 4| m4_5(type_info &) = Store[t1] : &:r4_1, r4_4
|
||||
# 5| r5_1(glval<type_info &>) = VariableAddress[t2] :
|
||||
# 5| r5_2(glval<type_info>) = TypeidType :
|
||||
# 5| r5_3(type_info &) = CopyValue : r5_2
|
||||
# 5| m5_4(type_info &) = Store[t2] : &:r5_1, r5_3
|
||||
# 6| v6_1(void) = NoOp :
|
||||
# 3| v3_8(void) = ReturnVoid :
|
||||
# 3| v3_9(void) = AliasedUse : m3_3
|
||||
# 3| v3_10(void) = ExitFunction :
|
||||
|
||||
@@ -2725,4 +2725,50 @@ char UseBracketOperator(const WithBracketOperator x, int i) {
|
||||
return x[i];
|
||||
}
|
||||
|
||||
void test_postfix_crement(int *p, int q) {
|
||||
p++;
|
||||
q++;
|
||||
(p++);
|
||||
(q++);
|
||||
(void)(p++);
|
||||
(void)(q++);
|
||||
(void)p++;
|
||||
(void)q++;
|
||||
int *p1 = p++;
|
||||
int q1 = q++;
|
||||
(int*)(p++);
|
||||
(int)(q++);
|
||||
int *p2 = (int*)(p++);
|
||||
int q2 = (int)(q++);
|
||||
}
|
||||
|
||||
namespace std {
|
||||
enum class _Order : signed char { __less = -1, __equiv = 0, __greater = 1 };
|
||||
class strong_ordering {
|
||||
explicit constexpr strong_ordering(_Order v) {}
|
||||
|
||||
public:
|
||||
static const strong_ordering less;
|
||||
static const strong_ordering equal;
|
||||
static const strong_ordering equivalent;
|
||||
static const strong_ordering greater;
|
||||
};
|
||||
|
||||
inline constexpr strong_ordering strong_ordering::less(_Order::__less);
|
||||
inline constexpr strong_ordering strong_ordering::equal(_Order::__equiv);
|
||||
inline constexpr strong_ordering strong_ordering::equivalent(_Order::__equiv);
|
||||
inline constexpr strong_ordering strong_ordering::greater(_Order::__greater);
|
||||
}
|
||||
|
||||
class ThreeWay {
|
||||
int x;
|
||||
public:
|
||||
std::strong_ordering operator<=>(ThreeWay &y) { return this->x <=> y.x; }
|
||||
};
|
||||
|
||||
void test_three_way(int a, int b, ThreeWay c, ThreeWay d) {
|
||||
auto x = a <=> b;
|
||||
auto y = c <=> d;
|
||||
}
|
||||
|
||||
// semmle-extractor-options: -std=c++20 --clang
|
||||
|
||||
@@ -18317,6 +18317,227 @@ ir.cpp:
|
||||
# 2724| v2724_10(void) = AliasedUse : ~m?
|
||||
# 2724| v2724_11(void) = ExitFunction :
|
||||
|
||||
# 2728| void test_postfix_crement(int*, int)
|
||||
# 2728| Block 0
|
||||
# 2728| v2728_1(void) = EnterFunction :
|
||||
# 2728| mu2728_2(unknown) = AliasedDefinition :
|
||||
# 2728| mu2728_3(unknown) = InitializeNonLocal :
|
||||
# 2728| r2728_4(glval<int *>) = VariableAddress[p] :
|
||||
# 2728| mu2728_5(int *) = InitializeParameter[p] : &:r2728_4
|
||||
# 2728| r2728_6(int *) = Load[p] : &:r2728_4, ~m?
|
||||
# 2728| mu2728_7(unknown) = InitializeIndirection[p] : &:r2728_6
|
||||
# 2728| r2728_8(glval<int>) = VariableAddress[q] :
|
||||
# 2728| mu2728_9(int) = InitializeParameter[q] : &:r2728_8
|
||||
# 2729| r2729_1(glval<int *>) = VariableAddress[p] :
|
||||
# 2729| r2729_2(int *) = Load[p] : &:r2729_1, ~m?
|
||||
# 2729| r2729_3(int) = Constant[1] :
|
||||
# 2729| r2729_4(int *) = PointerAdd[4] : r2729_2, r2729_3
|
||||
# 2729| mu2729_5(int *) = Store[p] : &:r2729_1, r2729_4
|
||||
# 2730| r2730_1(glval<int>) = VariableAddress[q] :
|
||||
# 2730| r2730_2(int) = Load[q] : &:r2730_1, ~m?
|
||||
# 2730| r2730_3(int) = Constant[1] :
|
||||
# 2730| r2730_4(int) = Add : r2730_2, r2730_3
|
||||
# 2730| mu2730_5(int) = Store[q] : &:r2730_1, r2730_4
|
||||
# 2731| r2731_1(glval<int *>) = VariableAddress[p] :
|
||||
# 2731| r2731_2(int *) = Load[p] : &:r2731_1, ~m?
|
||||
# 2731| r2731_3(int) = Constant[1] :
|
||||
# 2731| r2731_4(int *) = PointerAdd[4] : r2731_2, r2731_3
|
||||
# 2731| mu2731_5(int *) = Store[p] : &:r2731_1, r2731_4
|
||||
# 2731| r2731_6(int *) = CopyValue : r2731_2
|
||||
# 2732| r2732_1(glval<int>) = VariableAddress[q] :
|
||||
# 2732| r2732_2(int) = Load[q] : &:r2732_1, ~m?
|
||||
# 2732| r2732_3(int) = Constant[1] :
|
||||
# 2732| r2732_4(int) = Add : r2732_2, r2732_3
|
||||
# 2732| mu2732_5(int) = Store[q] : &:r2732_1, r2732_4
|
||||
# 2732| r2732_6(int) = CopyValue : r2732_2
|
||||
# 2733| r2733_1(glval<int *>) = VariableAddress[p] :
|
||||
# 2733| r2733_2(int *) = Load[p] : &:r2733_1, ~m?
|
||||
# 2733| r2733_3(int) = Constant[1] :
|
||||
# 2733| r2733_4(int *) = PointerAdd[4] : r2733_2, r2733_3
|
||||
# 2733| mu2733_5(int *) = Store[p] : &:r2733_1, r2733_4
|
||||
# 2733| r2733_6(int *) = CopyValue : r2733_2
|
||||
# 2733| v2733_7(void) = Convert : r2733_6
|
||||
# 2734| r2734_1(glval<int>) = VariableAddress[q] :
|
||||
# 2734| r2734_2(int) = Load[q] : &:r2734_1, ~m?
|
||||
# 2734| r2734_3(int) = Constant[1] :
|
||||
# 2734| r2734_4(int) = Add : r2734_2, r2734_3
|
||||
# 2734| mu2734_5(int) = Store[q] : &:r2734_1, r2734_4
|
||||
# 2734| r2734_6(int) = CopyValue : r2734_2
|
||||
# 2734| v2734_7(void) = Convert : r2734_6
|
||||
# 2735| r2735_1(glval<int *>) = VariableAddress[p] :
|
||||
# 2735| r2735_2(int *) = Load[p] : &:r2735_1, ~m?
|
||||
# 2735| r2735_3(int) = Constant[1] :
|
||||
# 2735| r2735_4(int *) = PointerAdd[4] : r2735_2, r2735_3
|
||||
# 2735| mu2735_5(int *) = Store[p] : &:r2735_1, r2735_4
|
||||
# 2735| r2735_6(int *) = CopyValue : r2735_2
|
||||
# 2735| v2735_7(void) = Convert : r2735_6
|
||||
# 2736| r2736_1(glval<int>) = VariableAddress[q] :
|
||||
# 2736| r2736_2(int) = Load[q] : &:r2736_1, ~m?
|
||||
# 2736| r2736_3(int) = Constant[1] :
|
||||
# 2736| r2736_4(int) = Add : r2736_2, r2736_3
|
||||
# 2736| mu2736_5(int) = Store[q] : &:r2736_1, r2736_4
|
||||
# 2736| r2736_6(int) = CopyValue : r2736_2
|
||||
# 2736| v2736_7(void) = Convert : r2736_6
|
||||
# 2737| r2737_1(glval<int *>) = VariableAddress[p1] :
|
||||
# 2737| r2737_2(glval<int *>) = VariableAddress[p] :
|
||||
# 2737| r2737_3(int *) = Load[p] : &:r2737_2, ~m?
|
||||
# 2737| r2737_4(int) = Constant[1] :
|
||||
# 2737| r2737_5(int *) = PointerAdd[4] : r2737_3, r2737_4
|
||||
# 2737| mu2737_6(int *) = Store[p] : &:r2737_2, r2737_5
|
||||
# 2737| r2737_7(int *) = CopyValue : r2737_3
|
||||
# 2737| mu2737_8(int *) = Store[p1] : &:r2737_1, r2737_7
|
||||
# 2738| r2738_1(glval<int>) = VariableAddress[q1] :
|
||||
# 2738| r2738_2(glval<int>) = VariableAddress[q] :
|
||||
# 2738| r2738_3(int) = Load[q] : &:r2738_2, ~m?
|
||||
# 2738| r2738_4(int) = Constant[1] :
|
||||
# 2738| r2738_5(int) = Add : r2738_3, r2738_4
|
||||
# 2738| mu2738_6(int) = Store[q] : &:r2738_2, r2738_5
|
||||
# 2738| r2738_7(int) = CopyValue : r2738_3
|
||||
# 2738| mu2738_8(int) = Store[q1] : &:r2738_1, r2738_7
|
||||
# 2739| r2739_1(glval<int *>) = VariableAddress[p] :
|
||||
# 2739| r2739_2(int *) = Load[p] : &:r2739_1, ~m?
|
||||
# 2739| r2739_3(int) = Constant[1] :
|
||||
# 2739| r2739_4(int *) = PointerAdd[4] : r2739_2, r2739_3
|
||||
# 2739| mu2739_5(int *) = Store[p] : &:r2739_1, r2739_4
|
||||
# 2739| r2739_6(int *) = CopyValue : r2739_2
|
||||
# 2739| r2739_7(int *) = Convert : r2739_6
|
||||
# 2740| r2740_1(glval<int>) = VariableAddress[q] :
|
||||
# 2740| r2740_2(int) = Load[q] : &:r2740_1, ~m?
|
||||
# 2740| r2740_3(int) = Constant[1] :
|
||||
# 2740| r2740_4(int) = Add : r2740_2, r2740_3
|
||||
# 2740| mu2740_5(int) = Store[q] : &:r2740_1, r2740_4
|
||||
# 2740| r2740_6(int) = CopyValue : r2740_2
|
||||
# 2740| r2740_7(int) = Convert : r2740_6
|
||||
# 2741| r2741_1(glval<int *>) = VariableAddress[p2] :
|
||||
# 2741| r2741_2(glval<int *>) = VariableAddress[p] :
|
||||
# 2741| r2741_3(int *) = Load[p] : &:r2741_2, ~m?
|
||||
# 2741| r2741_4(int) = Constant[1] :
|
||||
# 2741| r2741_5(int *) = PointerAdd[4] : r2741_3, r2741_4
|
||||
# 2741| mu2741_6(int *) = Store[p] : &:r2741_2, r2741_5
|
||||
# 2741| r2741_7(int *) = CopyValue : r2741_3
|
||||
# 2741| r2741_8(int *) = Convert : r2741_7
|
||||
# 2741| mu2741_9(int *) = Store[p2] : &:r2741_1, r2741_8
|
||||
# 2742| r2742_1(glval<int>) = VariableAddress[q2] :
|
||||
# 2742| r2742_2(glval<int>) = VariableAddress[q] :
|
||||
# 2742| r2742_3(int) = Load[q] : &:r2742_2, ~m?
|
||||
# 2742| r2742_4(int) = Constant[1] :
|
||||
# 2742| r2742_5(int) = Add : r2742_3, r2742_4
|
||||
# 2742| mu2742_6(int) = Store[q] : &:r2742_2, r2742_5
|
||||
# 2742| r2742_7(int) = CopyValue : r2742_3
|
||||
# 2742| r2742_8(int) = Convert : r2742_7
|
||||
# 2742| mu2742_9(int) = Store[q2] : &:r2742_1, r2742_8
|
||||
# 2743| v2743_1(void) = NoOp :
|
||||
# 2728| v2728_10(void) = ReturnIndirection[p] : &:r2728_6, ~m?
|
||||
# 2728| v2728_11(void) = ReturnVoid :
|
||||
# 2728| v2728_12(void) = AliasedUse : ~m?
|
||||
# 2728| v2728_13(void) = ExitFunction :
|
||||
|
||||
# 2747| void std::strong_ordering::strong_ordering(std::strong_ordering&&)
|
||||
# 2747| Block 0
|
||||
# 2747| v2747_1(void) = EnterFunction :
|
||||
# 2747| mu2747_2(unknown) = AliasedDefinition :
|
||||
# 2747| mu2747_3(unknown) = InitializeNonLocal :
|
||||
# 2747| r2747_4(glval<unknown>) = VariableAddress[#this] :
|
||||
# 2747| mu2747_5(glval<strong_ordering>) = InitializeParameter[#this] : &:r2747_4
|
||||
# 2747| r2747_6(glval<strong_ordering>) = Load[#this] : &:r2747_4, ~m?
|
||||
# 2747| mu2747_7(strong_ordering) = InitializeIndirection[#this] : &:r2747_6
|
||||
#-----| r0_1(glval<strong_ordering &&>) = VariableAddress[(unnamed parameter 0)] :
|
||||
#-----| mu0_2(strong_ordering &&) = InitializeParameter[(unnamed parameter 0)] : &:r0_1
|
||||
#-----| r0_3(strong_ordering &&) = Load[(unnamed parameter 0)] : &:r0_1, ~m?
|
||||
#-----| mu0_4(unknown) = InitializeIndirection[(unnamed parameter 0)] : &:r0_3
|
||||
# 2747| v2747_8(void) = NoOp :
|
||||
# 2747| v2747_9(void) = ReturnIndirection[#this] : &:r2747_6, ~m?
|
||||
#-----| v0_5(void) = ReturnIndirection[(unnamed parameter 0)] : &:r0_3, ~m?
|
||||
# 2747| v2747_10(void) = ReturnVoid :
|
||||
# 2747| v2747_11(void) = AliasedUse : ~m?
|
||||
# 2747| v2747_12(void) = ExitFunction :
|
||||
|
||||
# 2748| void std::strong_ordering::strong_ordering(std::_Order)
|
||||
# 2748| Block 0
|
||||
# 2748| v2748_1(void) = EnterFunction :
|
||||
# 2748| mu2748_2(unknown) = AliasedDefinition :
|
||||
# 2748| mu2748_3(unknown) = InitializeNonLocal :
|
||||
# 2748| r2748_4(glval<unknown>) = VariableAddress[#this] :
|
||||
# 2748| mu2748_5(glval<strong_ordering>) = InitializeParameter[#this] : &:r2748_4
|
||||
# 2748| r2748_6(glval<strong_ordering>) = Load[#this] : &:r2748_4, ~m?
|
||||
# 2748| mu2748_7(strong_ordering) = InitializeIndirection[#this] : &:r2748_6
|
||||
# 2748| r2748_8(glval<_Order>) = VariableAddress[v] :
|
||||
# 2748| mu2748_9(_Order) = InitializeParameter[v] : &:r2748_8
|
||||
# 2748| v2748_10(void) = NoOp :
|
||||
# 2748| v2748_11(void) = ReturnIndirection[#this] : &:r2748_6, ~m?
|
||||
# 2748| v2748_12(void) = ReturnVoid :
|
||||
# 2748| v2748_13(void) = AliasedUse : ~m?
|
||||
# 2748| v2748_14(void) = ExitFunction :
|
||||
|
||||
# 2766| std::strong_ordering ThreeWay::operator<=>(ThreeWay&)
|
||||
# 2766| Block 0
|
||||
# 2766| v2766_1(void) = EnterFunction :
|
||||
# 2766| mu2766_2(unknown) = AliasedDefinition :
|
||||
# 2766| mu2766_3(unknown) = InitializeNonLocal :
|
||||
# 2766| r2766_4(glval<unknown>) = VariableAddress[#this] :
|
||||
# 2766| mu2766_5(glval<ThreeWay>) = InitializeParameter[#this] : &:r2766_4
|
||||
# 2766| r2766_6(glval<ThreeWay>) = Load[#this] : &:r2766_4, ~m?
|
||||
# 2766| mu2766_7(ThreeWay) = InitializeIndirection[#this] : &:r2766_6
|
||||
# 2766| r2766_8(glval<ThreeWay &>) = VariableAddress[y] :
|
||||
# 2766| mu2766_9(ThreeWay &) = InitializeParameter[y] : &:r2766_8
|
||||
# 2766| r2766_10(ThreeWay &) = Load[y] : &:r2766_8, ~m?
|
||||
# 2766| mu2766_11(unknown) = InitializeIndirection[y] : &:r2766_10
|
||||
# 2766| r2766_12(glval<strong_ordering>) = VariableAddress[#return] :
|
||||
# 2766| r2766_13(glval<unknown>) = VariableAddress[#this] :
|
||||
# 2766| r2766_14(ThreeWay *) = Load[#this] : &:r2766_13, ~m?
|
||||
# 2766| r2766_15(glval<int>) = FieldAddress[x] : r2766_14
|
||||
# 2766| r2766_16(int) = Load[?] : &:r2766_15, ~m?
|
||||
# 2766| r2766_17(glval<ThreeWay &>) = VariableAddress[y] :
|
||||
# 2766| r2766_18(ThreeWay &) = Load[y] : &:r2766_17, ~m?
|
||||
# 2766| r2766_19(glval<ThreeWay>) = CopyValue : r2766_18
|
||||
# 2766| r2766_20(glval<int>) = FieldAddress[x] : r2766_19
|
||||
# 2766| r2766_21(int) = Load[?] : &:r2766_20, ~m?
|
||||
# 2766| r2766_22(strong_ordering) = Spaceship : r2766_16, r2766_21
|
||||
# 2766| mu2766_23(strong_ordering) = Store[#return] : &:r2766_12, r2766_22
|
||||
# 2766| v2766_24(void) = ReturnIndirection[#this] : &:r2766_6, ~m?
|
||||
# 2766| v2766_25(void) = ReturnIndirection[y] : &:r2766_10, ~m?
|
||||
# 2766| r2766_26(glval<strong_ordering>) = VariableAddress[#return] :
|
||||
# 2766| v2766_27(void) = ReturnValue : &:r2766_26, ~m?
|
||||
# 2766| v2766_28(void) = AliasedUse : ~m?
|
||||
# 2766| v2766_29(void) = ExitFunction :
|
||||
|
||||
# 2769| void test_three_way(int, int, ThreeWay, ThreeWay)
|
||||
# 2769| Block 0
|
||||
# 2769| v2769_1(void) = EnterFunction :
|
||||
# 2769| mu2769_2(unknown) = AliasedDefinition :
|
||||
# 2769| mu2769_3(unknown) = InitializeNonLocal :
|
||||
# 2769| r2769_4(glval<int>) = VariableAddress[a] :
|
||||
# 2769| mu2769_5(int) = InitializeParameter[a] : &:r2769_4
|
||||
# 2769| r2769_6(glval<int>) = VariableAddress[b] :
|
||||
# 2769| mu2769_7(int) = InitializeParameter[b] : &:r2769_6
|
||||
# 2769| r2769_8(glval<ThreeWay>) = VariableAddress[c] :
|
||||
# 2769| mu2769_9(ThreeWay) = InitializeParameter[c] : &:r2769_8
|
||||
# 2769| r2769_10(glval<ThreeWay>) = VariableAddress[d] :
|
||||
# 2769| mu2769_11(ThreeWay) = InitializeParameter[d] : &:r2769_10
|
||||
# 2770| r2770_1(glval<strong_ordering>) = VariableAddress[x] :
|
||||
# 2770| r2770_2(glval<int>) = VariableAddress[a] :
|
||||
# 2770| r2770_3(int) = Load[a] : &:r2770_2, ~m?
|
||||
# 2770| r2770_4(glval<int>) = VariableAddress[b] :
|
||||
# 2770| r2770_5(int) = Load[b] : &:r2770_4, ~m?
|
||||
# 2770| r2770_6(strong_ordering) = Spaceship : r2770_3, r2770_5
|
||||
# 2770| mu2770_7(strong_ordering) = Store[x] : &:r2770_1, r2770_6
|
||||
# 2771| r2771_1(glval<strong_ordering>) = VariableAddress[y] :
|
||||
# 2771| r2771_2(glval<ThreeWay>) = VariableAddress[c] :
|
||||
# 2771| r2771_3(glval<unknown>) = FunctionAddress[operator<=>] :
|
||||
# 2771| r2771_4(glval<ThreeWay>) = VariableAddress[d] :
|
||||
# 2771| r2771_5(ThreeWay &) = CopyValue : r2771_4
|
||||
# 2771| r2771_6(strong_ordering) = Call[operator<=>] : func:r2771_3, this:r2771_2, 0:r2771_5
|
||||
# 2771| mu2771_7(unknown) = ^CallSideEffect : ~m?
|
||||
# 2771| v2771_8(void) = ^IndirectReadSideEffect[-1] : &:r2771_2, ~m?
|
||||
# 2771| v2771_9(void) = ^BufferReadSideEffect[0] : &:r2771_5, ~m?
|
||||
# 2771| mu2771_10(ThreeWay) = ^IndirectMayWriteSideEffect[-1] : &:r2771_2
|
||||
# 2771| mu2771_11(unknown) = ^BufferMayWriteSideEffect[0] : &:r2771_5
|
||||
# 2771| mu2771_12(strong_ordering) = Store[y] : &:r2771_1, r2771_6
|
||||
# 2772| v2772_1(void) = NoOp :
|
||||
# 2769| v2769_12(void) = ReturnVoid :
|
||||
# 2769| v2769_13(void) = AliasedUse : ~m?
|
||||
# 2769| v2769_14(void) = ExitFunction :
|
||||
|
||||
ir23.cpp:
|
||||
# 1| bool consteval_1()
|
||||
# 1| Block 0
|
||||
@@ -37987,3 +38208,25 @@ try_except.cpp:
|
||||
# 54| v54_1(void) = NoOp :
|
||||
# 44| v44_9(void) = ReturnVoid :
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
type_info_test.cpp:
|
||||
# 3| void type_info_test(int)
|
||||
# 3| Block 0
|
||||
# 3| v3_1(void) = EnterFunction :
|
||||
# 3| mu3_2(unknown) = AliasedDefinition :
|
||||
# 3| mu3_3(unknown) = InitializeNonLocal :
|
||||
# 3| r3_4(glval<int>) = VariableAddress[x] :
|
||||
# 3| mu3_5(int) = InitializeParameter[x] : &:r3_4
|
||||
# 4| r4_1(glval<type_info &>) = VariableAddress[t1] :
|
||||
# 4| r4_2(glval<int>) = VariableAddress[x] :
|
||||
# 4| r4_3(glval<type_info>) = TypeidExpr : r4_2
|
||||
# 4| r4_4(type_info &) = CopyValue : r4_3
|
||||
# 4| mu4_5(type_info &) = Store[t1] : &:r4_1, r4_4
|
||||
# 5| r5_1(glval<type_info &>) = VariableAddress[t2] :
|
||||
# 5| r5_2(glval<type_info>) = TypeidType :
|
||||
# 5| r5_3(type_info &) = CopyValue : r5_2
|
||||
# 5| mu5_4(type_info &) = Store[t2] : &:r5_1, r5_3
|
||||
# 6| v6_1(void) = NoOp :
|
||||
# 3| v3_6(void) = ReturnVoid :
|
||||
# 3| v3_7(void) = AliasedUse : ~m?
|
||||
# 3| v3_8(void) = ExitFunction :
|
||||
|
||||
8
cpp/ql/test/library-tests/ir/ir/type_info_test.cpp
Normal file
8
cpp/ql/test/library-tests/ir/ir/type_info_test.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
#include <typeinfo>
|
||||
|
||||
void type_info_test(int x) {
|
||||
const std::type_info &t1 = typeid(x);
|
||||
const std::type_info &t2 = typeid(int);
|
||||
}
|
||||
|
||||
// semmle-extractor-options: -I.
|
||||
5
cpp/ql/test/library-tests/ir/ir/typeinfo
Normal file
5
cpp/ql/test/library-tests/ir/ir/typeinfo
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
namespace std{
|
||||
class type_info {};
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
| test.cpp:12:16:12:17 | g1 | Initialization code for 'g1' is never run. |
|
||||
| test.cpp:14:23:14:24 | g3 | Initialization code for 'g3' is never run. |
|
||||
@@ -0,0 +1 @@
|
||||
Critical/InitialisationNotRun.ql
|
||||
@@ -0,0 +1,36 @@
|
||||
// --- stubs ---
|
||||
|
||||
char *strcpy(char *dest, const char *src);
|
||||
|
||||
// --- tests ---
|
||||
|
||||
class GlobalStorage {
|
||||
public:
|
||||
char name[1000];
|
||||
};
|
||||
|
||||
GlobalStorage *g1; // BAD
|
||||
static GlobalStorage g2; // GOOD
|
||||
static GlobalStorage *g3; // BAD
|
||||
// static variables are initialized by compilers
|
||||
static int a; // GOOD
|
||||
static int b = 0; // GOOD
|
||||
|
||||
void init() { //initializes g_storage, but is never run from main
|
||||
g1 = new GlobalStorage();
|
||||
g3 = new GlobalStorage();
|
||||
}
|
||||
|
||||
void init2(int b) {
|
||||
for (int i = 0; i < b; ++i)
|
||||
a *= -1;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
//init not called
|
||||
strcpy(g1->name, argv[1]); // g1 is used before init() is called
|
||||
strcpy(g2.name, argv[1]); // g2 is initialised by compiler
|
||||
strcpy(g3->name, argv[1]);
|
||||
b++;
|
||||
return 0;
|
||||
}
|
||||
@@ -12,19 +12,6 @@ edges
|
||||
| test.cpp:42:13:42:15 | *str [string] | test.cpp:42:18:42:23 | string | provenance | |
|
||||
| test.cpp:72:17:72:19 | *str [string] | test.cpp:72:22:72:27 | string | provenance | |
|
||||
| test.cpp:80:17:80:19 | *str [string] | test.cpp:80:22:80:27 | string | provenance | |
|
||||
| test.cpp:88:11:88:30 | **mk_string_t_plus_one [string] | test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | provenance | |
|
||||
| test.cpp:90:5:90:7 | *str [post update] [string] | test.cpp:91:5:91:7 | *str [string] | provenance | |
|
||||
| test.cpp:90:5:90:34 | ... = ... | test.cpp:90:5:90:7 | *str [post update] [string] | provenance | |
|
||||
| test.cpp:90:19:90:24 | call to malloc | test.cpp:90:5:90:34 | ... = ... | provenance | |
|
||||
| test.cpp:91:5:91:7 | *str [string] | test.cpp:92:12:92:14 | *str [string] | provenance | |
|
||||
| test.cpp:92:12:92:14 | *str [string] | test.cpp:88:11:88:30 | **mk_string_t_plus_one [string] | provenance | |
|
||||
| test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | provenance | |
|
||||
| test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | test.cpp:99:13:99:15 | *str [string] | provenance | |
|
||||
| test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | test.cpp:129:17:129:19 | *str [string] | provenance | |
|
||||
| test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | test.cpp:137:17:137:19 | *str [string] | provenance | |
|
||||
| test.cpp:99:13:99:15 | *str [string] | test.cpp:99:18:99:23 | string | provenance | |
|
||||
| test.cpp:129:17:129:19 | *str [string] | test.cpp:129:22:129:27 | string | provenance | |
|
||||
| test.cpp:137:17:137:19 | *str [string] | test.cpp:137:22:137:27 | string | provenance | |
|
||||
| test.cpp:147:5:147:7 | *str [post update] [string] | test.cpp:148:5:148:7 | *str [string] | provenance | |
|
||||
| test.cpp:147:5:147:34 | ... = ... | test.cpp:147:5:147:7 | *str [post update] [string] | provenance | |
|
||||
| test.cpp:147:19:147:24 | call to malloc | test.cpp:147:5:147:34 | ... = ... | provenance | |
|
||||
@@ -46,12 +33,6 @@ edges
|
||||
| test.cpp:199:17:199:19 | *str [string] | test.cpp:199:22:199:27 | string | provenance | |
|
||||
| test.cpp:203:17:203:19 | *str [string] | test.cpp:203:22:203:27 | string | provenance | |
|
||||
| test.cpp:207:17:207:19 | *str [string] | test.cpp:207:22:207:27 | string | provenance | |
|
||||
| test.cpp:214:24:214:24 | p | test.cpp:216:10:216:10 | p | provenance | |
|
||||
| test.cpp:220:27:220:54 | call to malloc | test.cpp:220:27:220:54 | call to malloc | provenance | |
|
||||
| test.cpp:220:27:220:54 | call to malloc | test.cpp:222:15:222:20 | buffer | provenance | |
|
||||
| test.cpp:222:15:222:20 | buffer | test.cpp:214:24:214:24 | p | provenance | |
|
||||
| test.cpp:228:27:228:54 | call to malloc | test.cpp:228:27:228:54 | call to malloc | provenance | |
|
||||
| test.cpp:228:27:228:54 | call to malloc | test.cpp:232:10:232:15 | buffer | provenance | |
|
||||
| test.cpp:235:40:235:45 | buffer | test.cpp:236:5:236:26 | ... = ... | provenance | |
|
||||
| test.cpp:236:5:236:9 | *p_str [post update] [string] | test.cpp:235:27:235:31 | *p_str [Return] [string] | provenance | |
|
||||
| test.cpp:236:5:236:9 | *p_str [post update] [string] | test.cpp:235:27:235:31 | *p_str [string] | provenance | |
|
||||
@@ -64,8 +45,6 @@ edges
|
||||
| test.cpp:243:12:243:14 | *str [string] | test.cpp:243:12:243:21 | string | provenance | |
|
||||
| test.cpp:249:14:249:33 | call to my_alloc | test.cpp:249:14:249:33 | call to my_alloc | provenance | |
|
||||
| test.cpp:249:14:249:33 | call to my_alloc | test.cpp:250:12:250:12 | p | provenance | |
|
||||
| test.cpp:256:5:256:25 | ... = ... | test.cpp:257:12:257:12 | p | provenance | |
|
||||
| test.cpp:256:9:256:25 | call to malloc | test.cpp:256:5:256:25 | ... = ... | provenance | |
|
||||
| test.cpp:262:15:262:30 | call to malloc | test.cpp:262:15:262:30 | call to malloc | provenance | |
|
||||
| test.cpp:262:15:262:30 | call to malloc | test.cpp:266:12:266:12 | p | provenance | |
|
||||
| test.cpp:264:9:264:30 | ... = ... | test.cpp:266:12:266:12 | p | provenance | |
|
||||
@@ -85,20 +64,6 @@ nodes
|
||||
| test.cpp:72:22:72:27 | string | semmle.label | string |
|
||||
| test.cpp:80:17:80:19 | *str [string] | semmle.label | *str [string] |
|
||||
| test.cpp:80:22:80:27 | string | semmle.label | string |
|
||||
| test.cpp:88:11:88:30 | **mk_string_t_plus_one [string] | semmle.label | **mk_string_t_plus_one [string] |
|
||||
| test.cpp:90:5:90:7 | *str [post update] [string] | semmle.label | *str [post update] [string] |
|
||||
| test.cpp:90:5:90:34 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:90:19:90:24 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:91:5:91:7 | *str [string] | semmle.label | *str [string] |
|
||||
| test.cpp:92:12:92:14 | *str [string] | semmle.label | *str [string] |
|
||||
| test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | semmle.label | *call to mk_string_t_plus_one [string] |
|
||||
| test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | semmle.label | *call to mk_string_t_plus_one [string] |
|
||||
| test.cpp:99:13:99:15 | *str [string] | semmle.label | *str [string] |
|
||||
| test.cpp:99:18:99:23 | string | semmle.label | string |
|
||||
| test.cpp:129:17:129:19 | *str [string] | semmle.label | *str [string] |
|
||||
| test.cpp:129:22:129:27 | string | semmle.label | string |
|
||||
| test.cpp:137:17:137:19 | *str [string] | semmle.label | *str [string] |
|
||||
| test.cpp:137:22:137:27 | string | semmle.label | string |
|
||||
| test.cpp:147:5:147:7 | *str [post update] [string] | semmle.label | *str [post update] [string] |
|
||||
| test.cpp:147:5:147:34 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:147:19:147:24 | call to malloc | semmle.label | call to malloc |
|
||||
@@ -121,14 +86,6 @@ nodes
|
||||
| test.cpp:203:22:203:27 | string | semmle.label | string |
|
||||
| test.cpp:207:17:207:19 | *str [string] | semmle.label | *str [string] |
|
||||
| test.cpp:207:22:207:27 | string | semmle.label | string |
|
||||
| test.cpp:214:24:214:24 | p | semmle.label | p |
|
||||
| test.cpp:216:10:216:10 | p | semmle.label | p |
|
||||
| test.cpp:220:27:220:54 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:220:27:220:54 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:222:15:222:20 | buffer | semmle.label | buffer |
|
||||
| test.cpp:228:27:228:54 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:228:27:228:54 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:232:10:232:15 | buffer | semmle.label | buffer |
|
||||
| test.cpp:235:27:235:31 | *p_str [Return] [string] | semmle.label | *p_str [Return] [string] |
|
||||
| test.cpp:235:27:235:31 | *p_str [string] | semmle.label | *p_str [string] |
|
||||
| test.cpp:235:40:235:45 | buffer | semmle.label | buffer |
|
||||
@@ -143,9 +100,6 @@ nodes
|
||||
| test.cpp:249:14:249:33 | call to my_alloc | semmle.label | call to my_alloc |
|
||||
| test.cpp:249:14:249:33 | call to my_alloc | semmle.label | call to my_alloc |
|
||||
| test.cpp:250:12:250:12 | p | semmle.label | p |
|
||||
| test.cpp:256:5:256:25 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:256:9:256:25 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:257:12:257:12 | p | semmle.label | p |
|
||||
| test.cpp:262:15:262:30 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:262:15:262:30 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:264:9:264:30 | ... = ... | semmle.label | ... = ... |
|
||||
@@ -158,9 +112,6 @@ subpaths
|
||||
| test.cpp:42:5:42:11 | call to strncpy | test.cpp:18:19:18:24 | call to malloc | test.cpp:42:18:42:23 | string | This write may overflow $@ by 1 element. | test.cpp:42:18:42:23 | string | string |
|
||||
| test.cpp:72:9:72:15 | call to strncpy | test.cpp:18:19:18:24 | call to malloc | test.cpp:72:22:72:27 | string | This write may overflow $@ by 1 element. | test.cpp:72:22:72:27 | string | string |
|
||||
| test.cpp:80:9:80:15 | call to strncpy | test.cpp:18:19:18:24 | call to malloc | test.cpp:80:22:80:27 | string | This write may overflow $@ by 2 elements. | test.cpp:80:22:80:27 | string | string |
|
||||
| test.cpp:99:5:99:11 | call to strncpy | test.cpp:90:19:90:24 | call to malloc | test.cpp:99:18:99:23 | string | This write may overflow $@ by 1 element. | test.cpp:99:18:99:23 | string | string |
|
||||
| test.cpp:129:9:129:15 | call to strncpy | test.cpp:90:19:90:24 | call to malloc | test.cpp:129:22:129:27 | string | This write may overflow $@ by 1 element. | test.cpp:129:22:129:27 | string | string |
|
||||
| test.cpp:137:9:137:15 | call to strncpy | test.cpp:90:19:90:24 | call to malloc | test.cpp:137:22:137:27 | string | This write may overflow $@ by 2 elements. | test.cpp:137:22:137:27 | string | string |
|
||||
| test.cpp:152:5:152:11 | call to strncpy | test.cpp:147:19:147:24 | call to malloc | test.cpp:152:18:152:23 | string | This write may overflow $@ by 1 element. | test.cpp:152:18:152:23 | string | string |
|
||||
| test.cpp:154:5:154:11 | call to strncpy | test.cpp:147:19:147:24 | call to malloc | test.cpp:154:18:154:23 | string | This write may overflow $@ by 1 element. | test.cpp:154:18:154:23 | string | string |
|
||||
| test.cpp:156:5:156:11 | call to strncpy | test.cpp:147:19:147:24 | call to malloc | test.cpp:156:18:156:23 | string | This write may overflow $@ by 2 elements. | test.cpp:156:18:156:23 | string | string |
|
||||
|
||||
@@ -264,4 +264,15 @@ void test7(unsigned n) {
|
||||
p = (char*)malloc(++n);
|
||||
}
|
||||
memset(p, 0, n); // GOOD [FALSE POSITIVE]
|
||||
}
|
||||
|
||||
void test8(unsigned size, unsigned src_pos)
|
||||
{
|
||||
char *xs = new char[size];
|
||||
if (src_pos > size) {
|
||||
src_pos = size;
|
||||
}
|
||||
if (src_pos < size - 1) {
|
||||
memset(xs, 0, src_pos + 1); // GOOD
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user