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 14 #include "msan_dl.h" 15 16 #include <dlfcn.h> 17 #include <elf.h> 18 #include <link.h> 19 20 #include "msan_poisoning.h" 21 22 namespace __msan { 23 24 void UnpoisonDllAddrInfo(void *info) { 25 Dl_info *ptr = (Dl_info *)(info); 26 __msan_unpoison(ptr, sizeof(*ptr)); 27 if (ptr->dli_fname) 28 __msan_unpoison(ptr->dli_fname, internal_strlen(ptr->dli_fname) + 1); 29 if (ptr->dli_sname) 30 __msan_unpoison(ptr->dli_sname, internal_strlen(ptr->dli_sname) + 1); 31 } 32 33 #if SANITIZER_GLIBC 34 void UnpoisonDllAddr1ExtraInfo(void **extra_info, int flags) { 35 if (flags == RTLD_DL_SYMENT) { 36 __msan_unpoison(extra_info, sizeof(void *)); 37 38 ElfW(Sym) *s = *((ElfW(Sym) **)(extra_info)); 39 __msan_unpoison(s, sizeof(ElfW(Sym))); 40 } else if (flags == RTLD_DL_LINKMAP) { 41 __msan_unpoison(extra_info, sizeof(void *)); 42 43 struct link_map *map = *((struct link_map **)(extra_info)); 44 45 // Walk forward 46 for (auto *ptr = map; ptr; ptr = ptr->l_next) { 47 __msan_unpoison(ptr, sizeof(struct link_map)); 48 if (ptr->l_name) 49 __msan_unpoison(ptr->l_name, internal_strlen(ptr->l_name) + 1); 50 } 51 52 if (!map) 53 return; 54 55 // Walk backward 56 for (auto *ptr = map->l_prev; ptr; ptr = ptr->l_prev) { 57 __msan_unpoison(ptr, sizeof(struct link_map)); 58 if (ptr->l_name) 59 __msan_unpoison(ptr->l_name, internal_strlen(ptr->l_name) + 1); 60 } 61 } 62 } 63 #endif 64 65 } // namespace __msan 66