This is an archive of the discontinued LLVM Phabricator instance.

sanitizer_common: prepare for enabling format string checking
ClosedPublic

Authored by dvyukov on Aug 12 2021, 11:17 AM.

Details

Summary

The attribute((format)) was added somewhere in 2012,
the lost during refactoring, then re-added in 2014 but
to te source files, which is a no-op.
Move it back to header files so that it actually takes effect.
But over the past 7 years we've accumulated whole lot of
format string bugs of different types, so disable the warning
with -Wno-format for now for incremental clean up.

Among the bugs that it warns about are all kinds of bad things:

  • wrong sizes of arguments
  • missing/excessive arguments
  • printing wrong things (e.g. *ptr instead of ptr)
  • completely messed up format strings
  • security issues where external string is used as format

Diff Detail

Event Timeline

dvyukov created this revision.Aug 12 2021, 11:17 AM
dvyukov requested review of this revision.Aug 12 2021, 11:17 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 12 2021, 11:17 AM
Herald added a subscriber: Restricted Project. · View Herald Transcript
vitalybuka accepted this revision.Aug 12 2021, 12:22 PM
This revision is now accepted and ready to land.Aug 12 2021, 12:22 PM
This revision was landed with ongoing or failed builds.Aug 13 2021, 4:44 AM
This revision was automatically updated to reflect the committed changes.

There is a nasty issue: it seems we can't print uptr at all.
%zu give this warning on 32-bit platforms:

/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_tls_get_addr.cpp:140:22: error: format specifies type 'size_t' (aka 'unsigned int') but the argument has type '__sanitizer::uptr' (aka 'unsigned long') [-Werror,-Wformat]
          tls_beg, tls_size);
                   ^~~~~~~~

https://lab.llvm.org/buildbot/#/builders/37/builds/6061

But we can't use %lu either because on windows long is 32-bits and we define uptr to long long. And we obviously can't use %llu for uptr as well.

Maybe we should define uptr to unsigned int on 32-bits to match size_t? But I am not sure if it will cause more problems somewhere else...

Or we can disable -Wformat on 32-bits? Or on windows?

But we can't use %lu either because on windows long is 32-bits and we define uptr to long long. And we obviously can't use %llu for uptr as well.

Maybe we should define uptr to unsigned int on 32-bits to match size_t? But I am not sure if it will cause more problems somewhere else...

Or we can disable -Wformat on 32-bits? Or on windows?

If it's impossible to have one print-format, probably the only way around is to make a define like

#ifdef ...special builds...
#define UPTR_FMT ...
#elif ....
... 
#else
#define UPTR_FMT "%zu"
#endif

And then just

Printf("Foo bar " UPTR_FMT " baz", ...);

It's a bit more verbose, but would allow not having to disable warnings.

However, the simple and pragmatic solution would probably just be disabling these warnings on 32-bit. Unless they actually are bugs?

But we can't use %lu either because on windows long is 32-bits and we define uptr to long long. And we obviously can't use %llu for uptr as well.

Maybe we should define uptr to unsigned int on 32-bits to match size_t? But I am not sure if it will cause more problems somewhere else...

Or we can disable -Wformat on 32-bits? Or on windows?

If it's impossible to have one print-format, probably the only way around is to make a define like

#ifdef ...special builds...
#define UPTR_FMT ...
#elif ....
... 
#else
#define UPTR_FMT "%zu"
#endif

And then just

Printf("Foo bar " UPTR_FMT " baz", ...);

I don't want to live in this world.

It's a bit more verbose, but would allow not having to disable warnings.

However, the simple and pragmatic solution would probably just be disabling these warnings on 32-bit. Unless they actually are bugs?

Disabling the warning for 32-bits is the only practical solution I see...

dvyukov added a subscriber: fmayer.Aug 13 2021, 9:15 AM

FTR @fmayer sent D108042 to fix this.