summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChanggyu Choi <changyu.choi@samsung.com>2021-08-10 17:14:12 +0900
committerChanggyu Choi <changyu.choi@samsung.com>2021-08-11 18:30:45 +0900
commit9f8dd0dbbceb293a829f4e6933990cc6069c3ef7 (patch)
treedad955645f94079852094d9d42633d001101fb6a
parentac5655de8f5273a74b9afa8e8bb61deaef40d1ba (diff)
downloadaul-1-9f8dd0dbbceb293a829f4e6933990cc6069c3ef7.tar.gz
aul-1-9f8dd0dbbceb293a829f4e6933990cc6069c3ef7.tar.bz2
aul-1-9f8dd0dbbceb293a829f4e6933990cc6069c3ef7.zip
Change method of checking main symbol
Some binary may need to launch daemons for loading them. In special case such as mic build, deamons are not launched. As a result, the parser should not use dlopen(). Change-Id: I102eb220d4ecab2657668a335af95257de981e79 Signed-off-by: Changgyu Choi <changyu.choi@samsung.com>
-rw-r--r--CMakeLists.txt1
-rw-r--r--packaging/aul.spec1
-rw-r--r--parser/exec-checker/CMakeLists.txt2
-rw-r--r--parser/exec-checker/inc/exec_checker.hh3
-rw-r--r--parser/exec-checker/src/exec_checker.cc75
-rw-r--r--parser/exec-checker/src/plugin_manager.cc6
6 files changed, 70 insertions, 18 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bc0e00a8..52962fa4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -52,6 +52,7 @@ PKG_CHECK_MODULES(TTRACE_DEPS REQUIRED ttrace)
PKG_CHECK_MODULES(UUID_DEPS REQUIRED uuid)
PKG_CHECK_MODULES(VCONF_DEPS REQUIRED vconf)
PKG_CHECK_MODULES(XDGMIME_DEPS REQUIRED xdgmime)
+PKG_CHECK_MODULES(LIBELF_DEPS REQUIRED libelf)
## Target sources
AUX_SOURCE_DIRECTORY(src SRCS)
diff --git a/packaging/aul.spec b/packaging/aul.spec
index 9c510dbd..2144d6fd 100644
--- a/packaging/aul.spec
+++ b/packaging/aul.spec
@@ -36,6 +36,7 @@ BuildRequires: pkgconfig(uuid)
BuildRequires: pkgconfig(libsmack)
BuildRequires: pkgconfig(gmock)
BuildRequires: pkgconfig(parcel)
+BuildRequires: pkgconfig(libelf)
%if 0%{?gcov:1}
BuildRequires: lcov
diff --git a/parser/exec-checker/CMakeLists.txt b/parser/exec-checker/CMakeLists.txt
index bb26f1b4..97134e1f 100644
--- a/parser/exec-checker/CMakeLists.txt
+++ b/parser/exec-checker/CMakeLists.txt
@@ -20,7 +20,7 @@ APPLY_PKG_CONFIG(${TARGET_CHECK_EXEC_PLUGIN_PARSER} PUBLIC
LIBXML_DEPS
PKGMGR_INFO_DEPS
PKGMGR_INSTALLER_DEPS
- SQLITE3_DEPS
+ LIBELF_DEPS
)
INSTALL(TARGETS ${TARGET_CHECK_EXEC_PLUGIN_PARSER}
diff --git a/parser/exec-checker/inc/exec_checker.hh b/parser/exec-checker/inc/exec_checker.hh
index 7857e774..a1c08b86 100644
--- a/parser/exec-checker/inc/exec_checker.hh
+++ b/parser/exec-checker/inc/exec_checker.hh
@@ -24,7 +24,9 @@ namespace plugin {
class ExecChecker {
public:
explicit ExecChecker(std::string path);
+ ~ExecChecker() = default;
bool IsShared();
+ bool CheckMainSymbol();
bool CheckDependencyLibs();
bool IsSameArch(const ExecChecker& exe);
@@ -32,6 +34,7 @@ class ExecChecker {
std::string path_;
int class_bit_ = 0;
uint16_t arch_bit_ = 0;
+ uint16_t type_ = 0;
};
} // namespace plugin
diff --git a/parser/exec-checker/src/exec_checker.cc b/parser/exec-checker/src/exec_checker.cc
index 23278afb..5ef73c55 100644
--- a/parser/exec-checker/src/exec_checker.cc
+++ b/parser/exec-checker/src/exec_checker.cc
@@ -18,10 +18,14 @@
#include <elf.h>
#include <errno.h>
#include <fcntl.h>
+#include <gelf.h>
+#include <libelf.h>
+#include <linux/limits.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
+#include <uuid/uuid.h>
#include <fstream>
#include <memory>
@@ -66,40 +70,79 @@ ExecChecker::ExecChecker(std::string path) : path_(std::move(path)) {
h.c[EI_CLASS] == ELFCLASS32) {
class_bit_ = 32;
arch_bit_ = h.ehdr32.e_machine;
+ type_ = h.ehdr32.e_type;
} else if (nbyte >= static_cast<int>(sizeof(Elf64_Ehdr)) &&
h.c[EI_CLASS] == ELFCLASS64) {
class_bit_ = 64;
arch_bit_ = h.ehdr64.e_machine;
+ type_ = h.ehdr64.e_type;
}
- LOGI_STD("class: %dbit, e_machine: %hu", class_bit_, arch_bit_);
+ LOGI_STD("%s class: %dbit, e_machine: %hu, e_type : %hu",
+ path_.c_str(), class_bit_, arch_bit_, type_);
}
bool ExecChecker::IsShared() {
- void* handle = dlopen(path_.c_str(), RTLD_LAZY | RTLD_GLOBAL);
- if (handle == nullptr) {
- LOGE_STD("(%s) is not shared object.", path_.c_str());
+ return type_ == ET_DYN;
+}
+
+bool ExecChecker::CheckMainSymbol() {
+ int fd = open(path_.c_str(), O_RDONLY);
+ if (fd < 0) {
+ LOGE_STD("Failed to open file(%s). errno(%d)", path_.c_str(), errno);
+ return false;
+ }
+
+ elf_version(EV_CURRENT);
+
+ auto elf_destructor = [fd] (Elf* elf) -> void {
+ close(fd);
+ elf_end(elf);
+ };
+ auto elf = std::unique_ptr<Elf, decltype(elf_destructor)>
+ (elf_begin(fd, ELF_C_READ, nullptr), elf_destructor);
+ if (elf == nullptr) {
+ LOGE_STD("Out of memory");
return false;
}
- auto* main = dlsym(handle, "main");
- if (main == nullptr)
- LOGW_STD("Not found main symbol(%s). err(%s)", path_.c_str(), dlerror());
+ Elf_Scn* scn = nullptr;
+ GElf_Shdr shdr;
+ while ((scn = elf_nextscn(elf.get(), scn)) != nullptr) {
+ gelf_getshdr(scn, &shdr);
+ if (shdr.sh_type == SHT_SYMTAB)
+ break;
+ }
+
+ Elf_Data* data = elf_getdata(scn, nullptr);
+ int count = (shdr.sh_entsize == 0 ? 0 : shdr.sh_size / shdr.sh_entsize);
+
+ for (int i = 0; i < count; ++i) {
+ GElf_Sym sym;
+ gelf_getsym(data, i, &sym);
+ char* symbol = elf_strptr(elf.get(), shdr.sh_link, sym.st_name);
+ if (symbol != nullptr && strcmp("main", symbol) == 0)
+ return true;
+ }
- dlclose(handle);
- return main != nullptr;
+ LOGW_STD("Not found main symbol(%s)", path_.c_str());
+ return false;
}
bool ExecChecker::CheckDependencyLibs() {
std::string root_path = path_.substr(0, path_.find_last_of('/') - 4);
- char tmp_format[] = "/tmp/XXXXXX";
- auto* tmp = tmpnam_r(tmp_format);
- if (tmp == nullptr) {
- LOGE_STD("Failed to make temp file. errno(%d)", errno);
- return false;
- }
+ char uuid[37];
+ uuid_t u;
+ uuid_generate(u);
+ uuid_unparse(u, uuid);
+ std::string tmp = std::string("/tmp/") +
+ path_.substr(path_.find_last_of('/') + 1) + "_" + uuid;
std::string cmd = "LD_LIBRARY_PATH=" + root_path + "/lib /usr/bin/ldd " +
path_ + " > " + tmp;
+
+ if (tmp.size() > PATH_MAX)
+ tmp = tmp.substr(0, PATH_MAX);
+
bool pass = true;
int ret = WEXITSTATUS(system(cmd.c_str()));
if (ret != 0) {
@@ -122,7 +165,7 @@ bool ExecChecker::CheckDependencyLibs() {
}
f.close();
- remove(tmp);
+ remove(tmp.c_str());
return pass;
}
diff --git a/parser/exec-checker/src/plugin_manager.cc b/parser/exec-checker/src/plugin_manager.cc
index 91e1bdcf..24566dd9 100644
--- a/parser/exec-checker/src/plugin_manager.cc
+++ b/parser/exec-checker/src/plugin_manager.cc
@@ -118,7 +118,11 @@ int PluginManager::Process() {
if (!self_->IsSameArch(checker))
return -1;
- checker.IsShared();
+
+ if (!checker.IsShared())
+ LOGW("%s is not shared object", exec);
+
+ checker.CheckMainSymbol();
if (!checker.CheckDependencyLibs())
return -1;
}