mirror of
https://github.com/darlinghq/darling.git
synced 2025-02-17 08:09:10 +00:00
Resolve absolute symlinks relative to the prefix
This requires a change in libelfloader to ensure the interpreter is resolved according to the Linux root and not the prefix.
This commit is contained in:
parent
1c83210faa
commit
3761b3d7f1
@ -0,0 +1 @@
|
||||
../../../../../../../../../../../src/kernel/emulation/linux/ext/for-libelfloader.h
|
@ -266,6 +266,7 @@ set(emulation_sources
|
||||
ext/file_handle.c
|
||||
ext/fanotify.c
|
||||
ext/for-xtrace.c
|
||||
ext/for-libelfloader.c
|
||||
bsdthread/bsdthread_register.c
|
||||
bsdthread/bsdthread_create.c
|
||||
bsdthread/bsdthread_ctl.c
|
||||
|
43
src/kernel/emulation/linux/ext/for-libelfloader.c
Normal file
43
src/kernel/emulation/linux/ext/for-libelfloader.c
Normal file
@ -0,0 +1,43 @@
|
||||
#include "for-libelfloader.h"
|
||||
#include "../base.h"
|
||||
#include "../errno.h"
|
||||
#include "../bsdthread/cancelable.h"
|
||||
#include "../bsdthread/per_thread_wd.h"
|
||||
#include "../fcntl/open.h"
|
||||
|
||||
VISIBLE
|
||||
long _open_for_libelfloader(const char* path, int flags, unsigned int mode) {
|
||||
int linux_flags;
|
||||
int wd;
|
||||
int ret;
|
||||
|
||||
CANCELATION_POINT();
|
||||
|
||||
linux_flags = oflags_bsd_to_linux(flags);
|
||||
wd = oflags_bsd_to_linux(flags);
|
||||
|
||||
if (sizeof(void*) == 4) {
|
||||
linux_flags |= LINUX_O_LARGEFILE;
|
||||
}
|
||||
|
||||
ret = LINUX_SYSCALL(__NR_openat, wd, path, linux_flags, mode);
|
||||
if (ret < 0)
|
||||
ret = errno_linux_to_bsd(ret);
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
VISIBLE
|
||||
long _access_for_libelfloader(const char* path, int mode) {
|
||||
int ret;
|
||||
int wd;
|
||||
|
||||
wd = get_perthread_wd();
|
||||
|
||||
ret = LINUX_SYSCALL(__NR_faccessat, wd, path, mode, 0);
|
||||
|
||||
if (ret < 0)
|
||||
ret = errno_linux_to_bsd(ret);
|
||||
|
||||
return ret;
|
||||
};
|
14
src/kernel/emulation/linux/ext/for-libelfloader.h
Normal file
14
src/kernel/emulation/linux/ext/for-libelfloader.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef _DARLING_EMULATION_FOR_LIBELFLOADER_H_
|
||||
#define _DARLING_EMULATION_FOR_LIBELFLOADER_H_
|
||||
|
||||
#include <darling/emulation/base.h>
|
||||
|
||||
// these are non-vchrooted calls for libelfloader
|
||||
|
||||
VISIBLE
|
||||
long _open_for_libelfloader(const char* path, int flags, unsigned int mode);
|
||||
|
||||
VISIBLE
|
||||
long _access_for_libelfloader(const char* path, int mode);
|
||||
|
||||
#endif // _DARLING_EMULATION_FOR_LIBELFLOADER_H_
|
@ -423,6 +423,12 @@ done_getdents:
|
||||
ctxt->follow = true;
|
||||
ctxt->symlink_depth++;
|
||||
|
||||
// resolve absolute symlinks within the prefix
|
||||
if (link[0] == '/') {
|
||||
ctxt->current_root = prefix_path;
|
||||
ctxt->current_root_len = prefix_path_len;
|
||||
}
|
||||
|
||||
rv = vchroot_run(link, ctxt);
|
||||
|
||||
ctxt->symlink_depth--;
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <setjmp.h>
|
||||
#include <sys/random.h>
|
||||
#include <elf.h>
|
||||
#include <darling/emulation/ext/for-libelfloader.h>
|
||||
#include "auxvec.h"
|
||||
#include "loader.h"
|
||||
#include "native/elfcalls.h"
|
||||
@ -235,7 +236,8 @@ void load(const char* path, struct loader_context* lc, bool isInterp)
|
||||
ElfW(Ehdr) elfHdr;
|
||||
void* phdrs = NULL;
|
||||
|
||||
int fd = open(path, O_RDONLY);
|
||||
// the interpreter path should be relative to the Linux root, not the Darling prefix
|
||||
int fd = isInterp ? _open_for_libelfloader(path, O_RDONLY, 0) : open(path, O_RDONLY);
|
||||
uintptr_t slide, base;
|
||||
|
||||
if (fd == -1)
|
||||
@ -389,18 +391,7 @@ void load(const char* path, struct loader_context* lc, bool isInterp)
|
||||
interp[phdr->p_filesz] = '\0';
|
||||
|
||||
// Load interpreter
|
||||
if (access(interp, F_OK) != 0)
|
||||
{
|
||||
char* prefixed = (char*) malloc(phdr->p_filesz + sizeof(SYSTEM_ROOT));
|
||||
|
||||
strcpy(prefixed, SYSTEM_ROOT);
|
||||
strcat(prefixed, interp);
|
||||
|
||||
free(interp);
|
||||
interp = prefixed;
|
||||
}
|
||||
|
||||
if (access(interp, F_OK) != 0)
|
||||
if (_access_for_libelfloader(interp, F_OK) != 0)
|
||||
{
|
||||
fprintf(stderr, "Cannot load interpreter at %s\n", interp);
|
||||
free(interp);
|
||||
|
Loading…
x
Reference in New Issue
Block a user