Hello community,

here is the log from the commit of package cifs-utils for openSUSE:Factory 
checked in at 2020-09-09 17:45:49
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/cifs-utils (Old)
 and      /work/SRC/openSUSE:Factory/.cifs-utils.new.3399 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "cifs-utils"

Wed Sep  9 17:45:49 2020 rev:64 rq:832360 version:6.9

Changes:
--------
--- /work/SRC/openSUSE:Factory/cifs-utils/cifs-utils.changes    2020-04-15 
20:07:59.370166138 +0200
+++ /work/SRC/openSUSE:Factory/.cifs-utils.new.3399/cifs-utils.changes  
2020-09-09 17:45:55.290376831 +0200
@@ -1,0 +2,7 @@
+Mon Aug 10 06:56:11 UTC 2020 - Aurelien Aptel <aap...@suse.com>
+
+- CVE-2020-14342: Shell command injection vulnerability in mount.cifs;
+  (bsc#1174477); (bso#14442); CVE-2020-14342.
+  * add 0013-CVE-2020-14342-mount.cifs-fix-shell-command-injectio.patch
+
+-------------------------------------------------------------------

New:
----
  0013-CVE-2020-14342-mount.cifs-fix-shell-command-injectio.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ cifs-utils.spec ++++++
--- /var/tmp/diff_new_pack.3tnQS7/_old  2020-09-09 17:45:56.618377909 +0200
+++ /var/tmp/diff_new_pack.3tnQS7/_new  2020-09-09 17:45:56.622377913 +0200
@@ -44,11 +44,12 @@
 Patch9:         0010-Zero-fill-the-allocated-memory-for-a-new-ACE.patch
 Patch10:        0011-fix-doublefree.patch
 Patch11:        0012-mount.cifs-Fix-invalid-free.patch
+Patch12:        0013-CVE-2020-14342-mount.cifs-fix-shell-command-injectio.patch
 
 # cifs-utils 6.8 switched to python for man page generation
 # we need to require either py2 or py3 package
 # some products do not have a py2/py3 versions
-%if 0%{?suse_version} > 1500 || 0%{?sle_version} >= 120000
+%if 0%{?suse_version} >= 1500
 BuildRequires:  python3-docutils
 %else
 BuildRequires:  python-docutils
@@ -132,6 +133,7 @@
 %patch9 -p1
 %patch10 -p1
 %patch11 -p1
+%patch12 -p1
 
 %build
 export CFLAGS="%{optflags} -D_GNU_SOURCE -fpie"

++++++ 0013-CVE-2020-14342-mount.cifs-fix-shell-command-injectio.patch ++++++
>From 610ea2412e2f31fbf3e662bf7dfadf7d73ce2934 Mon Sep 17 00:00:00 2001
From: Aurelien Aptel <aap...@suse.com>
Date: Mon, 27 Jul 2020 10:34:44 +0200
Subject: [PATCH] CVE-2020-14342: mount.cifs: fix shell command injection

A bug has been reported recently for the mount.cifs utility which is
part of the cifs-utils package. The tool has a shell injection issue
where one can embed shell commands via the username mount option. Those
commands will be run via popen() in the context of the user calling
mount.

The bug requires cifs-utils to be built with --with-systemd (enabled
by default if supported).

A quick test to check if the mount.cifs binary is vulnerable is to look
for popen() calls like so:

    $ nm mount.cifs | grep popen
    U popen@@GLIBC_2.2.5

If the user is allowed to run mount.cifs via sudo, he can obtain a root
shell.

    sudo mount.cifs -o username='`sh`' //1 /mnt

If mount.cifs has the setuid bit, the command will still be run as the
calling user (no privilege escalation).

The bug was introduced in June 2012 with commit 4e264031d0da7d3f2
("mount.cifs: Use systemd's mechanism for getting password, if
present.").

Affected versions:
  cifs-utils-5.6
  cifs-utils-5.7
  cifs-utils-5.8
  cifs-utils-5.9
  cifs-utils-6.0
  cifs-utils-6.1
  cifs-utils-6.2
  cifs-utils-6.3
  cifs-utils-6.4
  cifs-utils-6.5
  cifs-utils-6.6
  cifs-utils-6.7
  cifs-utils-6.8
  cifs-utils-6.9
  cifs-utils-6.10

Bug: https://bugzilla.samba.org/show_bug.cgi?id=14442
Reported-by: Vadim Lebedev <va...@mbdsys.com>

Signed-off-by: Paulo Alcantara (SUSE) <pa...@paulo.ac>
Signed-off-by: Aurelien Aptel <aap...@suse.com>
---
 mount.cifs.c | 96 ++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 75 insertions(+), 21 deletions(-)

diff --git a/mount.cifs.c b/mount.cifs.c
index 40918c1..4feb397 100644
--- a/mount.cifs.c
+++ b/mount.cifs.c
@@ -1695,6 +1695,73 @@ drop_child_privs(void)
        return 0;
 }
 
+#ifdef ENABLE_SYSTEMD
+static int get_passwd_by_systemd(const char *prompt, char *input, int capacity)
+{
+       int fd[2];
+       pid_t pid;
+       int offs = 0;
+       int rc = 1;
+
+       if (pipe(fd) == -1) {
+               fprintf(stderr, "Failed to create pipe: %s\n", strerror(errno));
+               return 1;
+       }
+
+       pid = fork();
+       if (pid == -1) {
+               fprintf(stderr, "Unable to fork: %s\n", strerror(errno));
+               close(fd[0]);
+               close(fd[1]);
+               return 1;
+       }
+       if (pid == 0) {
+               close(fd[0]);
+               dup2(fd[1], STDOUT_FILENO);
+               if (execlp("systemd-ask-password", "systemd-ask-password", 
prompt, NULL) == -1) {
+                       fprintf(stderr, "Failed to execute 
systemd-ask-password: %s\n",
+                               strerror(errno));
+               }
+               exit(1);
+       }
+
+       close(fd[1]);
+       for (;;) {
+               if (offs+1 >= capacity) {
+                       fprintf(stderr, "Password too long.\n");
+                       kill(pid, SIGTERM);
+                       rc = 1;
+                       break;
+               }
+               rc = read(fd[0], input + offs, capacity - offs);
+               if (rc == -1) {
+                       fprintf(stderr, "Failed to read from pipe: %s\n", 
strerror(errno));
+                       rc = 1;
+                       break;
+               }
+               if (!rc)
+                       break;
+               offs += rc;
+               input[offs] = '\0';
+       }
+       if (wait(&rc) == -1) {
+               fprintf(stderr, "Failed to wait child: %s\n", strerror(errno));
+               rc = 1;
+               goto out;
+       }
+       if (!WIFEXITED(rc) || WEXITSTATUS(rc)) {
+               rc = 1;
+               goto out;
+       }
+
+       rc = 0;
+
+out:
+       close(fd[0]);
+       return rc;
+}
+#endif
+
 /*
  * If systemd is running and systemd-ask-password --
  * is available, then use that else fallback on getpass(..)
@@ -1708,35 +1775,22 @@ get_password(const char *prompt, char *input, int 
capacity)
        int is_systemd_running;
        struct stat a, b;
 
+       memset(input, 0, capacity);
+
        /* We simply test whether the systemd cgroup hierarchy is
         * mounted */
        is_systemd_running = (lstat("/sys/fs/cgroup", &a) == 0)
                && (lstat("/sys/fs/cgroup/systemd", &b) == 0)
                && (a.st_dev != b.st_dev);
 
-       if (is_systemd_running) {
-               char *cmd, *ret;
-               FILE *ask_pass_fp = NULL;
-
-               cmd = ret = NULL;
-               if (asprintf(&cmd, "systemd-ask-password \"%s\"", prompt) >= 0) 
{
-                       ask_pass_fp = popen (cmd, "re");
-                       free (cmd);
-               }
-
-               if (ask_pass_fp) {
-                       ret = fgets(input, capacity, ask_pass_fp);
-                       pclose(ask_pass_fp);
-               }
-
-               if (ret) {
-                       int len = strlen(input);
-                       if (input[len - 1] == '\n')
-                               input[len - 1] = '\0';
-                       return input;
-               }
+       if (is_systemd_running && !get_passwd_by_systemd(prompt, input, 
capacity)) {
+               int len = strlen(input);
+               if (input[len - 1] == '\n')
+                       input[len - 1] = '\0';
+               return input;
        }
 #endif
+       memset(input, 0, capacity);
 
        /*
         * Falling back to getpass(..)
-- 
2.27.0




Reply via email to