[Bug,14442] Shell command injection vulnerability in mount.cifs
diff mbox series

Message ID bug-14442-10630-6ZWPinY5i4@https.bugzilla.samba.org/
State New
Headers show
Series
  • [Bug,14442] Shell command injection vulnerability in mount.cifs
Related show

Commit Message

samba-bugs@samba.org July 17, 2020, 5:21 p.m. UTC
https://bugzilla.samba.org/show_bug.cgi?id=14442

--- Comment #5 from Paulo Alcantara <pc@cjr.nz> ---
Did some changes after testing and reviewing with Aurelien:

+#endif
+
 /*
  * If systemd is running and systemd-ask-password --
  * is available, then use that else fallback on getpass(..)
@@ -1714,27 +1781,11 @@ get_password(const char *prompt, char *input, int
capacity)
                && (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

Patch
diff mbox series

diff --git a/mount.cifs.c b/mount.cifs.c
index 40918c18649f..6c98b9432f10 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;
+}