#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>
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) {
}
f.close();
- remove(tmp);
+ remove(tmp.c_str());
return pass;
}