gcc 4.9 just got more aggressive and is now exploiting the fact that input pointers to memcpy/memmove cannot be null (even if the size is 0).
This patch adds support to ubsan to check for this UB. Very important since it's already being exploited by gcc.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
Wait a second, won't UBSan handle this automatically if memcpy/memmove are declared with attribute((nonnull)) in the header? Otherwise, is there a change to the standard that imposes these additional constraints on memcpy/memmove?
Wait a second, won't UBSan handle this automatically if memcpy/memmove are
declared with attribute((nonnull)) in the header? Otherwise, is there
a change to the standard that imposes these additional constraints on
memcpy/memmove?
Not really. memcpy/memmove calls are handled by CGBultin and not CGCall.
It's a different code path.
Nuno
Interesting. I think that if we decide to implement such a check, we shouldn't depend on
attributes specified in the headers, so nonnull-attribute is no longer relevant. There are another
kind of compiler builtins which worth extra checks, and which don't even require headers - e.g. behavior of __builtin_ctz(0)
is undefined. I think we should implement another check kind -fsanitize=builtin that would verify arguments of
various builtin functions.
Well, I think in the end they are all in the UB category, so I think they fall in the scope of -fsanitize=undefined.
Nuno
I agree that we should be respecting the __attribute__((nonnull)) on these functions whether or not we emit them as builtin calls; as such, it makes sense to me for this to be under -fsanitize=nonnull-attribute. A couple of minor copy-paste issues and then this looks fine to me, but please wait to make sure that @samsonov is persuaded.
lib/CodeGen/CGBuiltin.cpp | ||
---|---|---|
715 | The 0 here should be a 1. | |
776 | Likewise. |
The 0 here should be a 1.