summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-02-01 16:05:04 +0100
committerAndreas Kling <kling@serenityos.org>2020-02-01 16:14:09 +0100
commit998765a7a63f406131bdf49b800482e98fffe8b9 (patch)
treec872d42f86f024b2c62b1194b40ca765d14af7c3
parent268000e16641d4659a406b8a20eaf89bcddca1ac (diff)
downloadserenity-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.cpp9
-rw-r--r--Tests/LibC/exec-should-not-search-current-directory.cpp20
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;
+}