Subject: gdm3: CVE-2013-7273 gdm-3.4.1-8 patch proposal Package: gdm3 Version: 3.4.1-8 Severity: important Tags: patch
Dear Maintainer, I have 120 public debian Wheezy hosts on my network where user list is disabled in gdm. This bug is very annoying for me because it crash gdm and few users know how to restart the X server (ctr-alt-return). So the stations stay unusable. In reality this bug not only occur when cancel or escape is pressed. It is a event order/time issue, on certain station it appears when the login is typed to early after the window reset. So here my bug fix proposal and explanations for the gui/simple-greeter/gdm-greeter-login-window.c source. ------------------- Gdm simple greeter reset the login dialog with the following function : (line 1082) gboolean gdm_greeter_login_window_reset (GdmGreeterLoginWindow *login_window) { g_debug ("GdmGreeterLoginWindow: window reset"); g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE); reset_dialog_after_messages (login_window, MODE_SELECTION); g_list_foreach (login_window->priv->extensions, (GFunc) restart_extension_conversation, login_window); g_free (login_window->priv->service_name_of_session_ready_to_start); login_window->priv->service_name_of_session_ready_to_start = NULL; return TRUE; } We can see that gdm reset the dialog and next restart the extension conversations. The problem is that the "reset_dialog_after_messages" is not a blocking function. If there are pending messages it return immediately without resetting the dialog. The function is called again when all extension messages are flushed : (line 923) static void reset_dialog_after_messages (GdmGreeterLoginWindow *login_window, guint dialog_mode) { if (has_queued_messages (login_window)) { g_debug ("GdmGreeterLoginWindow: will reset dialog after pending messages"); login_window->priv->next_mode = dialog_mode; } else { g_debug ("GdmGreeterLoginWindow: resetting dialog"); reset_dialog (login_window, dialog_mode); } } Thus, in the public gdm_greeter_login_window_reset call, if there are pending messages, the extension conversations are restarted before the reset_dialog call (that reset all the extensions). So gdm stay in a idle state. If needed I can explain why this bug is only a problem when user list is disabled. In a patch I just added a boolean and moved the restart_conversation code to reset_dialog_after_message to be sure that it is called after reset_dialog. It seems to works. Thanks. PELLEGRIN Baptiste. -- System Information: Debian Release: 7.3 APT prefers stable-updates APT policy: (500, 'stable-updates'), (500, 'stable') Architecture: i386 (i686) Kernel: Linux 3.2.0-4-686-pae (SMP w/2 CPU cores) Locale: LANG=en_US.utf8, LC_CTYPE=en_US.utf8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Versions of packages gdm3 depends on: ii accountsservice 0.6.21-8 ii adduser 3.113+nmu3 ii dconf-gsettings-backend 0.12.1-3 ii dconf-tools 0.12.1-3 ii debconf [debconf-2.0] 1.5.49 ii dpkg 1.16.12 ii gir1.2-freedesktop 1.32.1-1 ii gir1.2-glib-2.0 1.32.1-1 ii gnome-session [x-session-manager] 3.4.2.1-4 ii gnome-session-bin 3.4.2.1-4 ii gnome-session-fallback [x-session-manage 3.4.2.1-4 ii gnome-settings-daemon 3.4.2+git20121218.7c1322-3+deb7u3 ii gnome-terminal [x-terminal-emulator] 3.4.1.1-2 ii gsettings-desktop-schemas 3.4.2-3 ii libaccountsservice0 0.6.21-8 ii libatk1.0-0 2.4.0-2 ii libattr1 1:2.4.46-8 ii libaudit0 1:1.7.18-1.1 ii libc6 2.13-38 ii libcairo-gobject2 1.12.2-3 ii libcairo2 1.12.2-3 ii libcanberra-gtk3-0 0.28-6 ii libcanberra0 0.28-6 ii libdbus-1-3 1.6.8-1+deb7u1 ii libdbus-glib-1-2 0.100.2-1 ii libfontconfig1 2.9.0-7.1 ii libgdk-pixbuf2.0-0 2.26.1-1 ii libglib2.0-0 2.33.12+really2.32.4-5 ii libglib2.0-bin 2.33.12+really2.32.4-5 ii libgtk-3-0 3.4.2-7 ii libpam-modules 1.1.3-7.1 ii libpam-runtime 1.1.3-7.1 ii libpam0g 1.1.3-7.1 ii libpango1.0-0 1.30.0-1 ii librsvg2-common 2.36.1-2 ii libselinux1 2.1.9-5 ii libupower-glib1 0.9.17-1 ii libwrap0 7.6.q-24 ii libx11-6 2:1.5.0-1+deb7u1 ii libxau6 1:1.0.7-1 ii libxdmcp6 1:1.1.1-1 ii libxklavier16 5.2.1-1 ii libxrandr2 2:1.3.2-2+deb7u1 ii lsb-base 4.1+Debian8+deb7u1 ii metacity [x-window-manager] 1:2.34.3-4 ii policykit-1-gnome 0.105-2 ii upower 0.9.17-1 ii x11-common 1:7.7+3~deb7u1 ii x11-xserver-utils 7.7~3 ii xterm [x-terminal-emulator] 278-4 Versions of packages gdm3 recommends: ii at-spi2-core 2.5.3-2 ii desktop-base 7.0.3 ii gnome-icon-theme 3.4.0-2 ii gnome-icon-theme-symbolic 3.4.0-2 ii x11-xkb-utils 7.7~1 ii xserver-xephyr 2:1.12.4-6+deb7u2 ii xserver-xorg 1:7.7+3~deb7u1 ii zenity 3.4.0-2 Versions of packages gdm3 suggests: ii gnome-orca 3.4.2-2 ii gnome-shell 3.4.2-7+deb7u1 pn gok <none> ii libpam-gnome-keyring 3.4.1-5 -- Configuration Files: /etc/gdm3/daemon.conf changed [not included] -- debconf information excluded
Index: gdm3-3.4.1/gui/simple-greeter/gdm-greeter-login-window.c =================================================================== --- gdm3-3.4.1.orig/gui/simple-greeter/gdm-greeter-login-window.c 2014-06-10 13:36:48.000000000 +0200 +++ gdm3-3.4.1/gui/simple-greeter/gdm-greeter-login-window.c 2014-06-10 14:15:03.811245189 +0200 @@ -147,6 +147,7 @@ guint start_session_handler_id; char *service_name_of_session_ready_to_start; + gboolean restart_conversation_after_reset; }; enum { @@ -187,6 +188,9 @@ static void handle_stopped_conversation (GdmGreeterLoginWindow *login_window, const char *service_name); +static gboolean restart_extension_conversation (GdmLoginExtension *extension, + GdmGreeterLoginWindow *login_window); + static void begin_single_service_verification (GdmGreeterLoginWindow *login_window, const char *service_name); @@ -922,6 +926,12 @@ } else { g_debug ("GdmGreeterLoginWindow: resetting dialog"); reset_dialog (login_window, dialog_mode); + if(login_window->priv->restart_conversation_after_reset) { + g_list_foreach (login_window->priv->extensions, + (GFunc) restart_extension_conversation, + login_window); + login_window->priv->restart_conversation_after_reset = FALSE; + } } } @@ -1085,10 +1095,8 @@ g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE); + login_window->priv->restart_conversation_after_reset = TRUE; reset_dialog_after_messages (login_window, MODE_SELECTION); - g_list_foreach (login_window->priv->extensions, - (GFunc) restart_extension_conversation, - login_window); g_free (login_window->priv->service_name_of_session_ready_to_start); login_window->priv->service_name_of_session_ready_to_start = NULL; @@ -2565,6 +2573,7 @@ user_list_disable = g_settings_get_boolean (settings, KEY_DISABLE_USER_LIST); login_window->priv->user_list_disabled = user_list_disable; + login_window->priv->restart_conversation_after_reset = FALSE; gtk_window_set_title (GTK_WINDOW (login_window), _("Login Window")); /*gtk_window_set_opacity (GTK_WINDOW (login_window), 0.85);*/