Add /lib/ld execution for dynamic binaries
This commit is contained in:
@@ -104,6 +104,39 @@ int binfmt_is_elf(const char *ident, size_t len) {
|
||||
return !strncmp(ident, "\x7F""ELF", 4);
|
||||
}
|
||||
|
||||
int elf_is_dynamic(struct vfs_ioctx *ioctx, struct ofile *fd, int *is_dynamic) {
|
||||
Elf64_Ehdr ehdr;
|
||||
Elf64_Phdr phdr;
|
||||
int res;
|
||||
|
||||
*is_dynamic = 0;
|
||||
|
||||
if ((res = elf_read(ioctx, fd, 0, &ehdr, sizeof(Elf64_Ehdr))) != 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
if (ehdr.e_ident[EI_CLASS] != ELFCLASS64) {
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ehdr.e_phnum; ++i) {
|
||||
if ((res = elf_read(ioctx,
|
||||
fd,
|
||||
ehdr.e_phoff + i * ehdr.e_phentsize,
|
||||
&phdr,
|
||||
ehdr.e_phentsize)) != 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
if (phdr.p_type == PT_DYNAMIC) {
|
||||
*is_dynamic = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int elf_load(struct process *proc, struct vfs_ioctx *ctx, struct ofile *fd, uintptr_t *entry) {
|
||||
int res;
|
||||
ssize_t bread;
|
||||
|
||||
@@ -6,3 +6,4 @@ struct ofile;
|
||||
|
||||
int elf_load(struct process *proc, struct vfs_ioctx *ctx, struct ofile *fd, uintptr_t *entry);
|
||||
int binfmt_is_elf(const char *guess, size_t len);
|
||||
int elf_is_dynamic(struct vfs_ioctx *ioctx, struct ofile *fd, int *is_dynamic);
|
||||
|
||||
+24
-4
@@ -171,12 +171,32 @@ int sys_execve(const char *path, const char **argv, const char **envp) {
|
||||
}
|
||||
argv_new[argc] = NULL;
|
||||
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
kdebug("[%d]: %s\n", i, argv_new[i]);
|
||||
}
|
||||
|
||||
return sys_execve(shebang + 2, argv_new, envp);
|
||||
}
|
||||
} else {
|
||||
int is_dynamic = 0;
|
||||
if ((res = elf_is_dynamic(&proc->ioctx, &fd, &is_dynamic)) != 0) {
|
||||
kerror("%s: %s\n", path, kstrerror(res));
|
||||
vfs_close(&proc->ioctx, &fd);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (is_dynamic) {
|
||||
vfs_close(&proc->ioctx, &fd);
|
||||
|
||||
int argc;
|
||||
for (argc = 0; argv[argc]; ++argc);
|
||||
|
||||
const char *argv_new[argc + 3];
|
||||
argv_new[0] = "/lib/ld";
|
||||
argv_new[1] = path;
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
argv_new[i + 2] = argv[i];
|
||||
}
|
||||
argv_new[argc + 2] = NULL;
|
||||
|
||||
return sys_execve(argv_new[0], argv_new, envp);
|
||||
}
|
||||
}
|
||||
|
||||
const char *e = strrchr(path, '/');
|
||||
|
||||
Reference in New Issue
Block a user