diff --git a/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp index 8138c8411fb26..54c3f6dcdddaf 100644 --- a/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp @@ -621,6 +621,7 @@ void GenericTaintChecker::initTaintRules(CheckerContext &C) const { {{{"getlogin_r"}}, TR::Source({{0}})}, // Props + {{{"accept"}}, TR::Prop({{0}}, {{ReturnValueIndex}})}, {{{"atoi"}}, TR::Prop({{0}}, {{ReturnValueIndex}})}, {{{"atol"}}, TR::Prop({{0}}, {{ReturnValueIndex}})}, {{{"atoll"}}, TR::Prop({{0}}, {{ReturnValueIndex}})}, diff --git a/clang/test/Analysis/taint-generic.c b/clang/test/Analysis/taint-generic.c index b7906d201e4fa..e58b9c71a7578 100644 --- a/clang/test/Analysis/taint-generic.c +++ b/clang/test/Analysis/taint-generic.c @@ -544,6 +544,10 @@ void testFread(const char *fname, int *buffer, size_t size, size_t count) { } ssize_t recv(int sockfd, void *buf, size_t len, int flags); +int accept(int fd, struct sockaddr *addr, socklen_t *addrlen); +int bind(int fd, const struct sockaddr *addr, socklen_t addrlen); +int listen(int fd, int backlog); + void testRecv(int *buf, size_t len, int flags) { int fd; scanf("%d", &fd); // fake a tainted a file descriptor @@ -1107,3 +1111,10 @@ void testProctitle2(char *real_argv[]) { setproctitle_init(1, argv, 0); // expected-warning {{Untrusted data is passed to a user-defined sink}} setproctitle_init(1, real_argv, argv); // expected-warning {{Untrusted data is passed to a user-defined sink}} } + +void testAcceptPropagates() { + int listenSocket = socket(2, 1, 6); + clang_analyzer_isTainted_int(listenSocket); // expected-warning {{YES}} + int acceptSocket = accept(listenSocket, 0, 0); + clang_analyzer_isTainted_int(acceptSocket); // expected-warning {{YES}} +}