From: Hwankyu Jhun Date: Tue, 5 Oct 2021 07:48:33 +0000 (+0900) Subject: Implement finding main symbol from .dynsym X-Git-Tag: submit/tizen/20211028.054746~8 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ae2d2baff6aa0064e5be6c1099869f0ebda92bf5;p=platform%2Fcore%2Fappfw%2Faul-1.git Implement finding main symbol from .dynsym This patch finds the main symbol using Elf64_Shdr and Elf64_Sym. If the main symbol doesn't exist, the plugin prints the warning log for debugging. Change-Id: Ib46bfcc66319c13be443d76773ab3f41b7496f12 Signed-off-by: Hwankyu Jhun --- diff --git a/parser/exec-checker/src/exec_checker.cc b/parser/exec-checker/src/exec_checker.cc index de48835..7f44813 100644 --- a/parser/exec-checker/src/exec_checker.cc +++ b/parser/exec-checker/src/exec_checker.cc @@ -42,6 +42,111 @@ union header { Elf64_Ehdr ehdr64; }; +template +Shdr* GetSectionFromShdr(const char* name, Shdr* shdr, + const char* shdr_names, int e_shnum) { + for (int i = 0; i < e_shnum; ++i) { + if (shdr[i].sh_size) { + if (!strcmp(&shdr_names[shdr[i].sh_name], name)) + return &shdr[i]; + } + } + + return nullptr; +} + +int Read(FILE* fp, void* ptr, long offset, size_t size) { + if (offset < 0 || size <= 0) { + LOGE_STD("Invalid parameter"); + return -1; + } + + if (fseek(fp, offset, SEEK_SET) < 0) { + LOGE_STD("fseek() is failed. errno(%d)", errno); + return -1; + } + + auto nbytes = fread(ptr, 1, size, fp); + if (nbytes <= 0) { + LOGE_STD("fread() is failed. error(%d)", nbytes); + return -1; + } + + return 0; +} + +char* GetDataFromFile(FILE* fp, long offset, size_t size) { + if (offset < 0 || size <= 0) { + LOGE_STD("Invalid parameter"); + return nullptr; + } + + void* ptr = malloc(size); + if (ptr == nullptr) { + LOGE_STD("Out of memory"); + return nullptr; + } + + if (Read(fp, ptr, offset, size) < 0) { + free(ptr); + return nullptr; + } + + return static_cast(ptr); +} + +template +bool FindMainSymbolFromEhdr(FILE* fp, Ehdr* ehdr) { + rewind(fp); + Half shdr_tab_size = ehdr->e_shentsize * ehdr->e_shnum; + Shdr shdr_tab[shdr_tab_size]; + if (Read(fp, &shdr_tab, ehdr->e_shoff, shdr_tab_size) < 0) + return false; + + char* shdr_names = GetDataFromFile(fp, shdr_tab[ehdr->e_shstrndx].sh_offset, + shdr_tab[ehdr->e_shstrndx].sh_size); + if (shdr_names == nullptr) + return false; + + std::unique_ptr shdr_names_auto( + shdr_names, std::free); + + auto* shdr_strtab = GetSectionFromShdr( + ".dynstr", shdr_tab, shdr_names, ehdr->e_shnum); + if (shdr_strtab == nullptr) + return false; + + auto* shdr_symtab = GetSectionFromShdr( + ".dynsym", shdr_tab, shdr_names, ehdr->e_shnum); + if (shdr_symtab == nullptr) + return false; + + if (shdr_symtab->sh_type == SHT_DYNSYM) { + auto* symtab = reinterpret_cast(GetDataFromFile(fp, + shdr_symtab->sh_offset, shdr_symtab->sh_size)); + if (symtab == nullptr) + return false; + + std::unique_ptr symtab_auto(symtab, std::free); + + auto* strtab = GetDataFromFile(fp, shdr_strtab->sh_offset, + shdr_strtab->sh_size); + if (strtab == nullptr) + return false; + + std::unique_ptr strtab_auto(strtab, std::free); + + int size = shdr_symtab->sh_size / sizeof(Sym); + for (int i = 0; i < size; ++i) { + char* name = strtab + symtab[i].st_name; + if (name && !strcmp(name, "main")) + return true; + } + } + + return false; +} + } // namespace ExecChecker::ExecChecker(std::string path) : path_(std::move(path)) { @@ -84,8 +189,27 @@ bool ExecChecker::IsShared() { } bool ExecChecker::CheckMainSymbol() { - // TODO: Implement finding main symbol using Elf64_Sym & Elf32_Sym - return false; + FILE* fp = fopen(path_.c_str(), "r"); + if (fp == nullptr) { + LOGE_STD("fopen() is failed. errno(%d)", errno); + return false; + } + + std::unique_ptr fp_auto(fp, fclose); + header h; + size_t nbytes = fread(h.c, 1, sizeof(h), fp); + if (nbytes < 2) { + LOGE_STD("fread() is failed"); + return false; + } + + if (class_bit_ == 64) { + return FindMainSymbolFromEhdr( + fp, &h.ehdr64); + } + + return FindMainSymbolFromEhdr( + fp, &h.ehdr32); } bool ExecChecker::CheckDependencyLibs() { diff --git a/parser/exec-checker/src/plugin_manager.cc b/parser/exec-checker/src/plugin_manager.cc index 24566dd..01d90e8 100644 --- a/parser/exec-checker/src/plugin_manager.cc +++ b/parser/exec-checker/src/plugin_manager.cc @@ -122,7 +122,9 @@ int PluginManager::Process() { if (!checker.IsShared()) LOGW("%s is not shared object", exec); - checker.CheckMainSymbol(); + if (!checker.CheckMainSymbol()) + LOGW_STD("Failed to find main symbol"); + if (!checker.CheckDependencyLibs()) return -1; }