diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp --- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp @@ -1235,9 +1235,8 @@ // read()-like functions that never return more than buffer size. auto FreadSummary = Summary(NoEvalCall) - .Case({ - ReturnValueCondition(LessThanOrEq, ArgNo(2)), - }) + .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)), + ReturnValueCondition(WithinRange, Range(0, SizeMax))}) .ArgConstraint(NotNull(ArgNo(0))) .ArgConstraint(NotNull(ArgNo(3))) .ArgConstraint(BufferSize(/*Buffer=*/ArgNo(0), /*BufSize=*/ArgNo(1), @@ -1764,6 +1763,12 @@ Signature(ArgTypes{ConstCharPtrRestrictTy, CharPtrRestrictTy, SizeTy}, RetType{Ssize_tTy}), Summary(NoEvalCall) + // Upon successful completion, these functions shall return the + // count of bytes placed in the buffer. Otherwise, these functions + // shall return a value of -1, leave the buffer unchanged, and set + // errno to indicate the error. + .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)), + ReturnValueCondition(WithinRange, Range(-1, Ssize_tMax))}) .ArgConstraint(NotNull(ArgNo(0))) .ArgConstraint(NotNull(ArgNo(1))) .ArgConstraint(BufferSize(/*Buffer=*/ArgNo(1), @@ -1779,6 +1784,8 @@ ArgTypes{IntTy, ConstCharPtrRestrictTy, CharPtrRestrictTy, SizeTy}, RetType{Ssize_tTy}), Summary(NoEvalCall) + .Case({ReturnValueCondition(LessThanOrEq, ArgNo(3)), + ReturnValueCondition(WithinRange, Range(-1, Ssize_tMax))}) .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax))) .ArgConstraint(NotNull(ArgNo(1))) .ArgConstraint(NotNull(ArgNo(2))) @@ -1850,6 +1857,7 @@ // constraints which require pointer types for the sockaddr param. auto Accept = Summary(NoEvalCall) + .Case({ReturnValueCondition(WithinRange, Range(-1, IntMax))}) .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax))); if (!addToFunctionSummaryMap( "accept", @@ -1872,6 +1880,7 @@ Signature(ArgTypes{IntTy, ConstStructSockaddrPtrTy, Socklen_tTy}, RetType{IntTy}), Summary(NoEvalCall) + .Case({ReturnValueCondition(WithinRange, Range(-1, 0))}) .ArgConstraint( ArgumentCondition(0, WithinRange, Range(0, IntMax))) .ArgConstraint(NotNull(ArgNo(1))) @@ -1884,6 +1893,7 @@ "bind", Signature(ArgTypes{IntTy, Irrelevant, Socklen_tTy}, RetType{IntTy}), Summary(NoEvalCall) + .Case({ReturnValueCondition(WithinRange, Range(-1, 0))}) .ArgConstraint( ArgumentCondition(0, WithinRange, Range(0, IntMax))) .ArgConstraint( @@ -1897,6 +1907,7 @@ Socklen_tPtrRestrictTy}, RetType{IntTy}), Summary(NoEvalCall) + .Case({ReturnValueCondition(WithinRange, Range(-1, 0))}) .ArgConstraint( ArgumentCondition(0, WithinRange, Range(0, IntMax))) .ArgConstraint(NotNull(ArgNo(1))) @@ -1906,6 +1917,7 @@ Signature(ArgTypes{IntTy, Irrelevant, Socklen_tPtrRestrictTy}, RetType{IntTy}), Summary(NoEvalCall) + .Case({ReturnValueCondition(WithinRange, Range(-1, 0))}) .ArgConstraint( ArgumentCondition(0, WithinRange, Range(0, IntMax)))); @@ -1917,6 +1929,7 @@ Socklen_tPtrRestrictTy}, RetType{IntTy}), Summary(NoEvalCall) + .Case({ReturnValueCondition(WithinRange, Range(-1, 0))}) .ArgConstraint( ArgumentCondition(0, WithinRange, Range(0, IntMax))) .ArgConstraint(NotNull(ArgNo(1))) @@ -1926,6 +1939,7 @@ Signature(ArgTypes{IntTy, Irrelevant, Socklen_tPtrRestrictTy}, RetType{IntTy}), Summary(NoEvalCall) + .Case({ReturnValueCondition(WithinRange, Range(-1, 0))}) .ArgConstraint( ArgumentCondition(0, WithinRange, Range(0, IntMax)))); @@ -1936,6 +1950,7 @@ Signature(ArgTypes{IntTy, ConstStructSockaddrPtrTy, Socklen_tTy}, RetType{IntTy}), Summary(NoEvalCall) + .Case({ReturnValueCondition(WithinRange, Range(-1, 0))}) .ArgConstraint( ArgumentCondition(0, WithinRange, Range(0, IntMax))) .ArgConstraint(NotNull(ArgNo(1))))) @@ -1943,11 +1958,19 @@ "connect", Signature(ArgTypes{IntTy, Irrelevant, Socklen_tTy}, RetType{IntTy}), Summary(NoEvalCall) + .Case({ReturnValueCondition(WithinRange, Range(-1, 0))}) .ArgConstraint( ArgumentCondition(0, WithinRange, Range(0, IntMax)))); auto Recvfrom = Summary(NoEvalCall) + // Upon successful completion, recvfrom() shall return the length of + // the message in bytes. If no messages are available to be received + // and the peer has performed an orderly shutdown, recvfrom() shall + // return 0. Otherwise, the function shall return -1 and set errno + // to indicate the error. + .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)), + ReturnValueCondition(WithinRange, Range(-1, Ssize_tMax))}) .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax))) .ArgConstraint(BufferSize(/*Buffer=*/ArgNo(1), /*BufSize=*/ArgNo(2))); @@ -1971,6 +1994,11 @@ auto Sendto = Summary(NoEvalCall) + // Upon successful completion, sendto() shall return the number of + // bytes sent. Otherwise, -1 shall be returned and errno set to + // indicate the error. + .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)), + ReturnValueCondition(WithinRange, Range(-1, Ssize_tMax))}) .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax))) .ArgConstraint(BufferSize(/*Buffer=*/ArgNo(1), /*BufSize=*/ArgNo(2))); @@ -1991,11 +2019,12 @@ Sendto); // int listen(int sockfd, int backlog); - addToFunctionSummaryMap("listen", - Signature(ArgTypes{IntTy, IntTy}, RetType{IntTy}), - Summary(NoEvalCall) - .ArgConstraint(ArgumentCondition( - 0, WithinRange, Range(0, IntMax)))); + addToFunctionSummaryMap( + "listen", Signature(ArgTypes{IntTy, IntTy}, RetType{IntTy}), + Summary(NoEvalCall) + .Case({ReturnValueCondition(WithinRange, Range(-1, 0))}) + .ArgConstraint( + ArgumentCondition(0, WithinRange, Range(0, IntMax)))); // ssize_t recv(int sockfd, void *buf, size_t len, int flags); addToFunctionSummaryMap( @@ -2003,6 +2032,8 @@ Signature(ArgTypes{IntTy, VoidPtrTy, SizeTy, IntTy}, RetType{Ssize_tTy}), Summary(NoEvalCall) + .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)), + ReturnValueCondition(WithinRange, Range(-1, Ssize_tMax))}) .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax))) .ArgConstraint(BufferSize(/*Buffer=*/ArgNo(1), /*BufSize=*/ArgNo(2)))); @@ -2013,12 +2044,14 @@ getPointerTy(getConstTy(StructMsghdrTy)); // ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags); - addToFunctionSummaryMap("recvmsg", - Signature(ArgTypes{IntTy, StructMsghdrPtrTy, IntTy}, - RetType{Ssize_tTy}), - Summary(NoEvalCall) - .ArgConstraint(ArgumentCondition( - 0, WithinRange, Range(0, IntMax)))); + addToFunctionSummaryMap( + "recvmsg", + Signature(ArgTypes{IntTy, StructMsghdrPtrTy, IntTy}, + RetType{Ssize_tTy}), + Summary(NoEvalCall) + .Case({ReturnValueCondition(WithinRange, Range(-1, Ssize_tMax))}) + .ArgConstraint( + ArgumentCondition(0, WithinRange, Range(0, IntMax)))); // ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags); addToFunctionSummaryMap( @@ -2026,6 +2059,10 @@ Signature(ArgTypes{IntTy, ConstStructMsghdrPtrTy, IntTy}, RetType{Ssize_tTy}), Summary(NoEvalCall) + // Upon successful completion, sendmsg() shall return the number of + // bytes sent. Otherwise, -1 shall be returned and errno set to + // indicate the error. + .Case({ReturnValueCondition(WithinRange, Range(-1, Ssize_tMax))}) .ArgConstraint( ArgumentCondition(0, WithinRange, Range(0, IntMax)))); @@ -2036,6 +2073,7 @@ Signature(ArgTypes{IntTy, IntTy, IntTy, ConstVoidPtrTy, Socklen_tTy}, RetType{IntTy}), Summary(NoEvalCall) + .Case({ReturnValueCondition(WithinRange, Range(-1, 0))}) .ArgConstraint(NotNull(ArgNo(3))) .ArgConstraint( BufferSize(/*Buffer=*/ArgNo(3), /*BufSize=*/ArgNo(4))) @@ -2051,6 +2089,7 @@ Socklen_tPtrRestrictTy}, RetType{IntTy}), Summary(NoEvalCall) + .Case({ReturnValueCondition(WithinRange, Range(-1, 0))}) .ArgConstraint(NotNull(ArgNo(3))) .ArgConstraint(NotNull(ArgNo(4)))); @@ -2060,6 +2099,8 @@ Signature(ArgTypes{IntTy, ConstVoidPtrTy, SizeTy, IntTy}, RetType{Ssize_tTy}), Summary(NoEvalCall) + .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)), + ReturnValueCondition(WithinRange, Range(-1, Ssize_tMax))}) .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax))) .ArgConstraint(BufferSize(/*Buffer=*/ArgNo(1), /*BufSize=*/ArgNo(2)))); @@ -2068,7 +2109,9 @@ addToFunctionSummaryMap( "socketpair", Signature(ArgTypes{IntTy, IntTy, IntTy, IntPtrTy}, RetType{IntTy}), - Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(3)))); + Summary(NoEvalCall) + .Case({ReturnValueCondition(WithinRange, Range(-1, 0))}) + .ArgConstraint(NotNull(ArgNo(3)))); // int getnameinfo(const struct sockaddr *restrict sa, socklen_t salen, // char *restrict node, socklen_t nodelen,