diff options
author | Andreas Kling <kling@serenityos.org> | 2020-02-01 16:05:04 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-02-01 16:14:09 +0100 |
commit | 998765a7a63f406131bdf49b800482e98fffe8b9 (patch) | |
tree | c872d42f86f024b2c62b1194b40ca765d14af7c3 | |
parent | 268000e16641d4659a406b8a20eaf89bcddca1ac (diff) | |
download | serenity-998765a7a63f406131bdf49b800482e98fffe8b9.zip |
LibC: The exec() family of functions should not search "." by default
We should only execute the filename verbatim if it contains a slash (/)
character somewhere. Otherwise, we need to look through the entries in
the PATH environment variable.
This fixes an issue where you could easily "override" system programs
by placing them in a directory you control, and then waiting for
someone to come there and run e.g "ls" :^)
Test: LibC/exec-should-not-search-current-directory.cpp
-rw-r--r-- | Libraries/LibC/unistd.cpp | 9 | ||||
-rw-r--r-- | Tests/LibC/exec-should-not-search-current-directory.cpp | 20 |
2 files changed, 23 insertions, 6 deletions
diff --git a/Libraries/LibC/unistd.cpp b/Libraries/LibC/unistd.cpp index fe07434a68..db2434c7f4 100644 --- a/Libraries/LibC/unistd.cpp +++ b/Libraries/LibC/unistd.cpp @@ -111,13 +111,10 @@ int execve(const char* filename, char* const argv[], char* const envp[]) int execvpe(const char* filename, char* const argv[], char* const envp[]) { + if (strchr(filename, '/')) + return execve(filename, argv, envp); + ScopedValueRollback errno_rollback(errno); - int rc = execve(filename, argv, envp); - if (rc < 0 && errno != ENOENT) { - errno_rollback.set_override_rollback_value(errno); - dbg() << "execvpe() failed on first with" << strerror(errno); - return rc; - } String path = getenv("PATH"); if (path.is_empty()) path = "/bin:/usr/bin"; diff --git a/Tests/LibC/exec-should-not-search-current-directory.cpp b/Tests/LibC/exec-should-not-search-current-directory.cpp new file mode 100644 index 0000000000..57a023a6df --- /dev/null +++ b/Tests/LibC/exec-should-not-search-current-directory.cpp @@ -0,0 +1,20 @@ +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> + +int main() +{ + int fd = open("hax", O_CREAT | O_RDWR, 0755); + ftruncate(fd, 0); + close(fd); + + int rc = execlp("hax", "hax", nullptr); + int saved_errno = errno; + unlink("hax"); + if (rc == -1 && saved_errno == ENOEXEC) { + printf("FAIL\n"); + return 1; + } + printf("PASS\n"); + return 0; +} |