Changeset View
Changeset View
Standalone View
Standalone View
libexec/rtld-elf/rtld.c
Show First 20 Lines • Show All 5,518 Lines • ▼ Show 20 Lines | symlook_init_from_req(SymLook *dst, const SymLook *src) | ||||
dst->sym_out = NULL; | dst->sym_out = NULL; | ||||
dst->lockstate = src->lockstate; | dst->lockstate = src->lockstate; | ||||
} | } | ||||
static int | static int | ||||
open_binary_fd(const char *argv0, bool search_in_path, | open_binary_fd(const char *argv0, bool search_in_path, | ||||
const char **binpath_res) | const char **binpath_res) | ||||
{ | { | ||||
char *abspath, *absres, *binpath, *pathenv, *pe, *res1; | char *binpath, *pathenv, *pe, *res1; | ||||
const char *res; | const char *res; | ||||
int fd; | int fd; | ||||
binpath = NULL; | binpath = NULL; | ||||
res = NULL; | res = NULL; | ||||
if (search_in_path && strchr(argv0, '/') == NULL) { | if (search_in_path && strchr(argv0, '/') == NULL) { | ||||
binpath = xmalloc(PATH_MAX); | binpath = xmalloc(PATH_MAX); | ||||
pathenv = getenv("PATH"); | pathenv = getenv("PATH"); | ||||
Show All 27 Lines | if (search_in_path && strchr(argv0, '/') == NULL) { | ||||
fd = open(argv0, O_RDONLY | O_CLOEXEC | O_VERIFY); | fd = open(argv0, O_RDONLY | O_CLOEXEC | O_VERIFY); | ||||
res = argv0; | res = argv0; | ||||
} | } | ||||
if (fd == -1) { | if (fd == -1) { | ||||
_rtld_error("Cannot open %s: %s", argv0, rtld_strerror(errno)); | _rtld_error("Cannot open %s: %s", argv0, rtld_strerror(errno)); | ||||
rtld_die(); | rtld_die(); | ||||
} | } | ||||
if (res != NULL && res[0] != '/') { | if (res != NULL && res[0] != '/') { | ||||
rstone: This will change /foo/symlink to /bar/target where we didn't before. That's not an enormous… | |||||
Done Inline ActionsSo do you want realpath(3) at all there ? kib: So do you want realpath(3) at all there ? | |||||
Done Inline ActionsI can test with cap_getmode(2) and only call realpath if not in cap mode. This is also a valid question for $ORIGIN resolution, where we use realpath(3) as well. See some minimal discussion with completely wrong patch at D23043. kib: I can test with cap_getmode(2) and only call realpath if not in cap mode.
This is also a valid… | |||||
abspath = getcwd(NULL, 0); | |||||
if (abspath != NULL) { | |||||
res1 = xmalloc(PATH_MAX); | res1 = xmalloc(PATH_MAX); | ||||
if (realpath(res, res1) != NULL) { | if (realpath(res, res1) != NULL) { | ||||
if (res != argv0) | if (res != argv0) | ||||
free(__DECONST(char *, res)); | free(__DECONST(char *, res)); | ||||
res = res1; | res = res1; | ||||
} else { | } else { | ||||
free(res1); | free(res1); | ||||
} | } | ||||
absres = xmalloc(strlen(abspath) + | |||||
strlen(res) + 2); | |||||
strcpy(absres, abspath); | |||||
strcat(absres, "/"); | |||||
strcat(absres, res); | |||||
free(abspath); | |||||
if (res != argv0) | |||||
free(__DECONST(char *, res)); | |||||
*binpath_res = absres; | |||||
} else { | |||||
*binpath_res = res; | |||||
} | } | ||||
} else { | |||||
*binpath_res = res; | *binpath_res = res; | ||||
} | |||||
return (fd); | return (fd); | ||||
} | } | ||||
/* | /* | ||||
* Parse a set of command-line arguments. | * Parse a set of command-line arguments. | ||||
*/ | */ | ||||
static int | static int | ||||
parse_args(char* argv[], int argc, bool *use_pathp, int *fdp) | parse_args(char* argv[], int argc, bool *use_pathp, int *fdp) | ||||
▲ Show 20 Lines • Show All 192 Lines • Show Last 20 Lines |
This will change /foo/symlink to /bar/target where we didn't before. That's not an enormous deal, but realpath will fail within a capsicum sandbox as it needs to be able to stat every component of the path, including "/". I'd prefer to only use realpath on relative paths for this reason.