diff options
Diffstat (limited to 'src/firejail/run_symlink.c')
-rw-r--r-- | src/firejail/run_symlink.c | 47 |
1 files changed, 6 insertions, 41 deletions
diff --git a/src/firejail/run_symlink.c b/src/firejail/run_symlink.c index ea3889024..b38cc0ca6 100644 --- a/src/firejail/run_symlink.c +++ b/src/firejail/run_symlink.c | |||
@@ -22,6 +22,8 @@ | |||
22 | #include <sys/stat.h> | 22 | #include <sys/stat.h> |
23 | #include <unistd.h> | 23 | #include <unistd.h> |
24 | 24 | ||
25 | extern char *find_in_path(const char *program); | ||
26 | |||
25 | void run_symlink(int argc, char **argv, int run_as_is) { | 27 | void run_symlink(int argc, char **argv, int run_as_is) { |
26 | EUID_ASSERT(); | 28 | EUID_ASSERT(); |
27 | 29 | ||
@@ -40,54 +42,17 @@ void run_symlink(int argc, char **argv, int run_as_is) { | |||
40 | errExit("setresuid"); | 42 | errExit("setresuid"); |
41 | 43 | ||
42 | // find the real program by looking in PATH | 44 | // find the real program by looking in PATH |
43 | char *p = getenv("PATH"); | 45 | if (!getenv("PATH")) { |
44 | if (!p) { | ||
45 | fprintf(stderr, "Error: PATH environment variable not set\n"); | 46 | fprintf(stderr, "Error: PATH environment variable not set\n"); |
46 | exit(1); | 47 | exit(1); |
47 | } | 48 | } |
48 | 49 | ||
49 | char *path = strdup(p); | 50 | char *p = find_in_path(program); |
50 | if (!path) | 51 | if (!p) { |
51 | errExit("strdup"); | ||
52 | |||
53 | char *selfpath = realpath("/proc/self/exe", NULL); | ||
54 | if (!selfpath) | ||
55 | errExit("realpath"); | ||
56 | |||
57 | // look in path for our program | ||
58 | char *tok = strtok(path, ":"); | ||
59 | int found = 0; | ||
60 | while (tok) { | ||
61 | char *name; | ||
62 | if (asprintf(&name, "%s/%s", tok, program) == -1) | ||
63 | errExit("asprintf"); | ||
64 | |||
65 | struct stat s; | ||
66 | if (stat(name, &s) == 0) { | ||
67 | /* coverity[toctou] */ | ||
68 | char* rp = realpath(name, NULL); | ||
69 | if (!rp) | ||
70 | errExit("realpath"); | ||
71 | |||
72 | if (strcmp(selfpath, rp) != 0) { | ||
73 | program = strdup(name); | ||
74 | found = 1; | ||
75 | free(rp); | ||
76 | break; | ||
77 | } | ||
78 | |||
79 | free(rp); | ||
80 | } | ||
81 | |||
82 | free(name); | ||
83 | tok = strtok(NULL, ":"); | ||
84 | } | ||
85 | if (!found) { | ||
86 | fprintf(stderr, "Error: cannot find the program in the path\n"); | 52 | fprintf(stderr, "Error: cannot find the program in the path\n"); |
87 | exit(1); | 53 | exit(1); |
88 | } | 54 | } |
89 | 55 | program = p; | |
90 | free(selfpath); | ||
91 | 56 | ||
92 | // restore original umask | 57 | // restore original umask |
93 | umask(orig_umask); | 58 | umask(orig_umask); |