This is an archive of the discontinued LLVM Phabricator instance.

[scudo] Workaround for uninitialized Bionic globals
ClosedPublic

Authored by cryptoad on Nov 27 2017, 9:32 AM.

Details

Summary

Bionic doesn't initialize its globals early enough. This causes issues when
trying to access them from a preinit_array (b/25751302) or from another
constructor called before the libc one (b/68046352). __progname is initialized
after the other globals, so we can check its value to know if calling
getauxval is safe.

Event Timeline

cryptoad created this revision.Nov 27 2017, 9:32 AM
alekseyshl accepted this revision.Nov 27 2017, 11:22 AM
alekseyshl added inline comments.
lib/scudo/scudo_utils.cpp
110

So, hasHardwareCRC32ARMPosix() works fine, even that not all globals are initialized? Maybe the proper way is to repeat the check after globals are initialized (a lot more hassle, I know)?

This revision is now accepted and ready to land.Nov 27 2017, 11:22 AM
cryptoad added inline comments.Nov 27 2017, 11:33 AM
lib/scudo/scudo_utils.cpp
110

I'll see what I can whip out regarding the 2nd part of the comment.

A few other words for the record:
hasHardwareCRC32ARMPosix will work if the application has access to /proc/self/auxv. Two reasons I see why it wouldn't: /proc is not mounted yet (which is the case for init) or the file is disallowed via selinux/seccompbpf/sandboxing in general. This doesn't involve the libc globals.
getauxval will work if the first dynamic memory allocation related call isn't prior to the initialization of the Bionic globals, as it loops through __libc_auxv which is NULL at this point.
Things work with other libcs (musl, glibc) AFAICT, and is only an issue for Bionic.

cryptoad closed this revision.Nov 27 2017, 1:34 PM