<div dir="ltr"><div><div><div><div><div>Hi Veli-Matti,<br><br></div>Thanks for finding this problem.<br><br></div>There's more information in the bug report (<a href="https://bugs.launchpad.net/lightdm/+bug/1172752" target="_blank">https://bugs.launchpad.net/lightdm/+bug/1172752</a>) but to summarise for others reading the list:<br>
</div>- It is correct that two sessions are spawned - one is the greeter and one is the user session being authenticated<br></div>- There is a bug here though, the signal handler and pipe is open before the child processes are execed, which could cause the daemon to handle a SIGTERM from the child process and exit<br>
<br></div>--Robert<br></div><div class="gmail_extra"><br><br><div class="gmail_quote">On 4 May 2013 01:56, Veli-Matti Lintu <span dir="ltr"><<a href="mailto:veli-matti.lintu@opinsys.fi" target="_blank">veli-matti.lintu@opinsys.fi</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
I came across a race condition in lightdm greeter setup phase before the login screen is displayed (at boot time or after logout).<br>
<br>
I reported this also on Launchpad with more details (<a href="https://bugs.launchpad.net/lightdm/+bug/1172752" target="_blank">https://bugs.launchpad.net/lightdm/+bug/1172752</a>), but to work on a proper fix, ideas on how to fix this would be welcome.<br>

<br>
During greeter setup "lightdm --session-child" is spawned twice. The first call to session_start() that does fork+execlp() is done from greeter_start() and right after that handle_login() calls session_stop() + session_start(). session_stop() sends SIGTERM to the child process, but if the child has not managed to call execlp() yet, it still has signal handler set for SIGTERM, because fork copies the parent's signal handlers to the child. Now when session_stop() sends SIGTERM to the child, it uses the signal handler set by the parent which causes the signal go to signal_cb() that then signals the main lightdm process to die.<br>

<br>
I managed to get rid of the problem by switching fork() -> vfork() in session_start() which blocks the parent before execlp() is run and signal handlers are cleared. This ensures that the signal sent from session_stop() always ends up only to the child. Using vfork() is probably not the best solution, though, so I wonder if others have better ideas on how to fix this?<br>

<br>
<br>
--- src/session.c.orig  2012-08-29 21:25:16.000000000 +0000<br>
+++ src/session.c       2013-04-25 15:15:13.353450704 +0000<br>
@@ -360,7 +360,7 @@<br>
     session->priv->username = g_strdup (username);<br>
<br>
     /* Run the child */<br>
-    session->priv->pid = fork ();<br>
+    session->priv->pid = vfork ();<br>
     if (session->priv->pid < 0)<br>
     {<br>
         g_debug ("Failed to fork session child process: %s", strerror (errno));<br>
<br>
<br>
The signal handling in lightdm looks quite tricky, so I'm not really sure if this is the best way to handle this. Maybe it would be possible to get rid of the first "lightdm --session-child" spawning to make all this unnecessary? I could try to work on fixing this if someone who knows the code better has an opinion on this.<br>

<br>
Happy hacking!<br>
<br>
Veli-Matti<br>
_______________________________________________<br>
LightDM mailing list<br>
<a href="mailto:LightDM@lists.freedesktop.org">LightDM@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/lightdm" target="_blank">http://lists.freedesktop.org/mailman/listinfo/lightdm</a><br>
</blockquote></div><br></div>