//===-- 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 #include #include #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