Skip to content

Commit

Permalink
Fix wrapper_open redirects (#64)
Browse files Browse the repository at this point in the history
* Fix wrapper_open redirects

* Return boolean for redirected paths

* comments
  • Loading branch information
hensldm authored Dec 17, 2023
1 parent ea41a45 commit d6dd7fd
Showing 1 changed file with 36 additions and 23 deletions.
59 changes: 36 additions & 23 deletions libc_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -339,11 +339,11 @@ static void init_redirect_paths(void) {
}

/**
* Redirects `path` by replacing the initial segment `from` by `to`. The result is placed in `out`.
* If `path` does not have `from` as its initial segment, or there is no `to`, the original path is used.
* Redirects `path` by replacing the initial segment `from` by `to`. The result is placed in `out`, and true returned
* If `path` does not have `from` as its initial segment, or there is no `to`, false is returned.
* If an error occurs, an error message will be printed, and the program exited.
*/
void redirect_path(char* out, const char* path, const char* from, const char* to) {
bool redirect_path(char* out, const char* path, const char* from, const char* to) {
int from_len = strlen(from);

if ((strncmp(path, from, from_len) == 0) && (to[0] != '\0')) {
Expand All @@ -354,14 +354,15 @@ void redirect_path(char* out, const char* path, const char* from, const char* to

if ((n >= 0) && ((size_t)n < sizeof(redirected_path))) {
strcpy(out, redirected_path);
} else {
fprintf(stderr, "Error: Unable to redirect %s->%s for %s\n", from, to, path);
exit(1);
return true;
}
} else {
// memmove instead of strcpy to allow overlapping buffers
memmove(out, path, strlen(path) + 1);

// Redirection failed
fprintf(stderr, "Error: Unable to redirect %s->%s for %s\n", from, to, path);
exit(1);
}

return false;
}

typedef struct GlobalArgs {
Expand Down Expand Up @@ -1031,13 +1032,17 @@ uint32_t wrapper_strlen(uint8_t* mem, uint32_t str_addr) {
return len;
}

int wrapper_open(uint8_t* mem, uint32_t pathname_addr, int flags, int mode) {
STRING(pathname)
int wrapper_open(uint8_t* mem, uint32_t path_addr, int flags, int mode) {
STRING(path)

char rpathname[PATH_MAX + 1];
redirect_path(rpathname, pathname, "/usr/include", usr_include_redirect);
redirect_path(rpathname, pathname, "/usr/lib", usr_lib_redirect);
redirect_path(rpathname, pathname, "/lib", usr_lib_redirect);
char rpath[PATH_MAX + 1];
char* pathPtr = path;

if (redirect_path(rpath, path, "/usr/include", usr_include_redirect) ||
redirect_path(rpath, path, "/usr/lib", usr_lib_redirect) ||
redirect_path(rpath, path, "/lib", usr_lib_redirect) ) {
pathPtr = rpath;
}

int f = flags & O_ACCMODE;
if (flags & 0x100) {
Expand All @@ -1056,7 +1061,7 @@ int wrapper_open(uint8_t* mem, uint32_t pathname_addr, int flags, int mode) {
f |= O_APPEND;
}

int fd = open(rpathname, f, mode);
int fd = open(pathPtr, f, mode);
MEM_U32(ERRNO_ADDR) = errno;
return fd;
}
Expand Down Expand Up @@ -1471,11 +1476,15 @@ static uint32_t init_file(uint8_t* mem, int fd, int i, const char* path, const c
}

if (fd == -1) {
char rpathname[PATH_MAX + 1];
redirect_path(rpathname, path, "/usr/lib/DCC", usr_lib_redirect);
redirect_path(rpathname, rpathname, "/usr/lib", usr_lib_redirect);
char rpath[PATH_MAX + 1];
const char* pathPtr = path;

if (redirect_path(rpath, path, "/usr/lib/DCC", usr_lib_redirect) ||
redirect_path(rpath, path, "/usr/lib", usr_lib_redirect)) {
pathPtr = rpath;
}

fd = open(rpathname, flags, 0666);
fd = open(pathPtr, flags, 0666);

if (fd < 0) {
MEM_U32(ERRNO_ADDR) = errno;
Expand Down Expand Up @@ -2737,10 +2746,14 @@ int wrapper_execvp(uint8_t* mem, uint32_t file_addr, uint32_t argv_addr) {
char** argv = make_argv_from_mem(mem, argc, argv_addr);

char rfile[PATH_MAX + 1];
redirect_path(rfile, file, "/usr/lib/DCC", usr_lib_redirect);
redirect_path(rfile, rfile, "/usr/lib", usr_lib_redirect);
char* filePtr = file;

if (redirect_path(rfile, file, "/usr/lib/DCC", usr_lib_redirect) ||
redirect_path(rfile, file, "/usr/lib", usr_lib_redirect)) {
filePtr = rfile;
}

execvp(rfile, argv);
execvp(filePtr, argv);

MEM_U32(ERRNO_ADDR) = errno;

Expand Down

0 comments on commit d6dd7fd

Please sign in to comment.