C++: Fix false positives involving STDIN_FILENO.

This commit is contained in:
Geoffrey White
2021-09-07 13:49:22 +01:00
parent 3ba9e80635
commit e696eaaa2f
3 changed files with 16 additions and 3 deletions

View File

@@ -21,6 +21,12 @@ import semmle.code.cpp.valuenumbering.GlobalValueNumbering
* A function call that sends or receives data over a network.
*/
abstract class NetworkSendRecv extends FunctionCall {
/**
* Gets the expression for the socket or similar object used for sending or
* receiving data.
*/
abstract Expr getSocketExpr();
/**
* Gets the expression for the buffer to be sent from / received into.
*/
@@ -38,6 +44,8 @@ class NetworkSend extends NetworkSendRecv {
.hasGlobalName(["send", "sendto", "sendmsg", "write", "writev", "pwritev", "pwritev2"])
}
override Expr getSocketExpr() { result = this.getArgument(0) }
override Expr getDataExpr() { result = this.getArgument(1) }
}
@@ -52,9 +60,15 @@ class NetworkRecv extends NetworkSendRecv {
])
}
override Expr getSocketExpr() { result = this.getArgument(0) }
override Expr getDataExpr() { result = this.getArgument(1) }
}
from NetworkSendRecv transmission, SensitiveExpr e
where DataFlow::localFlow(DataFlow::exprNode(e), DataFlow::exprNode(transmission.getDataExpr()))
where
DataFlow::localFlow(DataFlow::exprNode(e), DataFlow::exprNode(transmission.getDataExpr())) and
not exists(Zero zero |
DataFlow::localFlow(DataFlow::exprNode(zero), DataFlow::exprNode(transmission.getSocketExpr()))
)
select transmission, e

View File

@@ -5,4 +5,3 @@
| test3.cpp:70:3:70:6 | call to send | test3.cpp:68:21:68:29 | password1 |
| test3.cpp:77:3:77:6 | call to recv | test3.cpp:75:15:75:22 | password |
| test3.cpp:95:3:95:6 | call to read | test3.cpp:95:12:95:19 | password |
| test3.cpp:102:3:102:6 | call to read | test3.cpp:102:12:102:19 | password |

View File

@@ -99,7 +99,7 @@ void test_read()
char password[256];
int fd = STDIN_FILENO;
read(fd, password, 256); // GOOD: `password` is received from stdin, not a network socket [FALSE POSITIVE]
read(fd, password, 256); // GOOD: `password` is received from stdin, not a network socket
}
}