Skip to content

Commit 7c25063

Browse files
committed
Merge branch 'main' into swift-decls-in-cfg
2 parents df2c197 + 2dcd7e1 commit 7c25063

File tree

180 files changed

+5798
-4368
lines changed

Some content is hidden

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

180 files changed

+5798
-4368
lines changed

.github/workflows/js-ml-tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ on:
1212
paths:
1313
- "javascript/ql/experimental/adaptivethreatmodeling/**"
1414
- .github/workflows/js-ml-tests.yml
15+
workflow_dispatch:
1516

1617
defaults:
1718
run:

cpp/ql/src/experimental/Security/CWE/CWE-020/NoCheckBeforeUnsafePutUser.ql

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,36 @@
1717
import cpp
1818
import semmle.code.cpp.dataflow.DataFlow
1919

20+
/**
21+
* A Linux system call.
22+
*/
23+
class SystemCallFunction extends Function {
24+
SystemCallFunction() {
25+
exists(MacroInvocation m |
26+
m.getMacro().getName().matches("SYSCALL\\_DEFINE%") and
27+
this = m.getEnclosingFunction()
28+
)
29+
}
30+
}
31+
32+
/**
33+
* A value that comes from a Linux system call (sources).
34+
*/
35+
class SystemCallSource extends DataFlow::Node {
36+
SystemCallSource() {
37+
exists(FunctionCall fc |
38+
fc.getTarget() instanceof SystemCallFunction and
39+
(
40+
this.asDefiningArgument() = fc.getAnArgument().getAChild*() or
41+
this.asExpr() = fc
42+
)
43+
)
44+
}
45+
}
46+
47+
/**
48+
* Macros used to check the value (barriers).
49+
*/
2050
class WriteAccessCheckMacro extends Macro {
2151
VariableAccess va;
2252

@@ -28,6 +58,9 @@ class WriteAccessCheckMacro extends Macro {
2858
VariableAccess getArgument() { result = va }
2959
}
3060

61+
/**
62+
* The `unsafe_put_user` macro and its uses (sinks).
63+
*/
3164
class UnSafePutUserMacro extends Macro {
3265
PointerDereferenceExpr writeUserPtr;
3366

@@ -42,15 +75,13 @@ class UnSafePutUserMacro extends Macro {
4275
}
4376
}
4477

45-
class ExploitableUserModePtrParam extends Parameter {
78+
class ExploitableUserModePtrParam extends SystemCallSource {
4679
ExploitableUserModePtrParam() {
47-
not exists(WriteAccessCheckMacro writeAccessCheck |
48-
DataFlow::localFlow(DataFlow::parameterNode(this),
49-
DataFlow::exprNode(writeAccessCheck.getArgument()))
50-
) and
5180
exists(UnSafePutUserMacro unsafePutUser |
52-
DataFlow::localFlow(DataFlow::parameterNode(this),
53-
DataFlow::exprNode(unsafePutUser.getUserModePtr()))
81+
DataFlow::localFlow(this, DataFlow::exprNode(unsafePutUser.getUserModePtr()))
82+
) and
83+
not exists(WriteAccessCheckMacro writeAccessCheck |
84+
DataFlow::localFlow(this, DataFlow::exprNode(writeAccessCheck.getArgument()))
5485
)
5586
}
5687
}
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
| test.cpp:14:16:14:16 | p | unsafe_put_user write user-mode pointer $@ without check. | test.cpp:14:16:14:16 | p | p |
1+
| test.cpp:20:21:20:22 | ref arg & ... | unsafe_put_user write user-mode pointer $@ without check. | test.cpp:20:21:20:22 | ref arg & ... | ref arg & ... |
2+
| test.cpp:41:21:41:22 | ref arg & ... | unsafe_put_user write user-mode pointer $@ without check. | test.cpp:41:21:41:22 | ref arg & ... | ref arg & ... |
3+
| test.cpp:69:21:69:27 | ref arg & ... | unsafe_put_user write user-mode pointer $@ without check. | test.cpp:69:21:69:27 | ref arg & ... | ref arg & ... |

cpp/ql/test/experimental/query-tests/Security/CWE/CWE-020/NoCheckBeforeUnsafePutUser/test.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11

22
typedef unsigned long size_t;
33

4-
void SYSC_SOMESYSTEMCALL(void *param);
4+
#define SYSCALL_DEFINE(name, ...) \
5+
void do_sys_##name(); \
6+
void sys_##name(...) { do_sys_##name(); } \
7+
void do_sys_##name()
8+
SYSCALL_DEFINE(somesystemcall, void *param) {};
59

610
bool user_access_begin_impl(const void *where, size_t sz);
711
void user_access_end_impl();
@@ -13,14 +17,14 @@ void unsafe_put_user_impl(int what, const void *where, size_t sz);
1317

1418
void test1(int p)
1519
{
16-
SYSC_SOMESYSTEMCALL(&p);
20+
sys_somesystemcall(&p);
1721

1822
unsafe_put_user(123, &p); // BAD
1923
}
2024

2125
void test2(int p)
2226
{
23-
SYSC_SOMESYSTEMCALL(&p);
27+
sys_somesystemcall(&p);
2428

2529
if (user_access_begin(&p, sizeof(p)))
2630
{
@@ -34,16 +38,16 @@ void test3()
3438
{
3539
int v;
3640

37-
SYSC_SOMESYSTEMCALL(&v);
41+
sys_somesystemcall(&v);
3842

39-
unsafe_put_user(123, &v); // BAD [NOT DETECTED]
43+
unsafe_put_user(123, &v); // BAD
4044
}
4145

4246
void test4()
4347
{
4448
int v;
4549

46-
SYSC_SOMESYSTEMCALL(&v);
50+
sys_somesystemcall(&v);
4751

4852
if (user_access_begin(&v, sizeof(v)))
4953
{
@@ -62,16 +66,16 @@ void test5()
6266
{
6367
data myData;
6468

65-
SYSC_SOMESYSTEMCALL(&myData);
69+
sys_somesystemcall(&myData);
6670

67-
unsafe_put_user(123, &(myData.x)); // BAD [NOT DETECTED]
71+
unsafe_put_user(123, &(myData.x)); // BAD
6872
}
6973

7074
void test6()
7175
{
7276
data myData;
7377

74-
SYSC_SOMESYSTEMCALL(&myData);
78+
sys_somesystemcall(&myData);
7579

7680
if (user_access_begin(&myData, sizeof(myData)))
7781
{

docs/codeql/codeql-cli/creating-codeql-databases.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,8 @@ commands that you can specify for compiled languages.
226226

227227
- Java project built using Gradle::
228228

229-
codeql database create java-database --language=java --command='gradle clean test'
229+
# Use `--no-daemon` because a build delegated to an existing daemon cannot be detected by CodeQL:
230+
codeql database create java-database --language=java --command='gradle --no-daemon clean test'
230231

231232
- Java project built using Maven::
232233

java/kotlin-extractor/src/main/java/com/semmle/extractor/java/OdasaOutput.java

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@
44
import java.io.File;
55
import java.io.IOException;
66
import java.util.Arrays;
7+
import java.util.Enumeration;
8+
import java.util.HashMap;
79
import java.util.LinkedHashMap;
810
import java.util.Map;
911
import java.util.Objects;
1012
import java.util.regex.Pattern;
13+
import java.util.zip.ZipEntry;
14+
import java.util.zip.ZipFile;
1115

1216
import com.github.codeql.Logger;
1317
import static com.github.codeql.ClassNamesKt.getIrDeclBinaryName;
@@ -547,6 +551,51 @@ else if (majorVersion==0)
547551
(tcv.majorVersion == majorVersion && tcv.minorVersion == minorVersion &&
548552
tcv.lastModified < lastModified);
549553
}
554+
555+
private static Map<String, Map<String, Long>> jarFileEntryTimeStamps = new HashMap<>();
556+
557+
private static Map<String, Long> getZipFileEntryTimeStamps(String path, Logger log) {
558+
try {
559+
Map<String, Long> result = new HashMap<>();
560+
ZipFile zf = new ZipFile(path);
561+
Enumeration<? extends ZipEntry> entries = zf.entries();
562+
while (entries.hasMoreElements()) {
563+
ZipEntry ze = entries.nextElement();
564+
result.put(ze.getName(), ze.getLastModifiedTime().toMillis());
565+
}
566+
return result;
567+
} catch(IOException e) {
568+
log.warn("Failed to get entry timestamps from " + path, e);
569+
return null;
570+
}
571+
}
572+
573+
private static long getVirtualFileTimeStamp(VirtualFile vf, Logger log) {
574+
if (vf.getFileSystem().getProtocol().equals("jar")) {
575+
String[] parts = vf.getPath().split("!/");
576+
if (parts.length == 2) {
577+
String jarFilePath = parts[0];
578+
String entryPath = parts[1];
579+
if (!jarFileEntryTimeStamps.containsKey(jarFilePath)) {
580+
jarFileEntryTimeStamps.put(jarFilePath, getZipFileEntryTimeStamps(jarFilePath, log));
581+
}
582+
Map<String, Long> entryTimeStamps = jarFileEntryTimeStamps.get(jarFilePath);
583+
if (entryTimeStamps != null) {
584+
Long entryTimeStamp = entryTimeStamps.get(entryPath);
585+
if (entryTimeStamp != null)
586+
return entryTimeStamp;
587+
else
588+
log.warn("Couldn't find timestamp for jar file " + jarFilePath + " entry " + entryPath);
589+
}
590+
} else {
591+
log.warn("Expected JAR-file path " + vf.getPath() + " to have exactly one '!/' separator");
592+
}
593+
}
594+
595+
// For all files except for jar files, and a fallback in case of I/O problems reading a jar file:
596+
return vf.getTimeStamp();
597+
}
598+
550599
private static TrapClassVersion fromSymbol(IrDeclaration sym, Logger log) {
551600
VirtualFile vf = sym instanceof IrClass ? getIrClassVirtualFile((IrClass)sym) :
552601
sym.getParent() instanceof IrClass ? getIrClassVirtualFile((IrClass)sym.getParent()) :
@@ -583,7 +632,7 @@ public void visit(int version, int access, java.lang.String name, java.lang.Stri
583632
};
584633
(new ClassReader(vf.contentsToByteArray())).accept(versionGetter, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
585634

586-
return new TrapClassVersion(versionStore[0] & 0xffff, versionStore[0] >> 16, vf.getTimeStamp(), "kotlin");
635+
return new TrapClassVersion(versionStore[0] & 0xffff, versionStore[0] >> 16, getVirtualFileTimeStamp(vf, log), "kotlin");
587636
}
588637
catch(IllegalAccessException e) {
589638
log.warn("Failed to read class file version information", e);

javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: codeql/javascript-experimental-atm-lib
2-
version: 0.2.1
2+
version: 0.3.1
33
extractor: javascript
44
library: true
55
groups:

javascript/ql/experimental/adaptivethreatmodeling/model/qlpack.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: codeql/javascript-experimental-atm-model
2-
version: 0.1.1
2+
version: 0.2.1
33
groups:
44
- javascript
55
- experimental
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
dependencies:
33
codeql/javascript-experimental-atm-model:
4-
version: 0.1.0
4+
version: 0.2.0
55
compiled: false
66
lockVersion: 1.0.0

javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/qlpack.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ groups:
66
- experimental
77
dependencies:
88
codeql/javascript-experimental-atm-lib: "*"
9-
codeql/javascript-experimental-atm-model: "0.1.0"
9+
codeql/javascript-experimental-atm-model: "0.2.0"

0 commit comments

Comments
 (0)