xref: /llvm-project/compiler-rt/lib/msan/msan_dl.cpp (revision 0c9145f4134312fce41fa52099cd45358ed572a5)
19095d5c4SThurston Dang //===-- msan_dl.cpp -------------------------------------------------------===//
29095d5c4SThurston Dang //
39095d5c4SThurston Dang // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
49095d5c4SThurston Dang // See https://llvm.org/LICENSE.txt for license information.
59095d5c4SThurston Dang // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
69095d5c4SThurston Dang //
79095d5c4SThurston Dang //===----------------------------------------------------------------------===//
89095d5c4SThurston Dang //
99095d5c4SThurston Dang // This file is a part of MemorySanitizer.
109095d5c4SThurston Dang //
119095d5c4SThurston Dang // Helper functions for unpoisoning results of dladdr and dladdr1.
129095d5c4SThurston Dang //===----------------------------------------------------------------------===//
139095d5c4SThurston Dang 
149095d5c4SThurston Dang #include "msan_dl.h"
159095d5c4SThurston Dang 
169095d5c4SThurston Dang #include <dlfcn.h>
179095d5c4SThurston Dang #include <elf.h>
189095d5c4SThurston Dang #include <link.h>
199095d5c4SThurston Dang 
209095d5c4SThurston Dang #include "msan_poisoning.h"
219095d5c4SThurston Dang 
229095d5c4SThurston Dang namespace __msan {
239095d5c4SThurston Dang 
UnpoisonDllAddrInfo(void * info)249095d5c4SThurston Dang void UnpoisonDllAddrInfo(void *info) {
259095d5c4SThurston Dang   Dl_info *ptr = (Dl_info *)(info);
269095d5c4SThurston Dang   __msan_unpoison(ptr, sizeof(*ptr));
279095d5c4SThurston Dang   if (ptr->dli_fname)
289095d5c4SThurston Dang     __msan_unpoison(ptr->dli_fname, internal_strlen(ptr->dli_fname) + 1);
299095d5c4SThurston Dang   if (ptr->dli_sname)
309095d5c4SThurston Dang     __msan_unpoison(ptr->dli_sname, internal_strlen(ptr->dli_sname) + 1);
319095d5c4SThurston Dang }
329095d5c4SThurston Dang 
339095d5c4SThurston Dang #if SANITIZER_GLIBC
UnpoisonDllAddr1ExtraInfo(void ** extra_info,int flags)349095d5c4SThurston Dang void UnpoisonDllAddr1ExtraInfo(void **extra_info, int flags) {
359095d5c4SThurston Dang   if (flags == RTLD_DL_SYMENT) {
369095d5c4SThurston Dang     __msan_unpoison(extra_info, sizeof(void *));
379095d5c4SThurston Dang 
38*0c9145f4SThurston Dang     ElfW(Sym) *s = *((ElfW(Sym) **)(extra_info));
399095d5c4SThurston Dang     __msan_unpoison(s, sizeof(ElfW(Sym)));
409095d5c4SThurston Dang   } else if (flags == RTLD_DL_LINKMAP) {
419095d5c4SThurston Dang     __msan_unpoison(extra_info, sizeof(void *));
429095d5c4SThurston Dang 
439095d5c4SThurston Dang     struct link_map *map = *((struct link_map **)(extra_info));
449095d5c4SThurston Dang 
459095d5c4SThurston Dang     // Walk forward
469095d5c4SThurston Dang     for (auto *ptr = map; ptr; ptr = ptr->l_next) {
479095d5c4SThurston Dang       __msan_unpoison(ptr, sizeof(struct link_map));
489095d5c4SThurston Dang       if (ptr->l_name)
499095d5c4SThurston Dang         __msan_unpoison(ptr->l_name, internal_strlen(ptr->l_name) + 1);
509095d5c4SThurston Dang     }
519095d5c4SThurston Dang 
529095d5c4SThurston Dang     if (!map)
539095d5c4SThurston Dang       return;
549095d5c4SThurston Dang 
559095d5c4SThurston Dang     // Walk backward
569095d5c4SThurston Dang     for (auto *ptr = map->l_prev; ptr; ptr = ptr->l_prev) {
579095d5c4SThurston Dang       __msan_unpoison(ptr, sizeof(struct link_map));
589095d5c4SThurston Dang       if (ptr->l_name)
599095d5c4SThurston Dang         __msan_unpoison(ptr->l_name, internal_strlen(ptr->l_name) + 1);
609095d5c4SThurston Dang     }
619095d5c4SThurston Dang   }
629095d5c4SThurston Dang }
639095d5c4SThurston Dang #endif
649095d5c4SThurston Dang 
659095d5c4SThurston Dang }  // namespace __msan
66