Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix wrapper_open redirects #64

Merged
merged 3 commits into from
Dec 17, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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