aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2020-08-07 20:59:53 -0400
committerLibravatar netblue30 <netblue30@yahoo.com>2020-08-07 20:59:53 -0400
commit1f1d896f5aa9fc56862b65db370964920db7a9ba (patch)
treed5d9c92b2a11ebe222ccc8203c795ed4def88473
parentcleanup dummy.c, leftover form 0.9.60 release (diff)
downloadfirejail-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.c86
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);