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

Reply via email to