[clang] [-Wunsafe-buffer-usage] Warning Libc functions (PR #101583)

Ziqing Luo via cfe-commits cfe-commits at lists.llvm.org
Wed Aug 28 14:36:45 PDT 2024


================
@@ -0,0 +1,101 @@
+// RUN: %clang_cc1 -std=c++20 -Wno-all -Wunsafe-buffer-usage \
+// RUN:            -verify %s
+
+typedef struct {} FILE;
+void memcpy();
+void __asan_memcpy();
+void strcpy();
+void strcpy_s();
+void wcscpy_s();
+unsigned strlen( const char* str );
+int fprintf( FILE* stream, const char* format, ... );
+int printf( const char* format, ... );
+int sprintf( char* buffer, const char* format, ... );
+int swprintf( char* buffer, const char* format, ... );
+int snprintf( char* buffer, unsigned buf_size, const char* format, ... );
+int snwprintf( char* buffer, unsigned buf_size, const char* format, ... );
+int snwprintf_s( char* buffer, unsigned buf_size, const char* format, ... );
+int vsnprintf( char* buffer, unsigned buf_size, const char* format, ... );
+int sscanf_s(const char * buffer, const char * format, ...);
+int sscanf(const char * buffer, const char * format, ... );
+
+namespace std {
+  template< class InputIt, class OutputIt >
+  OutputIt copy( InputIt first, InputIt last,
+		 OutputIt d_first );
+
+  struct iterator{};
+  template<typename T>
+  struct span {
+    T * ptr;
+    T * data();
+    unsigned size_bytes();
+    unsigned size();
+    iterator begin() const noexcept;
+    iterator end() const noexcept;
+  };
+
+  template<typename T>
+  struct basic_string {
+    T* p;
+    T *c_str();
+    T *data();
+    unsigned size_bytes();
+  };
+
+  typedef basic_string<char> string;
+  typedef basic_string<wchar_t> wstring;
+
+  // C function under std:
+  void memcpy();
+  void strcpy();
+}
+
+void f(char * p, char * q, std::span<char> s, std::span<char> s2) {
+  memcpy();                   // expected-warning{{function 'memcpy' introduces unsafe buffer access}}
+  std::memcpy();              // expected-warning{{function 'memcpy' introduces unsafe buffer access}}
+  __builtin_memcpy(p, q, 64); // expected-warning{{function '__builtin_memcpy' introduces unsafe buffer access}}
+  __builtin___memcpy_chk(p, q, 8, 64);  // expected-warning{{function '__builtin___memcpy_chk' introduces unsafe buffer access}}
+  __asan_memcpy();                      // expected-warning{{function '__asan_memcpy' introduces unsafe buffer access}}
+  strcpy();                   // expected-warning{{function 'strcpy' introduces unsafe buffer access}}
+  std::strcpy();              // expected-warning{{function 'strcpy' introduces unsafe buffer access}}
+  strcpy_s();                 // expected-warning{{function 'strcpy_s' introduces unsafe buffer access}}
+  wcscpy_s();                 // expected-warning{{function 'wcscpy_s' introduces unsafe buffer access}}
+
+
+  /* Test printfs */
+  fprintf((FILE*)p, "%s%d", p, *p);  // expected-warning{{function 'fprintf' introduces unsafe buffer access}} expected-note{{use 'std::string::c_str' or string literal as string pointer to guarantee null-termination}}
+  printf("%s%d", p, *p);  // expected-warning{{function 'printf' introduces unsafe buffer access}} expected-note{{use 'std::string::c_str' or string literal as string pointer to guarantee null-termination}}
+  sprintf(q, "%s%d", "hello", *p); // expected-warning{{function 'sprintf' introduces unsafe buffer access}} expected-note{{change to 'snprintf' for explicit bounds checking}}
+  swprintf(q, "%s%d", "hello", *p); // expected-warning{{function 'swprintf' introduces unsafe buffer access}} expected-note{{change to 'snprintf' for explicit bounds checking}}
+  snprintf(q, 10, "%s%d", "hello", *p); // expected-warning{{function 'snprintf' introduces unsafe buffer access}} expected-note{{buffer pointer and size may not match}}
----------------
ziqingluo-90 wrote:

yep, this case actually happens a lot in our downstream projects.   I planed to handle it in a follow-up patch: https://github.com/llvm/llvm-project/pull/105383

https://github.com/llvm/llvm-project/pull/101583


More information about the cfe-commits mailing list