summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <smcv@debian.org>2023-02-03 21:06:38 +0000
committerSimon McVittie <smcv@debian.org>2023-02-05 19:01:09 +0000
commit4fde420a7b25d1a54bdb4e4ade67770a5ac79d02 (patch)
tree595bfeb975e61e7eddc7927ff6bea3aade8fa22b
parenta929c4c12375817954bfaedb8ea13568fcbb8b11 (diff)
downloadaccountsservice-4fde420a7b25d1a54bdb4e4ade67770a5ac79d02.tar.gz
user: Replace usermod -p with chpasswd -e
Writing the password to chpasswd's standard input avoids it becoming visible in `/proc/$pid/cmdline` (CVE-2012-6655). Resolves: https://gitlab.freedesktop.org/accountsservice/accountsservice/-/issues/8 Bug-Debian: https://bugs.debian.org/757912 Signed-off-by: Simon McVittie <smcv@debian.org>
-rw-r--r--src/user.c42
-rw-r--r--src/util.c2
-rw-r--r--src/util.h3
3 files changed, 30 insertions, 17 deletions
diff --git a/src/user.c b/src/user.c
index 2203e69..5a6100d 100644
--- a/src/user.c
+++ b/src/user.c
@@ -2464,6 +2464,13 @@ user_set_password_mode (AccountsUser *auser,
}
static void
+free_passwords (gchar **strings)
+{
+ memset (strings[0], 0, strlen (strings[0]));
+ g_strfreev (strings);
+}
+
+static void
user_change_password_authorized_cb (Daemon *daemon,
User *user,
GDBusMethodInvocation *context,
@@ -2473,7 +2480,8 @@ user_change_password_authorized_cb (Daemon *daemon,
gchar **strings = data;
g_autoptr (GError) error = NULL;
- const gchar *argv[6];
+ g_autoptr (GSubprocess) process = NULL;
+ const char *argv[] = { "/usr/sbin/chpasswd", "-e", NULL };
sys_log (context,
"set password and hint of user '%s' (%d)",
@@ -2482,14 +2490,21 @@ user_change_password_authorized_cb (Daemon *daemon,
g_object_freeze_notify (G_OBJECT (user));
- argv[0] = "/usr/sbin/usermod";
- argv[1] = "-p";
- argv[2] = strings[0];
- argv[3] = "--";
- argv[4] = accounts_user_get_user_name (ACCOUNTS_USER (user));
- argv[5] = NULL;
+ process = g_subprocess_newv (argv,
+ G_SUBPROCESS_FLAGS_STDIN_PIPE,
+ &error);
- if (!spawn_sync (argv, &error)) {
+ if (process == NULL) {
+ throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message);
+ return;
+ }
+
+ if (!g_subprocess_communicate_utf8 (process, strings[0], NULL, NULL, NULL, &error)) {
+ throw_error (context, ERROR_FAILED, "writing input to '%s' failed: %s", argv[0], error->message);
+ return;
+ }
+
+ if (!compat_check_exit_status (g_subprocess_get_status (process), &error)) {
throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message);
return;
}
@@ -2505,13 +2520,6 @@ user_change_password_authorized_cb (Daemon *daemon,
accounts_user_complete_set_password (ACCOUNTS_USER (user), context);
}
-static void
-free_passwords (gchar **strings)
-{
- memset (strings[0], 0, strlen (strings[0]));
- g_strfreev (strings);
-}
-
static gboolean
user_set_password (AccountsUser *auser,
GDBusMethodInvocation *context,
@@ -2529,7 +2537,9 @@ user_set_password (AccountsUser *auser,
}
data = g_new (gchar *, 3);
- data[0] = g_strdup (password);
+ data[0] = g_strdup_printf ("%s:%s\n",
+ accounts_user_get_user_name (ACCOUNTS_USER (user)),
+ password);
data[1] = g_strdup (hint);
data[2] = NULL;
diff --git a/src/util.c b/src/util.c
index c8ba4cd..449d509 100644
--- a/src/util.c
+++ b/src/util.c
@@ -156,7 +156,7 @@ sys_log (GDBusMethodInvocation *context,
syslog (LOG_NOTICE, "%s", msg);
}
-static gboolean
+gboolean
compat_check_exit_status (int estatus,
GError **error)
{
diff --git a/src/util.h b/src/util.h
index 43e080b..d2cd6ed 100644
--- a/src/util.h
+++ b/src/util.h
@@ -49,3 +49,6 @@ void free_dirs (void);
const char *get_userdir (void);
const char *get_sysconfdir (void);
const char *get_icondir (void);
+
+gboolean compat_check_exit_status (int estatus,
+ GError **error);