[clang] [-Wunsafe-buffer-usage] Warning Libc functions (PR #101583)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 3 10:54:53 PDT 2024
================
@@ -0,0 +1,106 @@
+// 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 a string literal as string pointer to guarantee null-termination}}
+ printf("%s%d", // expected-warning{{function 'printf' introduces unsafe buffer access}}
+ p, // expected-note{{use 'std::string::c_str' or a string literal as string pointer to guarantee null-termination}} note attached to the unsafe argument
+ *p);
+ 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}}
+ snprintf(s.data(), s2.size(), "%s%d", "hello", *p); // expected-warning{{function 'snprintf' introduces unsafe buffer access}} expected-note{{buffer pointer and size may not match}}
+ snwprintf(s.data(), s2.size(), "%s%d", "hello", *p); // expected-warning{{function 'snwprintf' introduces unsafe buffer access}} expected-note{{buffer pointer and size may not match}}
+ snwprintf_s( // expected-warning{{function 'snwprintf_s' introduces unsafe buffer access}}
+ s.data(), // expected-note{{buffer pointer and size may not match}} // note attached to the buffer
+ s2.size(),
+ "%s%d", "hello", *p);
+ vsnprintf(s.data(), s.size_bytes(), "%s%d", "hello", *p); // expected-warning{{function 'vsnprintf' introduces unsafe buffer access}} expected-note{{do not use va_list, which cannot be checked at compile-time for bounds safety}}
----------------
jkorous-apple wrote:
Mentioning compile-time bounds safety to the users feels like too much details at this point and too high bar for what we expect them to understand about the programming model.
Can we just say:
warning: function 'vsnprintf' is unsafe
note: 'va_list' is unsafe
https://github.com/llvm/llvm-project/pull/101583
More information about the cfe-commits
mailing list