Hello community,

here is the log from the commit of package lightdm for openSUSE:Factory checked 
in at 2013-02-01 09:45:28
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/lightdm (Old)
 and      /work/SRC/openSUSE:Factory/.lightdm.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "lightdm", Maintainer is ""

Changes:
--------
--- /work/SRC/openSUSE:Factory/lightdm/lightdm.changes  2013-01-31 
10:27:21.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.lightdm.new/lightdm.changes     2013-02-01 
09:45:29.000000000 +0100
@@ -1,0 +2,10 @@
+Thu Jan 31 18:17:14 UTC 2013 - [email protected]
+
+- added lightdm-use-fine-grained-memory-locking.patch in order to
+  use libgcrypt to selectively secure password memory instead of
+  the big-hammer approach of mlockall (backported from upstrem bzr)
+- added lightdm-fix-determining-active-display.patch in order to
+  correctly work out the active display from the active VT when it
+  exits so a greeter starts (backported from upstrem bzr)
+
+-------------------------------------------------------------------

New:
----
  lightdm-fix-determining-active-display.patch
  lightdm-use-fine-grained-memory-locking.patch

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

Other differences:
------------------
++++++ lightdm.spec ++++++
--- /var/tmp/diff_new_pack.xqQdPy/_old  2013-02-01 09:45:32.000000000 +0100
+++ /var/tmp/diff_new_pack.xqQdPy/_new  2013-02-01 09:45:32.000000000 +0100
@@ -60,6 +60,10 @@
 Patch8:         lightdm-do-not-strip-codeset-from-language.patch
 # PATCH-FIX-OPENSUSE lightdm-use-run-dir.patch [email protected] -- Use /run 
instead of /var/run
 Patch9:         lightdm-use-run-dir.patch
+# PATCH-FIX-UPSTREAM lightdm-fix-determining-active-display.patch 
[email protected] -- Correctly work out the active display from the active VT 
when it exits so a greeter starts (backported from upstrem bzr)
+Patch10:        lightdm-fix-determining-active-display.patch
+# PATCH-FIX-UPSTREAM lightdm-use-fine-grained-memory-locking.patch 
[email protected] -- Use libgcrypt to selectively secure password memory 
instead of the big-hammer approach of mlockall (backported from upstrem bzr)
+Patch11:        lightdm-use-fine-grained-memory-locking.patch
 BuildRequires:  gcc-c++
 BuildRequires:  gnome-common
 BuildRequires:  gtk-doc
@@ -72,6 +76,7 @@
 BuildRequires:  xdm
 %endif
 BuildRequires:  polkit
+BuildRequires:  libgcrypt-devel
 BuildRequires:  pkgconfig(gobject-introspection-1.0)
 BuildRequires:  pkgconfig(gio-2.0)
 BuildRequires:  pkgconfig(gio-unix-2.0)
@@ -158,6 +163,8 @@
 %if 0%{?suse_version} >= 1230
 %patch9 -p1
 %endif
+%patch10 -p1
+%patch11 -p1
 
 %build
 ./autogen.sh

++++++ lightdm-fix-determining-active-display.patch ++++++
# HG changeset patch
# User Robert Ancell <[email protected]>
# Date 1354075156 -46800
# Branch lightdm
# Node ID ed6e0407be07304f9a7e95b1723205363e2914f7
# Parent a2ded106d9a556fbadb661003e300cd3d0c49a1f
Correctly work out the active display from the active VT when it exits so a 
greeter starts

diff --git a/src/display.c b/src/display.c
--- a/src/display.c
+++ b/src/display.c
@@ -112,8 +112,11 @@ static void user_session_stopped_cb (Ses
 Display *
 display_new (DisplayServer *display_server)
 {
-    Display *display = g_object_new (DISPLAY_TYPE, NULL);
+    Display *display;
 
+    g_return_val_if_fail (display_server != NULL, NULL);
+  
+    display = g_object_new (DISPLAY_TYPE, NULL);
     display->priv->display_server = g_object_ref (display_server);
 
     return display;
@@ -604,7 +607,7 @@ greeter_session_stopped_cb (Session *ses
         return;
     }
 
-    if (!display->priv->display_server)
+    if (display_server_get_is_stopped (display->priv->display_server))
         return;
 
     /* Start the session for the authenticated user */
@@ -764,10 +767,6 @@ display_server_stopped_cb (DisplayServer
 {
     g_debug ("Display server stopped");
 
-    g_signal_handlers_disconnect_matched (display->priv->display_server, 
G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, display);
-    g_object_unref (display->priv->display_server);
-    display->priv->display_server = NULL;
-
     /* Stop this display, it will be restarted by the seat if necessary */
     display_stop (display);
 }
@@ -835,47 +834,6 @@ display_start (Display *display)
     return TRUE;
 }
 
-void
-display_stop (Display *display)
-{
-    g_return_if_fail (display != NULL);
-
-    if (display->priv->stopped)
-        return;
-
-    if (!display->priv->stopping)
-    {
-        g_debug ("Stopping display");
-        display->priv->stopping = TRUE;
-    }
-
-    /* Stop the session first */
-    if (display->priv->session)
-    {
-        session_stop (display->priv->session);
-        if (display->priv->session && !session_get_is_stopped 
(display->priv->session))
-            return;
-        g_signal_handlers_disconnect_matched (display->priv->session, 
G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, display);
-        g_object_unref (display->priv->session);
-        display->priv->session = NULL;
-    }
-
-    /* Stop the display server after that */
-    if (display->priv->display_server)
-    {
-        display_server_stop (display->priv->display_server);
-        if (display->priv->display_server && !display_server_get_is_stopped 
(display->priv->display_server))
-            return;
-        g_signal_handlers_disconnect_matched (display->priv->display_server, 
G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, display);
-        g_object_unref (display->priv->display_server);
-        display->priv->display_server = NULL;
-    }
-
-    display->priv->stopped = TRUE;
-    g_debug ("Display stopped");
-    g_signal_emit (display, signals[STOPPED], 0);
-}
-
 gboolean
 display_get_is_ready (Display *display)
 {
@@ -910,6 +868,51 @@ display_unlock (Display *display)
     session_unlock (display->priv->session);
 }
 
+void
+display_stop (Display *display)
+{
+    g_return_if_fail (display != NULL);
+
+    if (display->priv->stopped)
+        return;
+
+    if (!display->priv->stopping)
+    {
+        g_debug ("Stopping display");
+        display->priv->stopping = TRUE;
+    }
+
+    /* Stop the session first */
+    if (display->priv->session)
+    {
+        session_stop (display->priv->session);
+        if (display->priv->session && !session_get_is_stopped 
(display->priv->session))
+            return;
+        g_signal_handlers_disconnect_matched (display->priv->session, 
G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, display);
+        g_object_unref (display->priv->session);
+        display->priv->session = NULL;
+    }
+
+    /* Stop the display server after that */
+    if (!display_server_get_is_stopped (display->priv->display_server))
+    {
+        display_server_stop (display->priv->display_server);
+        if (!display_server_get_is_stopped (display->priv->display_server))
+            return;
+    }
+
+    display->priv->stopped = TRUE;
+    g_debug ("Display stopped");
+    g_signal_emit (display, signals[STOPPED], 0);
+}
+
+gboolean
+display_get_is_stopped (Display *display)
+{
+    g_return_val_if_fail (display != NULL, FALSE);
+    return display->priv->stopped;
+}
+
 static gboolean
 display_real_switch_to_user (Display *display, User *user)
 {
@@ -941,11 +944,8 @@ display_finalize (GObject *object)
 
     self = DISPLAY (object);
 
-    if (self->priv->display_server)
-    {
-        g_signal_handlers_disconnect_matched (self->priv->display_server, 
G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);
-        g_object_unref (self->priv->display_server);
-    }
+    g_signal_handlers_disconnect_matched (self->priv->display_server, 
G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);
+    g_object_unref (self->priv->display_server);
     g_free (self->priv->greeter_session);
     if (self->priv->greeter)
     {
diff --git a/src/display.h b/src/display.h
--- a/src/display.h
+++ b/src/display.h
@@ -90,6 +90,8 @@ void display_unlock (Display *display);
 
 void display_stop (Display *display);
 
+gboolean display_get_is_stopped (Display *display);
+
 G_END_DECLS
 
 #endif /* _DISPLAY_H_ */
diff --git a/src/seat-xdmcp-session.c b/src/seat-xdmcp-session.c
--- a/src/seat-xdmcp-session.c
+++ b/src/seat-xdmcp-session.c
@@ -64,12 +64,6 @@ seat_xdmcp_session_create_session (Seat 
 }
 
 static void
-seat_xdmcp_session_display_removed (Seat *seat, Display *display)
-{
-   seat_stop (seat);
-}
-
-static void
 seat_xdmcp_session_init (SeatXDMCPSession *seat)
 {
     seat->priv = G_TYPE_INSTANCE_GET_PRIVATE (seat, SEAT_XDMCP_SESSION_TYPE, 
SeatXDMCPSessionPrivate);
@@ -95,7 +89,6 @@ seat_xdmcp_session_class_init (SeatXDMCP
 
     seat_class->create_display_server = 
seat_xdmcp_session_create_display_server;
     seat_class->create_session = seat_xdmcp_session_create_session;
-    seat_class->display_removed = seat_xdmcp_session_display_removed;
     object_class->finalize = seat_xdmcp_session_finalize;
 
     g_type_class_add_private (klass, sizeof (SeatXDMCPSessionPrivate));
diff --git a/src/seat-xlocal.c b/src/seat-xlocal.c
--- a/src/seat-xlocal.c
+++ b/src/seat-xlocal.c
@@ -125,13 +125,36 @@ seat_xlocal_create_session (Seat *seat, 
 static void
 seat_xlocal_set_active_display (Seat *seat, Display *display)
 {
-    gint number = xserver_local_get_vt (XSERVER_LOCAL (XSERVER 
(display_get_display_server (display))));
-    if (number >= 0)
-        vt_set_active (number);
+    gint vt = xserver_local_get_vt (XSERVER_LOCAL (display_get_display_server 
(display)));
+    if (vt >= 0)
+        vt_set_active (vt);
 
     SEAT_CLASS (seat_xlocal_parent_class)->set_active_display (seat, display);
 }
 
+static Display *
+seat_xlocal_get_active_display (Seat *seat)
+{
+    gint vt;
+    GList *link;
+
+    vt = vt_get_active ();
+    if (vt < 0)
+        return NULL;
+
+    for (link = seat_get_displays (seat); link; link = link->next)
+    {
+        Display *display = link->data;
+        XServerLocal *xserver;
+
+        xserver = XSERVER_LOCAL (display_get_display_server (display));
+        if (xserver_local_get_vt (xserver) == vt)
+            return display;
+    }
+
+    return NULL;
+}
+
 static void
 seat_xlocal_run_script (Seat *seat, Display *display, Process *script)
 {
@@ -151,28 +174,6 @@ seat_xlocal_run_script (Seat *seat, Disp
 }
 
 static void
-seat_xlocal_display_removed (Seat *seat, Display *display)
-{
-    if (seat_get_is_stopping (seat))
-        return;
-
-    /* If this is the only display and it failed to start then stop this seat 
*/
-    if (g_list_length (seat_get_displays (seat)) == 0 && !display_get_is_ready 
(display))
-    {
-        g_debug ("Stopping X local seat, failed to start a display");
-        seat_stop (seat);
-        return;
-    }
-
-    /* Show a new greeter */  
-    if (display == seat_get_active_display (seat))
-    {
-        g_debug ("Active display stopped, switching to greeter");
-        seat_switch_to_greeter (seat);
-    }
-}
-
-static void
 seat_xlocal_init (SeatXLocal *seat)
 {
 }
@@ -186,6 +187,6 @@ seat_xlocal_class_init (SeatXLocalClass 
     seat_class->create_display_server = seat_xlocal_create_display_server;
     seat_class->create_session = seat_xlocal_create_session;
     seat_class->set_active_display = seat_xlocal_set_active_display;
+    seat_class->get_active_display = seat_xlocal_get_active_display;
     seat_class->run_script = seat_xlocal_run_script;
-    seat_class->display_removed = seat_xlocal_display_removed;
 }
diff --git a/src/seat-xremote.c b/src/seat-xremote.c
--- a/src/seat-xremote.c
+++ b/src/seat-xremote.c
@@ -71,13 +71,6 @@ seat_xremote_run_script (Seat *seat, Dis
 }
 
 static void
-seat_xremote_display_removed (Seat *seat, Display *display)
-{
-    /* Can't restart the display, so remove this seat */
-    seat_stop (seat);
-}
-
-static void
 seat_xremote_init (SeatXRemote *seat)
 {
 }
@@ -91,5 +84,4 @@ seat_xremote_class_init (SeatXRemoteClas
     seat_class->create_display_server = seat_xremote_create_display_server;
     seat_class->create_session = seat_xremote_create_session;
     seat_class->run_script = seat_xremote_run_script;
-    seat_class->display_removed = seat_xremote_display_removed;
 }
diff --git a/src/seat-xvnc.c b/src/seat-xvnc.c
--- a/src/seat-xvnc.c
+++ b/src/seat-xvnc.c
@@ -104,12 +104,6 @@ seat_xvnc_run_script (Seat *seat, Displa
 }
 
 static void
-seat_xvnc_display_removed (Seat *seat, Display *display)
-{
-    seat_stop (seat);
-}
-
-static void
 seat_xvnc_init (SeatXVNC *seat)
 {
     seat->priv = G_TYPE_INSTANCE_GET_PRIVATE (seat, SEAT_XVNC_TYPE, 
SeatXVNCPrivate);
@@ -136,7 +130,6 @@ seat_xvnc_class_init (SeatXVNCClass *kla
     seat_class->create_display_server = seat_xvnc_create_display_server;
     seat_class->create_session = seat_xvnc_create_session;
     seat_class->run_script = seat_xvnc_run_script;
-    seat_class->display_removed = seat_xvnc_display_removed;
     object_class->finalize = seat_xdmcp_session_finalize;
 
     g_type_class_add_private (klass, sizeof (SeatXVNCPrivate));
diff --git a/src/seat.c b/src/seat.c
--- a/src/seat.c
+++ b/src/seat.c
@@ -38,9 +38,6 @@ struct SeatPrivate
     /* The displays for this seat */
     GList *displays;
 
-    /* The active display */
-    Display *active_display;
-
     /* TRUE if stopping this seat (waiting for displays to stop) */
     gboolean stopping;
 
@@ -162,7 +159,7 @@ Display *
 seat_get_active_display (Seat *seat)
 {
     g_return_val_if_fail (seat != NULL, NULL);
-    return seat->priv->active_display;
+    return SEAT_GET_CLASS (seat)->get_active_display (seat);
 }
 
 gboolean
@@ -196,6 +193,9 @@ switch_to_user (Seat *seat, const gchar 
     {
         Display *display = link->data;
 
+        if (display_get_is_stopped (display))
+            continue;
+
         /* If already logged in, then switch to that display */
         if (g_strcmp0 (display_get_username (display), username) == 0)        
         {
@@ -427,11 +427,51 @@ check_stopped (Seat *seat)
 static void
 display_stopped_cb (Display *display, Seat *seat)
 {
+    gboolean is_active;
+
+    is_active = display == seat_get_active_display (seat);
+
+    g_signal_handlers_disconnect_matched (display, G_SIGNAL_MATCH_DATA, 0, 0, 
NULL, NULL, seat);
     seat->priv->displays = g_list_remove (seat->priv->displays, display);
-    g_signal_handlers_disconnect_matched (display, G_SIGNAL_MATCH_DATA, 0, 0, 
NULL, NULL, seat);
-    g_signal_emit (seat, signals[DISPLAY_REMOVED], 0, display);
     g_object_unref (display);
 
+    g_signal_emit (seat, signals[DISPLAY_REMOVED], 0, display);
+
+    /* If no more displays running either start a greeter or stop the seat */
+    if (!seat->priv->stopping)
+    {
+        if (g_list_length (seat->priv->displays) == 0)
+        {
+            /* If failed to start then stop this seat */
+            if (!display_get_is_ready (display))
+            {
+                g_debug ("Stopping seat, failed to start a display");
+                seat_stop (seat);
+            }
+            /* Attempt to start a greeter */
+            else if (!seat->priv->can_switch)
+            {
+                g_debug ("Stopping seat, display stopped");
+                seat_stop (seat);             
+            }
+            
+            else if (!seat_switch_to_greeter (seat))
+            {
+                g_debug ("Stopping seat, unable to start greeter");
+                seat_stop (seat);
+            }        
+        }
+        else if (is_active)
+        {
+            g_debug ("Active display stopped, switching to greeter");
+            if (!seat_switch_to_greeter (seat))
+            {
+                g_debug ("Stopping seat, unable to start greeter");
+                seat_stop (seat);              
+            }
+        }
+    }
+  
     check_stopped (seat);
 }
 
@@ -502,7 +542,7 @@ switch_to_user_or_start_greeter (Seat *s
     g_signal_emit (seat, signals[DISPLAY_ADDED], 0, display);
 
     /* Switch to this display if currently not looking at anything */
-    if (!seat->priv->active_display)
+    if (seat_get_active_display (seat) == NULL)
         seat_set_active_display (seat, display);
 
     return display_start (display);
@@ -610,25 +650,30 @@ seat_real_start (Seat *seat)
 static void
 seat_real_set_active_display (Seat *seat, Display *display)
 {
-    if (display == seat->priv->active_display)
-        return;
+    GList *link;
 
-    if (seat->priv->active_display)
+    for (link = seat->priv->displays; link; link = link->next)
     {
-        /* Stop the existing display if it is a greeter */
-        if (!display_get_username (seat->priv->active_display))
+        Display *d = link->data;
+
+        if (d == display)
+            continue;
+
+        /* Stop any greeters and lock any other sessions */
+        if (!display_get_username (d))
         {
-            g_debug ("Stopping greeter display being switched from");
-            display_stop (seat->priv->active_display);
+            g_debug ("Stopping background greeter");
+            display_stop (d);
         }
-        /* Otherwise lock it */
         else
-        {
-            display_lock (seat->priv->active_display);
-        }
-        g_object_unref (seat->priv->active_display);
-    }
-    seat->priv->active_display = g_object_ref (display);
+            display_lock (d);
+    }  
+}
+
+static Display *
+seat_real_get_active_display (Seat *seat)
+{
+    return NULL;
 }
 
 static void
@@ -664,8 +709,6 @@ seat_finalize (GObject *object)
     g_hash_table_unref (self->priv->properties);
     g_free (self->priv->guest_username);
     g_list_free_full (self->priv->displays, g_object_unref);
-    if (self->priv->active_display)
-        g_object_unref (self->priv->active_display);
 
     G_OBJECT_CLASS (seat_parent_class)->finalize (object);
 }
@@ -678,6 +721,7 @@ seat_class_init (SeatClass *klass)
     klass->setup = seat_real_setup;
     klass->start = seat_real_start;
     klass->set_active_display = seat_real_set_active_display;
+    klass->get_active_display = seat_real_get_active_display;
     klass->run_script = seat_real_run_script;
     klass->stop = seat_real_stop;
 
diff --git a/src/seat.h b/src/seat.h
--- a/src/seat.h
+++ b/src/seat.h
@@ -40,6 +40,7 @@ typedef struct
     DisplayServer *(*create_display_server) (Seat *seat);
     Session *(*create_session) (Seat *seat, Display *display);
     void (*set_active_display)(Seat *seat, Display *display);
+    Display *(*get_active_display)(Seat *seat);
     void (*run_script)(Seat *seat, Display *display, Process *script);
     void (*stop)(Seat *seat);
 
diff --git a/src/xserver-local.c b/src/xserver-local.c
--- a/src/xserver-local.c
+++ b/src/xserver-local.c
@@ -61,6 +61,9 @@ struct XServerLocalPrivate
     /* VT to run on */
     gint vt;
   
+    /* TRUE if holding a reference to the VT */
+    gboolean have_vt_ref;
+  
     /* TRUE if replacing Plymouth */
     gboolean replacing_plymouth;
 };
@@ -148,7 +151,10 @@ xserver_local_new (void)
     if (self->priv->vt < 0)
         self->priv->vt = vt_get_unused ();
     if (self->priv->vt >= 0)
+    {
         vt_ref (self->priv->vt);
+        self->priv->have_vt_ref = TRUE;
+    }
 
     return self;
 }
@@ -316,9 +322,6 @@ stopped_cb (Process *process, XServerLoc
 {
     g_debug ("X server stopped");
 
-    g_object_unref (server->priv->xserver_process);
-    server->priv->xserver_process = NULL;
-
     xserver_local_release_display_number (xserver_get_display_number (XSERVER 
(server)));
   
     if (xserver_get_authority (XSERVER (server)) && 
server->priv->authority_file)
@@ -339,11 +342,11 @@ stopped_cb (Process *process, XServerLoc
         server->priv->authority_file = NULL;
     }
 
-    if (server->priv->vt >= 0)
+    if (server->priv->have_vt_ref)
     {
         vt_unref (server->priv->vt);
-        server->priv->vt = -1;
-    }
+        server->priv->have_vt_ref = FALSE;
+    }  
 
     if (server->priv->replacing_plymouth && plymouth_get_is_running ())
     {
@@ -546,7 +549,7 @@ xserver_local_finalize (GObject *object)
     g_free (self->priv->xdmcp_key);
     if (self->priv->authority_file)
         g_object_unref (self->priv->authority_file);
-    if (self->priv->vt >= 0)
+    if (self->priv->have_vt_ref)
         vt_unref (self->priv->vt);
 
     G_OBJECT_CLASS (xserver_local_parent_class)->finalize (object);
++++++ lightdm-use-fine-grained-memory-locking.patch ++++++
# HG changeset patch
# User Michael Terry <[email protected]>
# Date 1359392941 18000
# Branch precise-mlock
# Node ID 5b070d44540db1caad11c998a8678aafb1a2f4a5
# Parent ce5521d07555b291eb3a9cdc56a13e634dd951a9
Use libgcrypt to selectively secure password memory instead of the big-hammer 
approach of mlockall

diff --git a/src/Makefile.am b/src/Makefile.am
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -95,6 +95,7 @@ lightdm_CFLAGS = \
 
 lightdm_LDADD = \
        $(LIGHTDM_LIBS) \
+       -lgcrypt \
        -lpam
 
 pkglibexec_PROGRAMS = lightdm-guest-session-wrapper
diff --git a/src/greeter.c b/src/greeter.c
--- a/src/greeter.c
+++ b/src/greeter.c
@@ -15,6 +15,7 @@
 #include <string.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <gcrypt.h>
 
 #include "greeter.h"
 #include "ldm-marshal.h"
@@ -40,6 +41,7 @@ struct GreeterPrivate
     /* Buffer for data read from greeter */
     guint8 *read_buffer;
     gsize n_read;
+    gboolean use_secure_memory;
   
     /* Hints for the greeter */
     GHashTable *hints;
@@ -105,6 +107,7 @@ greeter_new (Session *session, const gch
     greeter->priv->session = g_object_ref (session);
     greeter->priv->pam_service = g_strdup (pam_service);
     greeter->priv->autologin_pam_service = g_strdup (autologin_pam_service);
+    greeter->priv->use_secure_memory = config_get_boolean (config_get_instance 
(), "LightDM", "lock-memory");
 
     return greeter;
 }
@@ -121,6 +124,33 @@ greeter_set_hint (Greeter *greeter, cons
     g_hash_table_insert (greeter->priv->hints, g_strdup (name), g_strdup 
(value));
 }
 
+static void *
+secure_malloc (Greeter *greeter, size_t n)
+{
+    if (greeter->priv->use_secure_memory)
+        return gcry_malloc_secure (n);
+    else
+        return g_malloc (n);
+}
+
+static void *
+secure_realloc (Greeter *greeter, void *ptr, size_t n)
+{
+    if (greeter->priv->use_secure_memory)
+        return gcry_realloc (ptr, n);
+    else
+        return g_realloc (ptr, n);
+}
+
+static void
+secure_free (Greeter *greeter, void *ptr)
+{
+    if (greeter->priv->use_secure_memory)
+        return gcry_free (ptr);
+    else
+        return g_free (ptr);
+}
+
 static guint32
 int_length ()
 {
@@ -259,6 +289,7 @@ pam_messages_cb (Session *session, Greet
         struct pam_response *response;
         response = calloc (messages_length, sizeof (struct pam_response));
         session_respond (greeter->priv->authentication_session, response);
+        free (response);
     }
 }
 
@@ -490,12 +521,18 @@ handle_continue_authentication (Greeter 
         int msg_style = messages[i].msg_style;
         if (msg_style == PAM_PROMPT_ECHO_OFF || msg_style == 
PAM_PROMPT_ECHO_ON)
         {
-            response[i].resp = strdup (secrets[j]); // FIXME: Need to convert 
from UTF-8
+            size_t secret_length = strlen (secrets[j]) + 1;
+            response[i].resp = secure_malloc (greeter, secret_length);
+            memcpy (response[i].resp, secrets[j], secret_length); // FIXME: 
Need to convert from UTF-8
             j++;
         }
     }
 
     session_respond (greeter->priv->authentication_session, response);
+
+    for (i = 0; i < messages_length; i++)
+        secure_free (greeter, response[i].resp);
+    free (response);
 }
 
 static void
@@ -587,7 +624,7 @@ read_int (Greeter *greeter, gsize *offse
 }
 
 static gchar *
-read_string (Greeter *greeter, gsize *offset)
+read_string_full (Greeter *greeter, gsize *offset, void* (*alloc_fn)(size_t n))
 {
     guint32 length;
     gchar *value;
@@ -599,7 +636,7 @@ read_string (Greeter *greeter, gsize *of
         return g_strdup ("");
     }
 
-    value = g_malloc (sizeof (gchar *) * (length + 1));
+    value = (*alloc_fn) (sizeof (gchar *) * (length + 1));
     memcpy (value, greeter->priv->read_buffer + *offset, length);
     value[length] = '\0';
     *offset += length;
@@ -607,6 +644,21 @@ read_string (Greeter *greeter, gsize *of
     return value;
 }
 
+static gchar *
+read_string (Greeter *greeter, gsize *offset)
+{
+    return read_string_full (greeter, offset, g_malloc);
+}
+
+static gchar *
+read_secret (Greeter *greeter, gsize *offset)
+{
+    if (greeter->priv->use_secure_memory)
+        return read_string_full (greeter, offset, gcry_malloc_secure);
+    else
+        return read_string_full (greeter, offset, g_malloc);
+}
+
 static gboolean
 read_cb (GIOChannel *source, GIOCondition condition, gpointer data)
 {
@@ -654,7 +706,7 @@ read_cb (GIOChannel *source, GIOConditio
         n_to_read = read_int (greeter, &offset);
         if (n_to_read > 0)
         {
-            greeter->priv->read_buffer = g_realloc 
(greeter->priv->read_buffer, HEADER_SIZE + n_to_read);
+            greeter->priv->read_buffer = secure_realloc (greeter, 
greeter->priv->read_buffer, HEADER_SIZE + n_to_read);
             read_cb (source, condition, greeter);
             return TRUE;
         }
@@ -690,10 +742,12 @@ read_cb (GIOChannel *source, GIOConditio
         n_secrets = read_int (greeter, &offset);
         secrets = g_malloc (sizeof (gchar *) * (n_secrets + 1));
         for (i = 0; i < n_secrets; i++)
-            secrets[i] = read_string (greeter, &offset);
+            secrets[i] = read_secret (greeter, &offset);
         secrets[i] = NULL;
         handle_continue_authentication (greeter, secrets);
-        g_strfreev (secrets);
+        for (i = 0; i < n_secrets; i++)
+            secure_free (greeter, secrets[i]);
+        g_free (secrets);
         break;
     case GREETER_MESSAGE_CANCEL_AUTHENTICATION:
         handle_cancel_authentication (greeter);
@@ -796,7 +850,7 @@ static void
 greeter_init (Greeter *greeter)
 {
     greeter->priv = G_TYPE_INSTANCE_GET_PRIVATE (greeter, GREETER_TYPE, 
GreeterPrivate);
-    greeter->priv->read_buffer = g_malloc (HEADER_SIZE);
+    greeter->priv->read_buffer = secure_malloc (greeter, HEADER_SIZE);
     greeter->priv->hints = g_hash_table_new_full (g_str_hash, g_str_equal, 
g_free, g_free);
 }
 
@@ -811,7 +865,7 @@ greeter_finalize (GObject *object)
     g_object_unref (self->priv->session);
     g_free (self->priv->pam_service);
     g_free (self->priv->autologin_pam_service);
-    g_free (self->priv->read_buffer);
+    secure_free (self, self->priv->read_buffer);
     g_hash_table_unref (self->priv->hints);
     g_free (self->priv->remote_session);
     if (self->priv->authentication_session)
diff --git a/src/lightdm.c b/src/lightdm.c
--- a/src/lightdm.c
+++ b/src/lightdm.c
@@ -19,7 +19,6 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/stat.h>
-#include <sys/mman.h>
 
 #include "configuration.h"
 #include "opensuse-sysconfig.h"
@@ -1194,12 +1193,6 @@ main (int argc, char **argv)
                              NULL,
                              NULL);
 
-    if (config_get_boolean (config_get_instance (), "LightDM", "lock-memory"))
-    {
-        /* Protect memory from being paged to disk, as we deal with passwords 
*/
-        mlockall (MCL_CURRENT | MCL_FUTURE);
-    }
-
     if (getuid () != 0)
         g_debug ("Running in user mode");
     if (getenv ("DISPLAY"))
diff --git a/src/session-child.c b/src/session-child.c
--- a/src/session-child.c
+++ b/src/session-child.c
@@ -67,7 +67,7 @@ read_data (void *buf, size_t count)
 }
 
 static gchar *
-read_string ()
+read_string_full (void* (*alloc_fn)(size_t n))
 {
     int length;
     char *value;
@@ -82,13 +82,19 @@ read_string ()
         return NULL;
     }
   
-    value = g_malloc (sizeof (char) * (length + 1));
+    value = (*alloc_fn) (sizeof (char) * (length + 1));
     read_data (value, length);
     value[length] = '\0';      
 
     return value;
 }
 
+static gchar *
+read_string ()
+{
+    return read_string_full (g_malloc);
+}
+
 static int
 pam_conv_cb (int msg_length, const struct pam_message **msg, struct 
pam_response **resp, void *app_data)
 {
@@ -139,7 +145,9 @@ pam_conv_cb (int msg_length, const struc
     for (i = 0; i < msg_length; i++)
     {
         struct pam_response *r = &response[i];
-        r->resp = read_string ();
+        // callers of this function inside pam will expect to be able to call
+        // free() on the strings we give back.  So alloc with malloc.
+        r->resp = read_string_full (malloc);
         read_data (&r->resp_retcode, sizeof (r->resp_retcode));
     }
 
-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to