mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-13 19:24:21 +00:00
[clang][analyzer] Improve StdCLibraryFunctions socket send/recv functions.
The modeling of send, recv, sendmsg, recvmsg, sendto, recvfrom is changed: These functions do not return 0, except if the message length is 0. (In sendmsg, recvmsg the length is not checkable but it is more likely that a message with 0 length is invalid for these functions.) Reviewed By: donat.nagy Differential Revision: https://reviews.llvm.org/D155715
This commit is contained in:
parent
8a5c0ccee2
commit
52ac71f92d
@ -3096,7 +3096,10 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
|
||||
auto Recvfrom =
|
||||
Summary(NoEvalCall)
|
||||
.Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
|
||||
ReturnValueCondition(WithinRange, Range(0, Ssize_tMax))},
|
||||
ReturnValueCondition(WithinRange, Range(1, Ssize_tMax))},
|
||||
ErrnoMustNotBeChecked, GenericSuccessMsg)
|
||||
.Case({ReturnValueCondition(WithinRange, SingleValue(0)),
|
||||
ArgumentCondition(2, WithinRange, SingleValue(0))},
|
||||
ErrnoMustNotBeChecked, GenericSuccessMsg)
|
||||
.Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
|
||||
.ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)))
|
||||
@ -3123,7 +3126,10 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
|
||||
auto Sendto =
|
||||
Summary(NoEvalCall)
|
||||
.Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
|
||||
ReturnValueCondition(WithinRange, Range(0, Ssize_tMax))},
|
||||
ReturnValueCondition(WithinRange, Range(1, Ssize_tMax))},
|
||||
ErrnoMustNotBeChecked, GenericSuccessMsg)
|
||||
.Case({ReturnValueCondition(WithinRange, SingleValue(0)),
|
||||
ArgumentCondition(2, WithinRange, SingleValue(0))},
|
||||
ErrnoMustNotBeChecked, GenericSuccessMsg)
|
||||
.Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
|
||||
.ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)))
|
||||
@ -3161,7 +3167,10 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
|
||||
RetType{Ssize_tTy}),
|
||||
Summary(NoEvalCall)
|
||||
.Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
|
||||
ReturnValueCondition(WithinRange, Range(0, Ssize_tMax))},
|
||||
ReturnValueCondition(WithinRange, Range(1, Ssize_tMax))},
|
||||
ErrnoMustNotBeChecked, GenericSuccessMsg)
|
||||
.Case({ReturnValueCondition(WithinRange, SingleValue(0)),
|
||||
ArgumentCondition(2, WithinRange, SingleValue(0))},
|
||||
ErrnoMustNotBeChecked, GenericSuccessMsg)
|
||||
.Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
|
||||
.ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)))
|
||||
@ -3179,7 +3188,7 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
|
||||
Signature(ArgTypes{IntTy, StructMsghdrPtrTy, IntTy},
|
||||
RetType{Ssize_tTy}),
|
||||
Summary(NoEvalCall)
|
||||
.Case({ReturnValueCondition(WithinRange, Range(0, Ssize_tMax))},
|
||||
.Case({ReturnValueCondition(WithinRange, Range(1, Ssize_tMax))},
|
||||
ErrnoMustNotBeChecked, GenericSuccessMsg)
|
||||
.Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
|
||||
.ArgConstraint(
|
||||
@ -3191,7 +3200,7 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
|
||||
Signature(ArgTypes{IntTy, ConstStructMsghdrPtrTy, IntTy},
|
||||
RetType{Ssize_tTy}),
|
||||
Summary(NoEvalCall)
|
||||
.Case({ReturnValueCondition(WithinRange, Range(0, Ssize_tMax))},
|
||||
.Case({ReturnValueCondition(WithinRange, Range(1, Ssize_tMax))},
|
||||
ErrnoMustNotBeChecked, GenericSuccessMsg)
|
||||
.Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
|
||||
.ArgConstraint(
|
||||
@ -3233,7 +3242,10 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
|
||||
RetType{Ssize_tTy}),
|
||||
Summary(NoEvalCall)
|
||||
.Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)),
|
||||
ReturnValueCondition(WithinRange, Range(0, Ssize_tMax))},
|
||||
ReturnValueCondition(WithinRange, Range(1, Ssize_tMax))},
|
||||
ErrnoMustNotBeChecked, GenericSuccessMsg)
|
||||
.Case({ReturnValueCondition(WithinRange, SingleValue(0)),
|
||||
ArgumentCondition(2, WithinRange, SingleValue(0))},
|
||||
ErrnoMustNotBeChecked, GenericSuccessMsg)
|
||||
.Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg)
|
||||
.ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)))
|
||||
|
@ -141,6 +141,8 @@
|
||||
|
||||
#include "Inputs/std-c-library-functions-POSIX.h"
|
||||
|
||||
void clang_analyzer_eval(int);
|
||||
|
||||
void test_open(void) {
|
||||
open(0, 0); // \
|
||||
// expected-warning{{The 1st argument to 'open' is NULL but should not be NULL}}
|
||||
@ -150,3 +152,56 @@ void test_open_additional_arg(void) {
|
||||
open(0, 0, 0); // \
|
||||
// expected-warning{{The 1st argument to 'open' is NULL but should not be NULL}}
|
||||
}
|
||||
|
||||
void test_recvfrom(int socket, void *restrict buffer, size_t length, int flags,
|
||||
struct sockaddr *restrict address,
|
||||
socklen_t *restrict address_len) {
|
||||
ssize_t Ret = recvfrom(socket, buffer, length, flags, address, address_len);
|
||||
if (Ret == 0)
|
||||
clang_analyzer_eval(length == 0); // expected-warning{{TRUE}}
|
||||
if (Ret > 0)
|
||||
clang_analyzer_eval(length > 0); // expected-warning{{TRUE}}
|
||||
if (Ret == -1)
|
||||
clang_analyzer_eval(length == 0); // expected-warning{{UNKNOWN}}
|
||||
}
|
||||
|
||||
void test_sendto(int socket, const void *message, size_t length, int flags,
|
||||
const struct sockaddr *dest_addr, socklen_t dest_len) {
|
||||
ssize_t Ret = sendto(socket, message, length, flags, dest_addr, dest_len);
|
||||
if (Ret == 0)
|
||||
clang_analyzer_eval(length == 0); // expected-warning{{TRUE}}
|
||||
if (Ret > 0)
|
||||
clang_analyzer_eval(length > 0); // expected-warning{{TRUE}}
|
||||
if (Ret == -1)
|
||||
clang_analyzer_eval(length == 0); // expected-warning{{UNKNOWN}}
|
||||
}
|
||||
|
||||
void test_recv(int sockfd, void *buf, size_t len, int flags) {
|
||||
ssize_t Ret = recv(sockfd, buf, len, flags);
|
||||
if (Ret == 0)
|
||||
clang_analyzer_eval(len == 0); // expected-warning{{TRUE}}
|
||||
if (Ret > 0)
|
||||
clang_analyzer_eval(len > 0); // expected-warning{{TRUE}}
|
||||
if (Ret == -1)
|
||||
clang_analyzer_eval(len == 0); // expected-warning{{UNKNOWN}}
|
||||
}
|
||||
|
||||
void test_send(int sockfd, void *buf, size_t len, int flags) {
|
||||
ssize_t Ret = send(sockfd, buf, len, flags);
|
||||
if (Ret == 0)
|
||||
clang_analyzer_eval(len == 0); // expected-warning{{TRUE}}
|
||||
if (Ret > 0)
|
||||
clang_analyzer_eval(len > 0); // expected-warning{{TRUE}}
|
||||
if (Ret == -1)
|
||||
clang_analyzer_eval(len == 0); // expected-warning{{UNKNOWN}}
|
||||
}
|
||||
|
||||
void test_recvmsg(int sockfd, struct msghdr *msg, int flags) {
|
||||
ssize_t Ret = recvmsg(sockfd, msg, flags);
|
||||
clang_analyzer_eval(Ret != 0); // expected-warning{{TRUE}}
|
||||
}
|
||||
|
||||
void test_sendmsg(int sockfd, const struct msghdr *msg, int flags) {
|
||||
ssize_t Ret = sendmsg(sockfd, msg, flags);
|
||||
clang_analyzer_eval(Ret != 0); // expected-warning{{TRUE}}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user