Intercepting dlinfo in memory sanitizer

Hi everyone,

I ran into a false positive with memory sanitizer due to it not intercepting dlinfo. I tried to get started on writing such an interceptor, but dlinfo seems like an extraordinarily difficult function to intercept. The three considerations that I would like somebody to look at are:

  1. How do we get the enum values to decide what kind of pointer dlinfo is getting. Ideally we’d include dlfcn.h, but the interceptor file doesn’t generally include system headers. What’s the right thing to do here?
  2. The structures pointed to contain linked lists, etc. of dynamic linker state. In order to avoid spurious failures, it seems like we should iterate the linked lists and unpoison all of them, but that seems expensive. Do you see a better solution?
  3. The return values include pointers into the object files. It seems perfectly reasonable for a user to want to read these object files based on information from dlinfo. That probably means we should unpoison them as well? Do we need to do something here or are these already unpoisoned by some other mechanism (e.g. because msan realizes they are part of a loaded object file or unposions them on load - does this happen?).

Thanks,
Keno

Hi everyone,

I ran into a false positive with memory sanitizer due to it not intercepting
dlinfo. I tried to get started on writing such an interceptor, but dlinfo
seems like an extraordinarily difficult function to intercept. The three
considerations that I would like somebody to look at are:

1) How do we get the enum values to decide what kind of pointer dlinfo is
getting. Ideally we'd include dlfcn.h, but the interceptor file doesn't
generally include system headers. What's the right thing to do here?

We generally redefine system constants and types in
sanitizer_platform_limits_posix.h and verify correctness with
assertions in .cc.

2) The structures pointed to contain linked lists, etc. of dynamic linker
state. In order to avoid spurious failures, it seems like we should iterate
the linked lists and unpoison all of them, but that seems expensive. Do you
see a better solution?

Nope, sounds like that's want you need to do.

3) The return values include pointers into the object files. It seems
perfectly reasonable for a user to want to read these object files based on
information from dlinfo. That probably means we should unpoison them as
well? Do we need to do something here or are these already unpoisoned by
some other mechanism (e.g. because msan realizes they are part of a loaded
object file or unposions them on load - does this happen?).

They are unpoisoned. All memory defaults to unpoisoned (shadow == 0),
and we take care of unpoisoning all memory we return to the OS.

Thanks! I’ll try that.

In order to avoid starting a new thread, let me ask you the next question. One of the shared libraries I load calls strtol and msan fails to intercept it. Why would this be? The library seems to be otherwise implemented. One of the potential culprits I saw is that strtol is marked as strong in libc. Is there any workaround?

Keno

Thanks! I'll try that.

In order to avoid starting a new thread, let me ask you the next question.
One of the shared libraries I load calls strtol and msan fails to intercept
it. Why would this be? The library seems to be otherwise implemented. One of
the potential culprits I saw is that strtol is marked as strong in libc. Is
there any workaround?

Strong symbol should not be a problem. What name is it called by?
There are a number of __strtol_internal, __strtol_l and other variants
that we intercept.
It is a problem with all calls from that library, or just this one function?

It’s called by strtol (there’s a strtol@plt in the assembly code). It seems to be a problem just with this function.

No idea then. We do have an interceptor for a function by that name in
msan_interceptors.cc. Is it exported from the main executable? Any
version scripts that could be interfering with it?