Skip to content

Commit a4ba780

Browse files
committed
[libc++] Enable -Wformat-nonliteral when building libc++
Using user-provided data as a format string is a well known source of security vulnerabilities. For this reason, it is a good idea to compile our code with -Wformat-nonliteral, which basically warns if a non-constant string is used as a format specifier. This is the compiler’s best signal that a format string call may be insecure. I audited the code after adding the warning and made sure that the few places where we used a non-literal string as a format string were not potential security issues. I either disabled the warning locally for those instances or fixed the warning by using a literal. The idea is that after we add the warning to the build, any new use of a non-literal string in a format string will trigger a diagnostic, and we can either get rid of it or disable the warning locally, which is a way of acknowledging that it has been audited. I also looked into enabling it in the test suite, which would perhaps allow finding additional instances of it in our headers, however that is not possible at the moment because Clang doesn't support putting __attribute__((__format__(...))) on variadic templates, which would be needed. rdar://84571685 Differential Revision: https://reviews.llvm.org/D112927
1 parent 56f7da6 commit a4ba780

File tree

2 files changed

+9
-3
lines changed

2 files changed

+9
-3
lines changed

libcxx/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,8 @@ function(cxx_add_warning_flags target)
614614
endif()
615615
target_add_compile_flags_if_supported(${target} PRIVATE -Wextra -W -Wwrite-strings
616616
-Wno-unused-parameter -Wno-long-long
617-
-Werror=return-type -Wextra-semi -Wundef)
617+
-Werror=return-type -Wextra-semi -Wundef
618+
-Wformat-nonliteral)
618619
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
619620
target_add_compile_flags_if_supported(${target} PRIVATE
620621
-Wno-user-defined-literals

libcxx/include/locale

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1486,7 +1486,10 @@ num_put<_CharT, _OutputIterator>::__do_put_integral(iter_type __s, ios_base& __i
14861486
+ ((numeric_limits<_Unsigned>::digits % 3) != 0) // round up
14871487
+ 2; // base prefix + terminating null character
14881488
char __nar[__nbuf];
1489+
#pragma clang diagnostic push
1490+
#pragma clang diagnostic ignored "-Wformat-nonliteral"
14891491
int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1492+
#pragma clang diagnostic pop
14901493
char* __ne = __nar + __nc;
14911494
char* __np = this->__identify_padding(__nar, __ne, __iob);
14921495
// Stage 2 - Widen __nar while adding thousands separators
@@ -1546,6 +1549,8 @@ num_put<_CharT, _OutputIterator>::__do_put_floating_point(iter_type __s, ios_bas
15461549
char __nar[__nbuf];
15471550
char* __nb = __nar;
15481551
int __nc;
1552+
#pragma clang diagnostic push
1553+
#pragma clang diagnostic ignored "-Wformat-nonliteral"
15491554
if (__specify_precision)
15501555
__nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
15511556
(int)__iob.precision(), __v);
@@ -1562,6 +1567,7 @@ num_put<_CharT, _OutputIterator>::__do_put_floating_point(iter_type __s, ios_bas
15621567
__throw_bad_alloc();
15631568
__nbh.reset(__nb);
15641569
}
1570+
#pragma clang diagnostic pop
15651571
char* __ne = __nb + __nc;
15661572
char* __np = this->__identify_padding(__nb, __ne, __iob);
15671573
// Stage 2 - Widen __nar while adding thousands separators
@@ -1606,10 +1612,9 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
16061612
char_type __fl, const void* __v) const
16071613
{
16081614
// Stage 1 - Get pointer in narrow char
1609-
char __fmt[6] = "%p";
16101615
const unsigned __nbuf = 20;
16111616
char __nar[__nbuf];
1612-
int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1617+
int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, "%p", __v);
16131618
char* __ne = __nar + __nc;
16141619
char* __np = this->__identify_padding(__nar, __ne, __iob);
16151620
// Stage 2 - Widen __nar

0 commit comments

Comments
 (0)