msan_dl.cpp 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. //===-- msan_dl.cpp -------------------------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file is a part of MemorySanitizer.
  10. //
  11. // Helper functions for unpoisoning results of dladdr and dladdr1.
  12. //===----------------------------------------------------------------------===//
  13. #include "msan_dl.h"
  14. #include <dlfcn.h>
  15. #include <elf.h>
  16. #include <link.h>
  17. #include "msan_poisoning.h"
  18. namespace __msan {
  19. void UnpoisonDllAddrInfo(void *info) {
  20. Dl_info *ptr = (Dl_info *)(info);
  21. __msan_unpoison(ptr, sizeof(*ptr));
  22. if (ptr->dli_fname)
  23. __msan_unpoison(ptr->dli_fname, internal_strlen(ptr->dli_fname) + 1);
  24. if (ptr->dli_sname)
  25. __msan_unpoison(ptr->dli_sname, internal_strlen(ptr->dli_sname) + 1);
  26. }
  27. #if SANITIZER_GLIBC
  28. void UnpoisonDllAddr1ExtraInfo(void **extra_info, int flags) {
  29. if (flags == RTLD_DL_SYMENT) {
  30. __msan_unpoison(extra_info, sizeof(void *));
  31. ElfW(Sym) *s = *((ElfW(Sym) **)(extra_info));
  32. __msan_unpoison(s, sizeof(ElfW(Sym)));
  33. } else if (flags == RTLD_DL_LINKMAP) {
  34. __msan_unpoison(extra_info, sizeof(void *));
  35. struct link_map *map = *((struct link_map **)(extra_info));
  36. // Walk forward
  37. for (auto *ptr = map; ptr; ptr = ptr->l_next) {
  38. __msan_unpoison(ptr, sizeof(struct link_map));
  39. if (ptr->l_name)
  40. __msan_unpoison(ptr->l_name, internal_strlen(ptr->l_name) + 1);
  41. }
  42. if (!map)
  43. return;
  44. // Walk backward
  45. for (auto *ptr = map->l_prev; ptr; ptr = ptr->l_prev) {
  46. __msan_unpoison(ptr, sizeof(struct link_map));
  47. if (ptr->l_name)
  48. __msan_unpoison(ptr->l_name, internal_strlen(ptr->l_name) + 1);
  49. }
  50. }
  51. }
  52. #endif
  53. } // namespace __msan