diff options
author | netblue30 <netblue30@yahoo.com> | 2020-08-07 20:59:53 -0400 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2020-08-07 20:59:53 -0400 |
commit | 1f1d896f5aa9fc56862b65db370964920db7a9ba (patch) | |
tree | d5d9c92b2a11ebe222ccc8203c795ed4def88473 | |
parent | cleanup dummy.c, leftover form 0.9.60 release (diff) | |
download | firejail-1f1d896f5aa9fc56862b65db370964920db7a9ba.tar.gz firejail-1f1d896f5aa9fc56862b65db370964920db7a9ba.tar.zst firejail-1f1d896f5aa9fc56862b65db370964920db7a9ba.zip |
fixes for CVE-2020-17367 and CVE-2020-17368
-rw-r--r-- | src/firejail/output.c | 86 |
1 files changed, 60 insertions, 26 deletions
diff --git a/src/firejail/output.c b/src/firejail/output.c index bd7e44788..f7e6856dd 100644 --- a/src/firejail/output.c +++ b/src/firejail/output.c | |||
@@ -30,6 +30,12 @@ void check_output(int argc, char **argv) { | |||
30 | int enable_stderr = 0; | 30 | int enable_stderr = 0; |
31 | 31 | ||
32 | for (i = 1; i < argc; i++) { | 32 | for (i = 1; i < argc; i++) { |
33 | if (strncmp(argv[i], "--", 2) != 0) { | ||
34 | return; | ||
35 | } | ||
36 | if (strcmp(argv[i], "--") == 0) { | ||
37 | return; | ||
38 | } | ||
33 | if (strncmp(argv[i], "--output=", 9) == 0) { | 39 | if (strncmp(argv[i], "--output=", 9) == 0) { |
34 | outindex = i; | 40 | outindex = i; |
35 | break; | 41 | break; |
@@ -71,38 +77,66 @@ void check_output(int argc, char **argv) { | |||
71 | } | 77 | } |
72 | } | 78 | } |
73 | 79 | ||
74 | // build the new command line | 80 | int pipefd[2]; |
75 | int len = 0; | 81 | if (pipe(pipefd) == -1) { |
76 | for (i = 0; i < argc; i++) { | 82 | errExit("pipe"); |
77 | len += strlen(argv[i]) + 1; // + ' ' | ||
78 | } | 83 | } |
79 | len += 100 + strlen(LIBDIR) + strlen(outfile); // tee command | ||
80 | 84 | ||
81 | char *cmd = malloc(len + 1); // + '\0' | 85 | pid_t pid = fork(); |
82 | if (!cmd) | 86 | if (pid == -1) { |
83 | errExit("malloc"); | 87 | errExit("fork"); |
88 | } else if (pid == 0) { | ||
89 | /* child */ | ||
90 | if (dup2(pipefd[0], STDIN_FILENO) == -1) { | ||
91 | errExit("dup2"); | ||
92 | } | ||
93 | close(pipefd[1]); | ||
94 | if (pipefd[0] != STDIN_FILENO) { | ||
95 | close(pipefd[0]); | ||
96 | } | ||
84 | 97 | ||
85 | char *ptr = cmd; | 98 | char *args[3]; |
86 | for (i = 0; i < argc; i++) { | 99 | args[0] = LIBDIR "/firejail/ftee"; |
87 | if (strncmp(argv[i], "--output=", 9) == 0) | 100 | args[1] = outfile; |
88 | continue; | 101 | args[2] = NULL; |
89 | if (strncmp(argv[i], "--output-stderr=", 16) == 0) | 102 | execv(args[0], args); |
90 | continue; | 103 | perror("execvp"); |
91 | ptr += sprintf(ptr, "%s ", argv[i]); | 104 | exit(1); |
92 | } | 105 | } |
93 | 106 | ||
94 | if (enable_stderr) | 107 | /* parent */ |
95 | sprintf(ptr, "2>&1 | %s/firejail/ftee %s", LIBDIR, outfile); | 108 | if (dup2(pipefd[1], STDOUT_FILENO) == -1) { |
96 | else | 109 | errExit("dup2"); |
97 | sprintf(ptr, " | %s/firejail/ftee %s", LIBDIR, outfile); | 110 | } |
111 | if (enable_stderr && dup2(STDOUT_FILENO, STDERR_FILENO) == -1) { | ||
112 | errExit("dup2"); | ||
113 | } | ||
114 | close(pipefd[0]); | ||
115 | if (pipefd[1] != STDOUT_FILENO) { | ||
116 | close(pipefd[1]); | ||
117 | } | ||
98 | 118 | ||
99 | // run command | 119 | char **args = calloc(argc + 1, sizeof(char *)); |
100 | char *a[4]; | 120 | if (!args) { |
101 | a[0] = "/bin/bash"; | 121 | errExit("calloc"); |
102 | a[1] = "-c"; | 122 | } |
103 | a[2] = cmd; | 123 | bool found_separator = false; |
104 | a[3] = NULL; | 124 | /* copy argv into args, but drop --output(-stderr) arguments */ |
105 | execvp(a[0], a); | 125 | for (int i = 0, j = 0; i < argc; i++) { |
126 | if (!found_separator && i > 0) { | ||
127 | if (strncmp(argv[i], "--output=", 9) == 0) { | ||
128 | continue; | ||
129 | } | ||
130 | if (strncmp(argv[i], "--output-stderr=", 16) == 0) { | ||
131 | continue; | ||
132 | } | ||
133 | if (strncmp(argv[i], "--", 2) != 0 || strcmp(argv[i], "--") == 0) { | ||
134 | found_separator = true; | ||
135 | } | ||
136 | } | ||
137 | args[j++] = argv[i]; | ||
138 | } | ||
139 | execvp(args[0], args); | ||
106 | 140 | ||
107 | perror("execvp"); | 141 | perror("execvp"); |
108 | exit(1); | 142 | exit(1); |