[scudo] Allow for non-Android Shared TSD platforms, part 2

Authored by cryptoad on Oct 12 2017, 10:39 AM.



Follow up to D38826.

We introduce pthread_{get,set}specific versions of {get,set}CurrentTSD to
allow for non Android platforms to use the Shared TSD model.
We now allow SCUDO_TSD_EXCLUSIVE to be defined at compile time.

A couple of things:

  • I know that #if SANITIZER_ANDROID is not ideal within a function, but in the end I feel it looks more compact and clean than going the .inc route; I am open to an alternative if anyone has one;
  • SCUDO_TSD_EXCLUSIVE=1 requires ELF TLS support (and not emutls as this uses malloc). I haven't found anything to enforce that, so it's currently not checked.
cryptoad created this revision.Oct 12 2017, 10:39 AM
cryptoad updated this revision to Diff 118845.Oct 12 2017, 2:22 PM

Remove a comment that is no longer relevant: the pthread key is used.

alekseyshl added inline comments.Oct 12 2017, 4:59 PM

What's going to happen if we define SCUDO_TSD_EXCLUSIVE at compile time on these platforms?


Why is it not static anymore?


You do not need this PThreadKey on Android, right? Maybe it does make sense to separate implementations along these lines? Move PThreadKey and Android into separate cpp files and link what you need?

cryptoad added inline comments.Oct 12 2017, 5:54 PM

It will blow up at runtime (see main comment of the patch).
Android doesn't have ELF TLS but it's planned for some point. They do have emutls but it doesn't work for us.
Fuchsia I think supports a non emulated TLS, I'd have to double check.
I can put some safeguards?


It is used from scudo_tsd_shared.inc (defined as extern there).


Correct, it's not needed, it's useful on Android to makes things work on older platforms (the comment that I removed explains it).
I guess the issue with the separation is that it will end up affecting the .inc as well, which would have to be split or have further #ifs (the pthread key is used there). If you see a way to make this work, I can accommodate that.

alekseyshl added inline comments.Oct 13 2017, 11:32 AM

Yep, something like this:



# error ...

If you are going to support O and below, I guess, the current way is fine. If you are not going to support releases before N, I'd suggest to separate implementations and either have 4 more files:
for getCurrentTSD:


for setCurrentTSD and the function called from initOnce (empty for Android):


or, another option is to define SCUDO_TSD_CPP_ and add two files, scudo_tsd_shared_android.inc and scudo_tsd_shared_pthread.inc, the pthread one will do something like this (android inc will look a bit simpler):

pthread_key_t PThreadKey;
ALWAYS_INLINE void setCurrentTSD(ScudoTSD *TSD) { ... }
void initSharedTsdOnce() { ... }
extern pthread_key_t PThreadKey;
ALWAYS_INLINE ScudoTSD* getCurrentTSD() { ... }

Both ways are pretty ugly.

Well, ok, I guess enough with that, I'll let you pick the way and accept your choice.

cryptoad added inline comments.Oct 13 2017, 11:43 AM

Does me picking a way allows for keeping things the way they are now? :)

cryptoad updated this revision to Diff 118956.Oct 13 2017, 12:27 PM
cryptoad marked 5 inline comments as done.

Safeguarding the use of the exclusive TSD model against misuse (eg: using it
on a platform that doesn't support it).

alekseyshl accepted this revision.Oct 13 2017, 1:26 PM
alekseyshl added inline comments.

No a big deal at all, but why add "#else" part? Less nesting in these # statements is always better. But, anyway, whatever works better for you.


Yep, none of the ways I came up with is significantly better. So, up to you.

This revision is now accepted and ready to land.Oct 13 2017, 1:26 PM
cryptoad added inline comments.Oct 13 2017, 1:31 PM

In my head it's one this check applies if SCUDO_TSD_EXCLUSIVE was defined initially, hence the #else.
I'll unnest it, it's not like we lose any performance that way!


I'd like to keep it that way for now.
If more platform specific stuff comes up in the future, I can see the split becoming necessary, but right now I feel it's less fragmented this way.

cryptoad updated this revision to Diff 118970.Oct 13 2017, 1:39 PM
cryptoad marked 8 inline comments as done.

Unnesting the #if.

cryptoad closed this revision.Oct 13 2017, 1:55 PM