Skip to content

Commit 6501647

Browse files
authored
[StaticAnalyzer] Relax the pre-condition of 'setsockopt' (#130683)
For the unix function `int setsockopt(int, int, int, const void *, socklen_t);`, the last two parameters represent a buffer and a size. In case the size is zero, buffer can be null. Previously, the hard-coded pre-condition requires the buffer to never be null, which can cause false positives. (rdar://146678142)
1 parent f10a870 commit 6501647

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1797,7 +1797,8 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
17971797
auto IsNull = [&](ArgNo ArgN) {
17981798
return std::make_shared<NotNullConstraint>(ArgN, false);
17991799
};
1800-
auto NotNullBuffer = [&](ArgNo ArgN, ArgNo SizeArg1N, ArgNo SizeArg2N) {
1800+
auto NotNullBuffer = [&](ArgNo ArgN, ArgNo SizeArg1N,
1801+
std::optional<ArgNo> SizeArg2N = std::nullopt) {
18011802
return std::make_shared<NotNullBufferConstraint>(ArgN, SizeArg1N,
18021803
SizeArg2N);
18031804
};
@@ -3365,7 +3366,7 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
33653366
Summary(NoEvalCall)
33663367
.Case(ReturnsZero, ErrnoMustNotBeChecked, GenericSuccessMsg)
33673368
.Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
3368-
.ArgConstraint(NotNull(ArgNo(3)))
3369+
.ArgConstraint(NotNullBuffer(ArgNo(3), ArgNo(4)))
33693370
.ArgConstraint(
33703371
BufferSize(/*Buffer=*/ArgNo(3), /*BufSize=*/ArgNo(4)))
33713372
.ArgConstraint(

clang/test/Analysis/std-c-library-functions-POSIX.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,3 +237,14 @@ void test_readlinkat_bufsize_zero(int fd, char *Buf, size_t Bufsize) {
237237
else
238238
clang_analyzer_eval(Bufsize == 0); // expected-warning{{UNKNOWN}}
239239
}
240+
241+
void test_setsockopt_bufptr_null(int x) {
242+
char buf[10] = {0};
243+
244+
setsockopt(1, 2, 3, 0, 0);
245+
setsockopt(1, 2, 3, buf, 10);
246+
if (x)
247+
setsockopt(1, 2, 3, buf, 11); // expected-warning{{The 4th argument to 'setsockopt' is a buffer with size 10 but should be a buffer with size equal to or greater than the value of the 5th argument (which is 11)}}
248+
else
249+
setsockopt(1, 2, 3, 0, 10); // expected-warning{{The 4th argument to 'setsockopt' is NULL but should not be NULL}}
250+
}

0 commit comments

Comments
 (0)