Skip to content

Commit b40b319

Browse files
author
Gabor Marton
committed
[analyzer][StdLibraryFunctionsChecker] Add return value constraint to functions with BufferSize
Differential Revision: https://reviews.llvm.org/D92474
1 parent 3900ec6 commit b40b319

File tree

1 file changed

+45
-10
lines changed

1 file changed

+45
-10
lines changed

clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,10 @@ class StdLibraryFunctionsChecker
457457
CaseConstraints.push_back(std::move(CS));
458458
return *this;
459459
}
460+
Summary &Case(const ConstraintSet &CS) {
461+
CaseConstraints.push_back(CS);
462+
return *this;
463+
}
460464
Summary &ArgConstraint(ValueConstraintPtr VC) {
461465
assert(VC->getArgNo() != Ret &&
462466
"Arg constraint should not refer to the return value");
@@ -1235,9 +1239,8 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
12351239
// read()-like functions that never return more than buffer size.
12361240
auto FreadSummary =
12371241
Summary(NoEvalCall)
1238-
.Case({
1239-
ReturnValueCondition(LessThanOrEq, ArgNo(2)),
1240-
})
1242+
.Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
1243+
ReturnValueCondition(WithinRange, Range(0, SizeMax))})
12411244
.ArgConstraint(NotNull(ArgNo(0)))
12421245
.ArgConstraint(NotNull(ArgNo(3)))
12431246
.ArgConstraint(BufferSize(/*Buffer=*/ArgNo(0), /*BufSize=*/ArgNo(1),
@@ -1764,6 +1767,8 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
17641767
Signature(ArgTypes{ConstCharPtrRestrictTy, CharPtrRestrictTy, SizeTy},
17651768
RetType{Ssize_tTy}),
17661769
Summary(NoEvalCall)
1770+
.Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
1771+
ReturnValueCondition(WithinRange, Range(-1, Ssize_tMax))})
17671772
.ArgConstraint(NotNull(ArgNo(0)))
17681773
.ArgConstraint(NotNull(ArgNo(1)))
17691774
.ArgConstraint(BufferSize(/*Buffer=*/ArgNo(1),
@@ -1779,6 +1784,8 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
17791784
ArgTypes{IntTy, ConstCharPtrRestrictTy, CharPtrRestrictTy, SizeTy},
17801785
RetType{Ssize_tTy}),
17811786
Summary(NoEvalCall)
1787+
.Case({ReturnValueCondition(LessThanOrEq, ArgNo(3)),
1788+
ReturnValueCondition(WithinRange, Range(-1, Ssize_tMax))})
17821789
.ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)))
17831790
.ArgConstraint(NotNull(ArgNo(1)))
17841791
.ArgConstraint(NotNull(ArgNo(2)))
@@ -1842,6 +1849,9 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
18421849
Optional<QualType> Socklen_tPtrRestrictTy = getRestrictTy(Socklen_tPtrTy);
18431850
Optional<RangeInt> Socklen_tMax = getMaxValue(Socklen_tTy);
18441851

1852+
const auto ReturnsZeroOrMinusOne =
1853+
ConstraintSet{ReturnValueCondition(WithinRange, Range(-1, 0))};
1854+
18451855
// In 'socket.h' of some libc implementations with C99, sockaddr parameter
18461856
// is a transparent union of the underlying sockaddr_ family of pointers
18471857
// instead of being a pointer to struct sockaddr. In these cases, the
@@ -1850,6 +1860,7 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
18501860
// constraints which require pointer types for the sockaddr param.
18511861
auto Accept =
18521862
Summary(NoEvalCall)
1863+
.Case({ReturnValueCondition(WithinRange, Range(-1, IntMax))})
18531864
.ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)));
18541865
if (!addToFunctionSummaryMap(
18551866
"accept",
@@ -1872,6 +1883,7 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
18721883
Signature(ArgTypes{IntTy, ConstStructSockaddrPtrTy, Socklen_tTy},
18731884
RetType{IntTy}),
18741885
Summary(NoEvalCall)
1886+
.Case(ReturnsZeroOrMinusOne)
18751887
.ArgConstraint(
18761888
ArgumentCondition(0, WithinRange, Range(0, IntMax)))
18771889
.ArgConstraint(NotNull(ArgNo(1)))
@@ -1884,6 +1896,7 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
18841896
"bind",
18851897
Signature(ArgTypes{IntTy, Irrelevant, Socklen_tTy}, RetType{IntTy}),
18861898
Summary(NoEvalCall)
1899+
.Case(ReturnsZeroOrMinusOne)
18871900
.ArgConstraint(
18881901
ArgumentCondition(0, WithinRange, Range(0, IntMax)))
18891902
.ArgConstraint(
@@ -1897,6 +1910,7 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
18971910
Socklen_tPtrRestrictTy},
18981911
RetType{IntTy}),
18991912
Summary(NoEvalCall)
1913+
.Case(ReturnsZeroOrMinusOne)
19001914
.ArgConstraint(
19011915
ArgumentCondition(0, WithinRange, Range(0, IntMax)))
19021916
.ArgConstraint(NotNull(ArgNo(1)))
@@ -1906,6 +1920,7 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
19061920
Signature(ArgTypes{IntTy, Irrelevant, Socklen_tPtrRestrictTy},
19071921
RetType{IntTy}),
19081922
Summary(NoEvalCall)
1923+
.Case(ReturnsZeroOrMinusOne)
19091924
.ArgConstraint(
19101925
ArgumentCondition(0, WithinRange, Range(0, IntMax))));
19111926

@@ -1917,6 +1932,7 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
19171932
Socklen_tPtrRestrictTy},
19181933
RetType{IntTy}),
19191934
Summary(NoEvalCall)
1935+
.Case(ReturnsZeroOrMinusOne)
19201936
.ArgConstraint(
19211937
ArgumentCondition(0, WithinRange, Range(0, IntMax)))
19221938
.ArgConstraint(NotNull(ArgNo(1)))
@@ -1926,6 +1942,7 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
19261942
Signature(ArgTypes{IntTy, Irrelevant, Socklen_tPtrRestrictTy},
19271943
RetType{IntTy}),
19281944
Summary(NoEvalCall)
1945+
.Case(ReturnsZeroOrMinusOne)
19291946
.ArgConstraint(
19301947
ArgumentCondition(0, WithinRange, Range(0, IntMax))));
19311948

@@ -1936,18 +1953,22 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
19361953
Signature(ArgTypes{IntTy, ConstStructSockaddrPtrTy, Socklen_tTy},
19371954
RetType{IntTy}),
19381955
Summary(NoEvalCall)
1956+
.Case(ReturnsZeroOrMinusOne)
19391957
.ArgConstraint(
19401958
ArgumentCondition(0, WithinRange, Range(0, IntMax)))
19411959
.ArgConstraint(NotNull(ArgNo(1)))))
19421960
addToFunctionSummaryMap(
19431961
"connect",
19441962
Signature(ArgTypes{IntTy, Irrelevant, Socklen_tTy}, RetType{IntTy}),
19451963
Summary(NoEvalCall)
1964+
.Case(ReturnsZeroOrMinusOne)
19461965
.ArgConstraint(
19471966
ArgumentCondition(0, WithinRange, Range(0, IntMax))));
19481967

19491968
auto Recvfrom =
19501969
Summary(NoEvalCall)
1970+
.Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
1971+
ReturnValueCondition(WithinRange, Range(-1, Ssize_tMax))})
19511972
.ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)))
19521973
.ArgConstraint(BufferSize(/*Buffer=*/ArgNo(1),
19531974
/*BufSize=*/ArgNo(2)));
@@ -1971,6 +1992,8 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
19711992

19721993
auto Sendto =
19731994
Summary(NoEvalCall)
1995+
.Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
1996+
ReturnValueCondition(WithinRange, Range(-1, Ssize_tMax))})
19741997
.ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)))
19751998
.ArgConstraint(BufferSize(/*Buffer=*/ArgNo(1),
19761999
/*BufSize=*/ArgNo(2)));
@@ -1994,6 +2017,7 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
19942017
addToFunctionSummaryMap("listen",
19952018
Signature(ArgTypes{IntTy, IntTy}, RetType{IntTy}),
19962019
Summary(NoEvalCall)
2020+
.Case(ReturnsZeroOrMinusOne)
19972021
.ArgConstraint(ArgumentCondition(
19982022
0, WithinRange, Range(0, IntMax))));
19992023

@@ -2003,6 +2027,8 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
20032027
Signature(ArgTypes{IntTy, VoidPtrTy, SizeTy, IntTy},
20042028
RetType{Ssize_tTy}),
20052029
Summary(NoEvalCall)
2030+
.Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
2031+
ReturnValueCondition(WithinRange, Range(-1, Ssize_tMax))})
20062032
.ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)))
20072033
.ArgConstraint(BufferSize(/*Buffer=*/ArgNo(1),
20082034
/*BufSize=*/ArgNo(2))));
@@ -2013,19 +2039,22 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
20132039
getPointerTy(getConstTy(StructMsghdrTy));
20142040

20152041
// ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
2016-
addToFunctionSummaryMap("recvmsg",
2017-
Signature(ArgTypes{IntTy, StructMsghdrPtrTy, IntTy},
2018-
RetType{Ssize_tTy}),
2019-
Summary(NoEvalCall)
2020-
.ArgConstraint(ArgumentCondition(
2021-
0, WithinRange, Range(0, IntMax))));
2042+
addToFunctionSummaryMap(
2043+
"recvmsg",
2044+
Signature(ArgTypes{IntTy, StructMsghdrPtrTy, IntTy},
2045+
RetType{Ssize_tTy}),
2046+
Summary(NoEvalCall)
2047+
.Case({ReturnValueCondition(WithinRange, Range(-1, Ssize_tMax))})
2048+
.ArgConstraint(
2049+
ArgumentCondition(0, WithinRange, Range(0, IntMax))));
20222050

20232051
// ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
20242052
addToFunctionSummaryMap(
20252053
"sendmsg",
20262054
Signature(ArgTypes{IntTy, ConstStructMsghdrPtrTy, IntTy},
20272055
RetType{Ssize_tTy}),
20282056
Summary(NoEvalCall)
2057+
.Case({ReturnValueCondition(WithinRange, Range(-1, Ssize_tMax))})
20292058
.ArgConstraint(
20302059
ArgumentCondition(0, WithinRange, Range(0, IntMax))));
20312060

@@ -2036,6 +2065,7 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
20362065
Signature(ArgTypes{IntTy, IntTy, IntTy, ConstVoidPtrTy, Socklen_tTy},
20372066
RetType{IntTy}),
20382067
Summary(NoEvalCall)
2068+
.Case(ReturnsZeroOrMinusOne)
20392069
.ArgConstraint(NotNull(ArgNo(3)))
20402070
.ArgConstraint(
20412071
BufferSize(/*Buffer=*/ArgNo(3), /*BufSize=*/ArgNo(4)))
@@ -2051,6 +2081,7 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
20512081
Socklen_tPtrRestrictTy},
20522082
RetType{IntTy}),
20532083
Summary(NoEvalCall)
2084+
.Case(ReturnsZeroOrMinusOne)
20542085
.ArgConstraint(NotNull(ArgNo(3)))
20552086
.ArgConstraint(NotNull(ArgNo(4))));
20562087

@@ -2060,6 +2091,8 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
20602091
Signature(ArgTypes{IntTy, ConstVoidPtrTy, SizeTy, IntTy},
20612092
RetType{Ssize_tTy}),
20622093
Summary(NoEvalCall)
2094+
.Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
2095+
ReturnValueCondition(WithinRange, Range(-1, Ssize_tMax))})
20632096
.ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)))
20642097
.ArgConstraint(BufferSize(/*Buffer=*/ArgNo(1),
20652098
/*BufSize=*/ArgNo(2))));
@@ -2068,7 +2101,9 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
20682101
addToFunctionSummaryMap(
20692102
"socketpair",
20702103
Signature(ArgTypes{IntTy, IntTy, IntTy, IntPtrTy}, RetType{IntTy}),
2071-
Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(3))));
2104+
Summary(NoEvalCall)
2105+
.Case(ReturnsZeroOrMinusOne)
2106+
.ArgConstraint(NotNull(ArgNo(3))));
20722107

20732108
// int getnameinfo(const struct sockaddr *restrict sa, socklen_t salen,
20742109
// char *restrict node, socklen_t nodelen,

0 commit comments

Comments
 (0)