llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Venkatesh Srinivasan (venk-ks) <details> <summary>Changes</summary> Add `-Wfortify-source` diagnostics for `recv`, `recvfrom`, and their `__builtin_` prefixed aliases when the size argument exceeds the destination buffer size. Part of #<!-- -->142230 Assisted-by: Gemini --- Full diff: https://github.com/llvm/llvm-project/pull/223520.diff 5 Files Affected: - (modified) clang/docs/ReleaseNotes.md (+5) - (modified) clang/include/clang/Basic/BuiltinHeaders.def (+1) - (modified) clang/include/clang/Basic/Builtins.td (+16) - (modified) clang/lib/Sema/SemaChecking.cpp (+12) - (modified) clang/test/Sema/warn-fortify-source.c (+40) ``````````diff diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 043a0ddae2a6c..ad6c20f8322c5 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -236,6 +236,8 @@ features cannot lower the translation-unit ABI level; - Added support for the `__builtin_strlcat` and `__builtin_strlcpy` builtins. +- Added support for the `__builtin_recv` and `__builtin_recvfrom` builtins. + ### New Compiler Flags - New option `-fdefined-pointer-subtraction` added to preserve stable semantics @@ -276,6 +278,9 @@ features cannot lower the translation-unit ABI level; - `-Wfortify-source` now diagnoses when `strlcat`, `__builtin_strlcat`, `strlcpy`, or `__builtin_strlcpy` is called with a size argument larger than the destination buffer. +- `-Wfortify-source` now diagnoses when `recv`, `__builtin_recv`, `recvfrom`, or + `__builtin_recvfrom` is called with a size argument larger than the destination buffer. + - The `cannot overload a member function` diagnostic now describes the previous declaration first, matching the order in which the declarations appear in the source. (#GH219803) diff --git a/clang/include/clang/Basic/BuiltinHeaders.def b/clang/include/clang/Basic/BuiltinHeaders.def index b18e470a8bd25..73a8e387cc4cb 100644 --- a/clang/include/clang/Basic/BuiltinHeaders.def +++ b/clang/include/clang/Basic/BuiltinHeaders.def @@ -38,6 +38,7 @@ HEADER(STDIO_H, "stdio.h") HEADER(STDLIB_H, "stdlib.h") HEADER(STRINGS_H, "strings.h") HEADER(STRING_H, "string.h") +HEADER(SYS_SOCKET_H, "sys/socket.h") HEADER(SYS_STAT_H, "sys/stat.h") HEADER(UNISTD_H, "unistd.h") HEADER(UTILITY, "utility") diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index d148cb4b9101e..7822144cfb988 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -3868,6 +3868,22 @@ def Umask : LibBuiltin<"sys/stat.h"> { let Prototype = ""; // mode_t(mode_t); mode_t is target-specific } +// POSIX sys/socket.h + +def Recv : LibBuiltin<"sys/socket.h"> { + let Spellings = ["recv"]; + let Attributes = [IgnoreSignature, NoThrow]; + let Prototype = ""; + let AddBuiltinPrefixedAlias = 1; +} + +def RecvFrom : LibBuiltin<"sys/socket.h"> { + let Spellings = ["recvfrom"]; + let Attributes = [IgnoreSignature, NoThrow]; + let Prototype = ""; + let AddBuiltinPrefixedAlias = 1; +} + // POSIX pthread.h def PthreadCreate : GNULibBuiltin<"pthread.h"> { diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index ac333d5b66662..f39abc18c6cab 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -1467,6 +1467,18 @@ void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, break; } + case Builtin::BIrecv: + case Builtin::BI__builtin_recv: + case Builtin::BIrecvfrom: + case Builtin::BI__builtin_recvfrom: { + if (TheCall->getNumArgs() < 3) + return; + DiagID = diag::warn_fortify_source_size_mismatch; + SourceSize = Checker.ComputeExplicitObjectSizeArgument(2); + DestinationSize = Checker.ComputeSizeArgument(1); + break; + } + case Builtin::BIbzero: case Builtin::BI__builtin_bzero: case Builtin::BImemcpy: diff --git a/clang/test/Sema/warn-fortify-source.c b/clang/test/Sema/warn-fortify-source.c index 8339efddc5b3e..3e07221e4cafd 100644 --- a/clang/test/Sema/warn-fortify-source.c +++ b/clang/test/Sema/warn-fortify-source.c @@ -9,6 +9,9 @@ // RUN: %clang_cc1 -xc++ -triple x86_64-apple-macosx10.14.0 %s -verify -DUSE_BUILTINS -fexperimental-new-constant-interpreter typedef unsigned long size_t; +typedef long ssize_t; +typedef unsigned int socklen_t; +struct sockaddr; #ifdef __cplusplus extern "C" { @@ -23,6 +26,10 @@ void *memcpy(void *dst, const void *src, size_t c); #endif void bcopy(const void *src, void *dst, size_t n); void bzero(void *dst, size_t n); +ssize_t recv(int, void *, size_t, int); +ssize_t recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *); +ssize_t __builtin_recv(int, void *, size_t, int); +ssize_t __builtin_recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *); #ifdef __cplusplus } @@ -270,6 +277,39 @@ void call_umask(mode_t runtime_mode) { umask(runtime_mode); // no warning, not a constant } +void call_recv(int fd) { + char buf[10]; + recv(fd, buf, 10, 0); + recv(fd, buf, 11, 0); // expected-warning {{'recv' size argument is too large; destination buffer has size 10, but size argument is 11}} + __builtin_recv(fd, buf, 10, 0); + __builtin_recv(fd, buf, 11, 0); // expected-warning {{'recv' size argument is too large; destination buffer has size 10, but size argument is 11}} +} + +void call_recvfrom(int fd) { + char buf[10]; + recvfrom(fd, buf, 10, 0, (struct sockaddr *)0, (socklen_t *)0); + recvfrom(fd, buf, 11, 0, (struct sockaddr *)0, (socklen_t *)0); // expected-warning {{'recvfrom' size argument is too large; destination buffer has size 10, but size argument is 11}} + __builtin_recvfrom(fd, buf, 10, 0, (struct sockaddr *)0, (socklen_t *)0); + __builtin_recvfrom(fd, buf, 11, 0, (struct sockaddr *)0, (socklen_t *)0); // expected-warning {{'recvfrom' size argument is too large; destination buffer has size 10, but size argument is 11}} +} + +void call_recv_subobject(int fd) { + struct { + char first[10]; + char second[20]; + } s; + recv(fd, s.first, 35, 0); // expected-warning {{'recv' size argument is too large; destination buffer has size 30, but size argument is 35}} + __builtin_recv(fd, s.first, 35, 0); // expected-warning {{'recv' size argument is too large; destination buffer has size 30, but size argument is 35}} +} + +void call_recv_runtime(int fd, size_t n) { + char buf[10]; + recv(fd, buf, n, 0); + recvfrom(fd, buf, n, 0, (struct sockaddr *)0, (socklen_t *)0); + __builtin_recv(fd, buf, n, 0); + __builtin_recvfrom(fd, buf, n, 0, (struct sockaddr *)0, (socklen_t *)0); +} + #ifdef __cplusplus template <class> struct S { void mf() const { `````````` </details> https://github.com/llvm/llvm-project/pull/223520 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
