Page MenuHomePhabricator

[libc++] Enable -Wformat-nonliteral when building libc++
ClosedPublic

Authored by ldionne on Nov 1 2021, 7:06 AM.

Details

Summary

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 disabled the warning locally for those
instances. 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

Diff Detail

Event Timeline

ldionne created this revision.Nov 1 2021, 7:06 AM
ldionne requested review of this revision.Nov 1 2021, 7:06 AM
Herald added a project: Restricted Project. · View Herald TranscriptNov 1 2021, 7:06 AM
Herald added a reviewer: Restricted Project. · View Herald Transcript
Quuxplusone accepted this revision as: Quuxplusone.Nov 1 2021, 7:45 AM
Quuxplusone added a subscriber: Quuxplusone.

because Clang doesn't support putting __attribute__((format(...))) on variadic templates

D112579 is related.

libcxx/include/locale
1617

Why on earth is this not just s/__fmt/"%p"/?

ldionne updated this revision to Diff 385802.Nov 9 2021, 6:45 AM
ldionne marked an inline comment as done.

Address review comment

ldionne accepted this revision as: Restricted Project.Nov 9 2021, 10:17 AM
This revision is now accepted and ready to land.Nov 9 2021, 10:17 AM
This revision was automatically updated to reflect the committed changes.

Hi,

I see a whole bunch of warnings like this with this patch:

/repo/uabelho/llvm-dev2/llvm/build-all-builtins/runtimes/runtimes-i386-unknown-linux-gnu-bins/compiler-rt/lib/fuzzer/libcxx_fuzzer_i386/include/c++/v1/__bsd_locale_fallbacks.h:116:37: warning: format string is not a string literal [-Wformat-nonliteral]
    int __res = vsnprintf(__s, __n, __format, __va);
                                    ^~~~~~~~
/repo/uabelho/llvm-dev2/llvm/build-all-builtins/runtimes/runtimes-i386-unknown-linux-gnu-bins/compiler-rt/lib/fuzzer/libcxx_fuzzer_i386/include/c++/v1/__bsd_locale_fallbacks.h:126:32: warning: format string is not a string literal [-Wformat-nonliteral]
    int __res = vasprintf(__s, __format, __va);
                               ^~~~~~~~
/repo/uabelho/llvm-dev2/llvm/build-all-builtins/runtimes/runtimes-i386-unknown-linux-gnu-bins/compiler-rt/lib/fuzzer/libcxx_fuzzer_i386/include/c++/v1/__bsd_locale_fallbacks.h:136:30: warning: format string is not a string literal [-Wformat-nonliteral]
    int __res = vsscanf(__s, __format, __va);
                             ^~~~~~~~
3 warnings generated.

Both with clang 8 and gcc 9.3

Hi,

I see a whole bunch of warnings like this with this patch:

/repo/uabelho/llvm-dev2/llvm/build-all-builtins/runtimes/runtimes-i386-unknown-linux-gnu-bins/compiler-rt/lib/fuzzer/libcxx_fuzzer_i386/include/c++/v1/__bsd_locale_fallbacks.h:116:37: warning: format string is not a string literal [-Wformat-nonliteral]
    int __res = vsnprintf(__s, __n, __format, __va);
                                    ^~~~~~~~
/repo/uabelho/llvm-dev2/llvm/build-all-builtins/runtimes/runtimes-i386-unknown-linux-gnu-bins/compiler-rt/lib/fuzzer/libcxx_fuzzer_i386/include/c++/v1/__bsd_locale_fallbacks.h:126:32: warning: format string is not a string literal [-Wformat-nonliteral]
    int __res = vasprintf(__s, __format, __va);
                               ^~~~~~~~
/repo/uabelho/llvm-dev2/llvm/build-all-builtins/runtimes/runtimes-i386-unknown-linux-gnu-bins/compiler-rt/lib/fuzzer/libcxx_fuzzer_i386/include/c++/v1/__bsd_locale_fallbacks.h:136:30: warning: format string is not a string literal [-Wformat-nonliteral]
    int __res = vsscanf(__s, __format, __va);
                             ^~~~~~~~
3 warnings generated.

Both with clang 8 and gcc 9.3

I put up
https://reviews.llvm.org/D113876
to silence the warnings

Hi,

I see a whole bunch of warnings like this with this patch:

/repo/uabelho/llvm-dev2/llvm/build-all-builtins/runtimes/runtimes-i386-unknown-linux-gnu-bins/compiler-rt/lib/fuzzer/libcxx_fuzzer_i386/include/c++/v1/__bsd_locale_fallbacks.h:116:37: warning: format string is not a string literal [-Wformat-nonliteral]
    int __res = vsnprintf(__s, __n, __format, __va);
                                    ^~~~~~~~
/repo/uabelho/llvm-dev2/llvm/build-all-builtins/runtimes/runtimes-i386-unknown-linux-gnu-bins/compiler-rt/lib/fuzzer/libcxx_fuzzer_i386/include/c++/v1/__bsd_locale_fallbacks.h:126:32: warning: format string is not a string literal [-Wformat-nonliteral]
    int __res = vasprintf(__s, __format, __va);
                               ^~~~~~~~
/repo/uabelho/llvm-dev2/llvm/build-all-builtins/runtimes/runtimes-i386-unknown-linux-gnu-bins/compiler-rt/lib/fuzzer/libcxx_fuzzer_i386/include/c++/v1/__bsd_locale_fallbacks.h:136:30: warning: format string is not a string literal [-Wformat-nonliteral]
    int __res = vsscanf(__s, __format, __va);
                             ^~~~~~~~
3 warnings generated.

Both with clang 8 and gcc 9.3

I put up
https://reviews.llvm.org/D113876
to silence the warnings

Yup, I'm seeing them too on the build bots. I missed them cause I was only building on Darwin, and that header isn't used on Darwin. Also since those are just warnings they are not failing the build, so CI passed. Looking at your patch now.