mirror of
https://github.com/github/codeql.git
synced 2025-12-21 19:26:31 +01:00
C++: Add models-as-data models for ZMQ networking library + wiring.
This commit is contained in:
@@ -41,3 +41,4 @@ private import implementations.SqLite3
|
||||
private import implementations.PostgreSql
|
||||
private import implementations.System
|
||||
private import implementations.StructuredExceptionHandling
|
||||
private import implementations.ZMQ
|
||||
|
||||
36
cpp/ql/lib/semmle/code/cpp/models/implementations/ZMQ.qll
Normal file
36
cpp/ql/lib/semmle/code/cpp/models/implementations/ZMQ.qll
Normal file
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Provides implementation classes modeling the ZeroMQ networking library.
|
||||
*/
|
||||
|
||||
import semmle.code.cpp.models.interfaces.FlowSource
|
||||
|
||||
/**
|
||||
* Remote flow sources.
|
||||
*/
|
||||
private class ZMQSource extends SourceModelCsv {
|
||||
override predicate row(string row) {
|
||||
row =
|
||||
[
|
||||
";;false;zmq_recv;;;Argument[*1];remote",
|
||||
";;false;zmq_recvmsg;;;Argument[*1];remote",
|
||||
";;false;zmq_msg_recv;;;Argument[*0];remote",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remote flow sinks.
|
||||
*/
|
||||
private class ZMQSinks extends SinkModelCsv {
|
||||
override predicate row(string row) {
|
||||
row =
|
||||
[
|
||||
";;false;zmq_send;;;Argument[*1];remote-sink",
|
||||
";;false;zmq_msg_init_data;;;Argument[*1];remote-sink",
|
||||
";;false;zmq_sendmsg;;;Argument[*1];remote-sink",
|
||||
";;false;zmq_msg_send;;;Argument[*0];remote-sink",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: flow into / through zmq_msg_data ?
|
||||
@@ -93,6 +93,9 @@ abstract class RemoteFlowSink extends DataFlow::Node {
|
||||
abstract string getSinkType();
|
||||
}
|
||||
|
||||
/**
|
||||
* A remote flow sink derived from the `RemoteFlowSinkFunction` model.
|
||||
*/
|
||||
private class RemoteParameterSink extends RemoteFlowSink {
|
||||
string sourceType;
|
||||
|
||||
@@ -106,3 +109,12 @@ private class RemoteParameterSink extends RemoteFlowSink {
|
||||
|
||||
override string getSinkType() { result = sourceType }
|
||||
}
|
||||
|
||||
/**
|
||||
* A remote flow sink defined in a CSV model.
|
||||
*/
|
||||
private class RemoteFlowFromCSVSink extends RemoteFlowSink {
|
||||
RemoteFlowFromCSVSink() { sinkNode(this, "remote-sink") }
|
||||
|
||||
override string getSinkType() { result = "remote flow sink" }
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import cpp
|
||||
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||
import semmle.code.cpp.models.interfaces.FlowSource
|
||||
import semmle.code.cpp.models.implementations.Memset
|
||||
import semmle.code.cpp.security.FlowSources
|
||||
import ExposedSystemData::PathGraph
|
||||
import SystemData
|
||||
|
||||
@@ -23,10 +24,12 @@ module ExposedSystemDataConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source = any(SystemData sd).getAnExpr() }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(FunctionCall fc, FunctionInput input, int arg |
|
||||
fc.getTarget().(RemoteFlowSinkFunction).hasRemoteFlowSink(input, _) and
|
||||
input.isParameterDeref(arg) and
|
||||
fc.getArgument(arg).getAChild*() = sink.asIndirectExpr()
|
||||
sink instanceof RemoteFlowSink
|
||||
or
|
||||
// workaround for cases where the sink contains the tainted thing as a child; this could
|
||||
// probably be handled better with taint inheriting content or similar modelling.
|
||||
exists(RemoteFlowSink sinkNode |
|
||||
sinkNode.asIndirectExpr().getAChild*() = sink.asIndirectExpr()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -101,17 +101,17 @@ void test_zmc(void *socket) {
|
||||
zmq_msg_t msg1, msg2;
|
||||
char buffer[1024];
|
||||
|
||||
if (zmq_recv(socket, buffer, sizeof(buffer), 0) >= 0) { // $ MISSING: remote_source
|
||||
if (zmq_recv(socket, buffer, sizeof(buffer), 0) >= 0) { // $ remote_source
|
||||
// ...
|
||||
}
|
||||
|
||||
zmq_msg_init(&msg1);
|
||||
if (zmq_msg_recv(&msg1, socket, 0) >= 0) { // $ MISSING: remote_source
|
||||
if (zmq_msg_recv(&msg1, socket, 0) >= 0) { // $ remote_source
|
||||
// ...
|
||||
}
|
||||
|
||||
zmq_msg_init(&msg2);
|
||||
if (zmq_recvmsg(socket, &msg2, 0) >= 0) { // $ MISSING: remote_source
|
||||
if (zmq_recvmsg(socket, &msg2, 0) >= 0) { // $ remote_source
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ edges
|
||||
| tests2.cpp:111:14:111:15 | *c1 [*ptr] | tests2.cpp:111:14:111:19 | *ptr | provenance | |
|
||||
| tests2.cpp:111:14:111:15 | *c1 [*ptr] | tests2.cpp:111:17:111:19 | *ptr | provenance | |
|
||||
| tests2.cpp:111:17:111:19 | *ptr | tests2.cpp:111:14:111:19 | *ptr | provenance | |
|
||||
| tests2.cpp:134:17:134:22 | *call to getenv | tests2.cpp:138:23:138:34 | *message_data | provenance | |
|
||||
| tests2.cpp:134:17:134:22 | *call to getenv | tests2.cpp:143:34:143:45 | *message_data | provenance | |
|
||||
| tests_sockets.cpp:26:15:26:20 | *call to getenv | tests_sockets.cpp:39:19:39:22 | *path | provenance | |
|
||||
| tests_sockets.cpp:26:15:26:20 | *call to getenv | tests_sockets.cpp:43:20:43:23 | *path | provenance | |
|
||||
| tests_sockets.cpp:63:15:63:20 | *call to getenv | tests_sockets.cpp:76:19:76:22 | *path | provenance | |
|
||||
@@ -36,6 +38,9 @@ nodes
|
||||
| tests2.cpp:111:14:111:15 | *c1 [*ptr] | semmle.label | *c1 [*ptr] |
|
||||
| tests2.cpp:111:14:111:19 | *ptr | semmle.label | *ptr |
|
||||
| tests2.cpp:111:17:111:19 | *ptr | semmle.label | *ptr |
|
||||
| tests2.cpp:134:17:134:22 | *call to getenv | semmle.label | *call to getenv |
|
||||
| tests2.cpp:138:23:138:34 | *message_data | semmle.label | *message_data |
|
||||
| tests2.cpp:143:34:143:45 | *message_data | semmle.label | *message_data |
|
||||
| tests_sockets.cpp:26:15:26:20 | *call to getenv | semmle.label | *call to getenv |
|
||||
| tests_sockets.cpp:39:19:39:22 | *path | semmle.label | *path |
|
||||
| tests_sockets.cpp:43:20:43:23 | *path | semmle.label | *path |
|
||||
@@ -56,6 +61,8 @@ subpaths
|
||||
| tests2.cpp:93:14:93:17 | *str1 | tests2.cpp:91:42:91:45 | *str1 | tests2.cpp:93:14:93:17 | *str1 | This operation exposes system data from $@. | tests2.cpp:91:42:91:45 | *str1 | *str1 |
|
||||
| tests2.cpp:102:14:102:15 | *pw | tests2.cpp:101:8:101:15 | *call to getpwuid | tests2.cpp:102:14:102:15 | *pw | This operation exposes system data from $@. | tests2.cpp:101:8:101:15 | *call to getpwuid | *call to getpwuid |
|
||||
| tests2.cpp:111:14:111:19 | *ptr | tests2.cpp:109:12:109:17 | *call to getenv | tests2.cpp:111:14:111:19 | *ptr | This operation exposes system data from $@. | tests2.cpp:109:12:109:17 | *call to getenv | *call to getenv |
|
||||
| tests2.cpp:138:23:138:34 | *message_data | tests2.cpp:134:17:134:22 | *call to getenv | tests2.cpp:138:23:138:34 | *message_data | This operation exposes system data from $@. | tests2.cpp:134:17:134:22 | *call to getenv | *call to getenv |
|
||||
| tests2.cpp:143:34:143:45 | *message_data | tests2.cpp:134:17:134:22 | *call to getenv | tests2.cpp:143:34:143:45 | *message_data | This operation exposes system data from $@. | tests2.cpp:134:17:134:22 | *call to getenv | *call to getenv |
|
||||
| tests_sockets.cpp:39:19:39:22 | *path | tests_sockets.cpp:26:15:26:20 | *call to getenv | tests_sockets.cpp:39:19:39:22 | *path | This operation exposes system data from $@. | tests_sockets.cpp:26:15:26:20 | *call to getenv | *call to getenv |
|
||||
| tests_sockets.cpp:43:20:43:23 | *path | tests_sockets.cpp:26:15:26:20 | *call to getenv | tests_sockets.cpp:43:20:43:23 | *path | This operation exposes system data from $@. | tests_sockets.cpp:26:15:26:20 | *call to getenv | *call to getenv |
|
||||
| tests_sockets.cpp:76:19:76:22 | *path | tests_sockets.cpp:63:15:63:20 | *call to getenv | tests_sockets.cpp:76:19:76:22 | *path | This operation exposes system data from $@. | tests_sockets.cpp:63:15:63:20 | *call to getenv | *call to getenv |
|
||||
|
||||
@@ -135,16 +135,16 @@ void test_zmq(void *remoteSocket)
|
||||
message_len = strlen(message_data) + 1;
|
||||
|
||||
// send as data
|
||||
if (zmq_send(socket, message_data, message_len, 0) >= 0) { // BAD: outputs HOME environment variable [NOT DETECTED]
|
||||
if (zmq_send(socket, message_data, message_len, 0) >= 0) { // BAD: outputs HOME environment variable
|
||||
// ...
|
||||
}
|
||||
|
||||
// send as message
|
||||
if (zmq_msg_init_data(&message, message_data, message_len, 0, 0)) {
|
||||
if (zmq_sendmsg(remoteSocket, &message, message_len)) { // BAD: outputs HOME environment variable [NOT DETECTED]
|
||||
if (zmq_sendmsg(remoteSocket, &message, message_len)) { // BAD: outputs HOME environment variable (detected above)
|
||||
// ...
|
||||
}
|
||||
if (zmq_msg_send(&message, remoteSocket, message_len)) { // BAD: outputs HOME environment variable [NOT DETECTED]
|
||||
if (zmq_msg_send(&message, remoteSocket, message_len)) { // BAD: outputs HOME environment variable (detected above)
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user