| //===-- msan_dl.cpp -------------------------------------------------------===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| // | |
| // This file is a part of MemorySanitizer. | |
| // | |
| // Helper functions for unpoisoning results of dladdr and dladdr1. | |
| //===----------------------------------------------------------------------===// | |
| #include "msan_dl.h" | |
| #include <dlfcn.h> | |
| #include <elf.h> | |
| #include <link.h> | |
| #include "msan_poisoning.h" | |
| namespace __msan { | |
| void UnpoisonDllAddrInfo(void *info) { | |
| Dl_info *ptr = (Dl_info *)(info); | |
| __msan_unpoison(ptr, sizeof(*ptr)); | |
| if (ptr->dli_fname) | |
| __msan_unpoison(ptr->dli_fname, internal_strlen(ptr->dli_fname) + 1); | |
| if (ptr->dli_sname) | |
| __msan_unpoison(ptr->dli_sname, internal_strlen(ptr->dli_sname) + 1); | |
| } | |
| #if SANITIZER_GLIBC | |
| void UnpoisonDllAddr1ExtraInfo(void **extra_info, int flags) { | |
| if (flags == RTLD_DL_SYMENT) { | |
| __msan_unpoison(extra_info, sizeof(void *)); | |
| ElfW(Sym) *s = *((ElfW(Sym) **)(extra_info)); | |
| __msan_unpoison(s, sizeof(ElfW(Sym))); | |
| } else if (flags == RTLD_DL_LINKMAP) { | |
| __msan_unpoison(extra_info, sizeof(void *)); | |
| struct link_map *map = *((struct link_map **)(extra_info)); | |
| // Walk forward | |
| for (auto *ptr = map; ptr; ptr = ptr->l_next) { | |
| __msan_unpoison(ptr, sizeof(struct link_map)); | |
| if (ptr->l_name) | |
| __msan_unpoison(ptr->l_name, internal_strlen(ptr->l_name) + 1); | |
| } | |
| if (!map) | |
| return; | |
| // Walk backward | |
| for (auto *ptr = map->l_prev; ptr; ptr = ptr->l_prev) { | |
| __msan_unpoison(ptr, sizeof(struct link_map)); | |
| if (ptr->l_name) | |
| __msan_unpoison(ptr->l_name, internal_strlen(ptr->l_name) + 1); | |
| } | |
| } | |
| } | |
| #endif | |
| } // namespace __msan |