diff options
author | Simon McVittie <smcv@debian.org> | 2023-02-03 21:06:38 +0000 |
---|---|---|
committer | Simon McVittie <smcv@debian.org> | 2023-02-05 19:01:09 +0000 |
commit | 4fde420a7b25d1a54bdb4e4ade67770a5ac79d02 (patch) | |
tree | 595bfeb975e61e7eddc7927ff6bea3aade8fa22b | |
parent | a929c4c12375817954bfaedb8ea13568fcbb8b11 (diff) | |
download | accountsservice-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.c | 42 | ||||
-rw-r--r-- | src/util.c | 2 | ||||
-rw-r--r-- | src/util.h | 3 |
3 files changed, 30 insertions, 17 deletions
@@ -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; @@ -156,7 +156,7 @@ sys_log (GDBusMethodInvocation *context, syslog (LOG_NOTICE, "%s", msg); } -static gboolean +gboolean compat_check_exit_status (int estatus, GError **error) { @@ -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); |