diff --git a/firejail.changes b/firejail.changes index 708a603..45f0eeb 100644 --- a/firejail.changes +++ b/firejail.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Sat Aug 8 16:56:43 UTC 2020 - Sebastian Wagner + +- Add patches fix-CVE-2020-17367.patch and fix-CVE-2020-17368.patch to fix CVE-2020-17367 and CVE-2020-17368 and boo#1174986 + ------------------------------------------------------------------- Wed Apr 29 11:30:38 UTC 2020 - Michael Vetter diff --git a/firejail.spec b/firejail.spec index 46137ce..be7bc4a 100644 --- a/firejail.spec +++ b/firejail.spec @@ -27,6 +27,10 @@ Source0: http://downloads.sourceforge.net/%{name}/%{name}-%{version}.tar. Source1: http://downloads.sourceforge.net/%{name}/%{name}-%{version}.tar.xz.asc # PATCH-FIX-OPENSUSE firejail-0.9.62-fix-usr-etc.patch -- https://github.com/netblue30/firejail/issues/3145 two patches combined, source see file Patch0: firejail-0.9.62-fix-usr-etc.patch +# PATHCH-FIX-UPSTREAM fix-CVE-2020-17367 -- fixes boo#1174986 +Patch1: https://github.com/netblue30/firejail/commit/2c734d6350ad321fccbefc5ef0382199ac331b37.patch#/fix-CVE-2020-17367.patch +# PATHCH-FIX-UPSTREAM fix-CVE-2020-17368 -- fixes boo#1174986 +Patch2: https://github.com/netblue30/firejail/commit/34193604fed04cad2b7b6b0f1a3a0428afd9ed5b.patch#/fix-CVE-2020-17368.patch BuildRequires: fdupes BuildRequires: gcc-c++ BuildRequires: libapparmor-devel @@ -45,6 +49,8 @@ Linux namespace support. It supports sandboxing specific users upon login. %prep %setup -q %patch0 -p1 +%patch1 -p1 +%patch2 -p1 sed -i '1s/^#!\/usr\/bin\/env /#!\/usr\/bin\//' contrib/fj-mkdeb.py contrib/fjclip.py contrib/fjdisplay.py contrib/fjresize.py contrib/sort.py %build diff --git a/fix-CVE-2020-17367.patch b/fix-CVE-2020-17367.patch new file mode 100644 index 0000000..e3591f9 --- /dev/null +++ b/fix-CVE-2020-17367.patch @@ -0,0 +1,35 @@ +From 2c734d6350ad321fccbefc5ef0382199ac331b37 Mon Sep 17 00:00:00 2001 +From: Reiner Herrmann +Date: Wed, 29 Jul 2020 20:16:16 +0200 +Subject: [PATCH] firejail: don't interpret output arguments after + end-of-options tag + +Firejail was parsing --output and --output-stderr options even after +the end-of-options separator ("--"), which would allow someone who +has control over command line options of the sandboxed application, +to write data to a specified file. + +Fixes: CVE-2020-17367 + +Reported-by: Tim Starling +--- + src/firejail/output.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/firejail/output.c b/src/firejail/output.c +index d4a7f464a..6e678afd3 100644 +--- a/src/firejail/output.c ++++ b/src/firejail/output.c +@@ -30,6 +30,12 @@ void check_output(int argc, char **argv) { + int enable_stderr = 0; + + for (i = 1; i < argc; i++) { ++ if (strncmp(argv[i], "--", 2) != 0) { ++ return; ++ } ++ if (strcmp(argv[i], "--") == 0) { ++ return; ++ } + if (strncmp(argv[i], "--output=", 9) == 0) { + outindex = i; + break; diff --git a/fix-CVE-2020-17368.patch b/fix-CVE-2020-17368.patch new file mode 100644 index 0000000..df97325 --- /dev/null +++ b/fix-CVE-2020-17368.patch @@ -0,0 +1,121 @@ +From 34193604fed04cad2b7b6b0f1a3a0428afd9ed5b Mon Sep 17 00:00:00 2001 +From: Reiner Herrmann +Date: Wed, 29 Jul 2020 20:22:52 +0200 +Subject: [PATCH] firejail: don't pass command line through shell when + redirecting output + +When redirecting output via --output or --output-stderr, firejail was +concatenating all command line arguments into a single string +that was passed to a shell. As the arguments were no longer escaped, +the shell was able to interpret them. +Someone who has control over the command line arguments of the +sandboxed application could use this to run arbitrary other commands. + +Instead of passing it through a shell for piping the output to ftee, +the pipeline is now manually created and the processes are executed +directly. + +Fixes: CVE-2020-17368 + +Reported-by: Tim Starling +--- + src/firejail/output.c | 80 +++++++++++++++++++++++++++++-------------- + 1 file changed, 54 insertions(+), 26 deletions(-) + +diff --git a/src/firejail/output.c b/src/firejail/output.c +index 6e678afd3..0e961bb61 100644 +--- a/src/firejail/output.c ++++ b/src/firejail/output.c +@@ -77,38 +77,66 @@ void check_output(int argc, char **argv) { + } + } + +- // build the new command line +- int len = 0; +- for (i = 0; i < argc; i++) { +- len += strlen(argv[i]) + 1; // + ' ' ++ int pipefd[2]; ++ if (pipe(pipefd) == -1) { ++ errExit("pipe"); + } +- len += 100 + strlen(LIBDIR) + strlen(outfile); // tee command + +- char *cmd = malloc(len + 1); // + '\0' +- if (!cmd) +- errExit("malloc"); ++ pid_t pid = fork(); ++ if (pid == -1) { ++ errExit("fork"); ++ } else if (pid == 0) { ++ /* child */ ++ if (dup2(pipefd[0], STDIN_FILENO) == -1) { ++ errExit("dup2"); ++ } ++ close(pipefd[1]); ++ if (pipefd[0] != STDIN_FILENO) { ++ close(pipefd[0]); ++ } + +- char *ptr = cmd; +- for (i = 0; i < argc; i++) { +- if (strncmp(argv[i], "--output=", 9) == 0) +- continue; +- if (strncmp(argv[i], "--output-stderr=", 16) == 0) +- continue; +- ptr += sprintf(ptr, "%s ", argv[i]); ++ char *args[3]; ++ args[0] = LIBDIR "/firejail/ftee"; ++ args[1] = outfile; ++ args[2] = NULL; ++ execv(args[0], args); ++ perror("execvp"); ++ exit(1); + } + +- if (enable_stderr) +- sprintf(ptr, "2>&1 | %s/firejail/ftee %s", LIBDIR, outfile); +- else +- sprintf(ptr, " | %s/firejail/ftee %s", LIBDIR, outfile); ++ /* parent */ ++ if (dup2(pipefd[1], STDOUT_FILENO) == -1) { ++ errExit("dup2"); ++ } ++ if (enable_stderr && dup2(STDOUT_FILENO, STDERR_FILENO) == -1) { ++ errExit("dup2"); ++ } ++ close(pipefd[0]); ++ if (pipefd[1] != STDOUT_FILENO) { ++ close(pipefd[1]); ++ } + +- // run command +- char *a[4]; +- a[0] = "/bin/bash"; +- a[1] = "-c"; +- a[2] = cmd; +- a[3] = NULL; +- execvp(a[0], a); ++ char **args = calloc(argc + 1, sizeof(char *)); ++ if (!args) { ++ errExit("calloc"); ++ } ++ bool found_separator = false; ++ /* copy argv into args, but drop --output(-stderr) arguments */ ++ for (int i = 0, j = 0; i < argc; i++) { ++ if (!found_separator && i > 0) { ++ if (strncmp(argv[i], "--output=", 9) == 0) { ++ continue; ++ } ++ if (strncmp(argv[i], "--output-stderr=", 16) == 0) { ++ continue; ++ } ++ if (strncmp(argv[i], "--", 2) != 0 || strcmp(argv[i], "--") == 0) { ++ found_separator = true; ++ } ++ } ++ args[j++] = argv[i]; ++ } ++ execvp(args[0], args); + + perror("execvp"); + exit(1);