diff options
author | Robert Ancell <robert.ancell@canonical.com> | 2012-03-05 11:23:32 +1100 |
---|---|---|
committer | Robert Ancell <robert.ancell@canonical.com> | 2012-03-05 11:23:32 +1100 |
commit | 457e99f08bba531f8452894a76306dee92fa6393 (patch) | |
tree | 4e16dc4fccfe1d7158898f613a9461677d712680 /src | |
parent | 5f146e0db50357c8cd3630834a090f1ec33b083a (diff) | |
download | lightdm-457e99f08bba531f8452894a76306dee92fa6393.tar.gz |
Stop file descriptors leaking into the session processes
Diffstat (limited to 'src')
-rw-r--r-- | src/display.c | 2 | ||||
-rw-r--r-- | src/greeter.c | 69 | ||||
-rw-r--r-- | src/greeter.h | 2 | ||||
-rw-r--r-- | src/lightdm.c | 1 | ||||
-rw-r--r-- | src/process.c | 2 | ||||
-rw-r--r-- | src/session-child.c | 9 | ||||
-rw-r--r-- | src/session.c | 2 |
7 files changed, 54 insertions, 33 deletions
diff --git a/src/display.c b/src/display.c index da6949dd..40a0efcf 100644 --- a/src/display.c +++ b/src/display.c @@ -430,7 +430,7 @@ start_greeter (Display *display) } g_signal_connect_after (display->priv->session, "stopped", G_CALLBACK (greeter_session_stopped_cb), display); - result = session_start (display->priv->session, display->priv->pam_service, greeter_user, FALSE, FALSE); + result = greeter_start (display->priv->greeter, display->priv->pam_service, greeter_user); g_free (greeter_user); if (!result) diff --git a/src/greeter.c b/src/greeter.c index 434a6bd3..bcdc2ae3 100644 --- a/src/greeter.c +++ b/src/greeter.c @@ -61,8 +61,6 @@ struct GreeterPrivate gboolean guest_account_authenticated; /* Communication channels to communicate with */ - int to_greeter_pipe[2]; - int from_greeter_pipe[2]; GIOChannel *to_greeter_channel; GIOChannel *from_greeter_channel; }; @@ -95,38 +93,12 @@ static gboolean read_cb (GIOChannel *source, GIOCondition condition, gpointer da Greeter * greeter_new (Session *session, const gchar *pam_service) { - gchar *value; Greeter *greeter; greeter = g_object_new (GREETER_TYPE, NULL); greeter->priv->session = g_object_ref (session); greeter->priv->pam_service = g_strdup (pam_service); - /* Create a pipe to talk with the greeter */ - if (pipe (greeter->priv->to_greeter_pipe) != 0 || pipe (greeter->priv->from_greeter_pipe) != 0) - { - g_warning ("Failed to create pipes: %s", strerror (errno)); - //return; - } - greeter->priv->to_greeter_channel = g_io_channel_unix_new (greeter->priv->to_greeter_pipe[1]); - g_io_channel_set_encoding (greeter->priv->to_greeter_channel, NULL, NULL); - greeter->priv->from_greeter_channel = g_io_channel_unix_new (greeter->priv->from_greeter_pipe[0]); - g_io_channel_set_encoding (greeter->priv->from_greeter_channel, NULL, NULL); - g_io_channel_set_buffered (greeter->priv->from_greeter_channel, FALSE); - g_io_add_watch (greeter->priv->from_greeter_channel, G_IO_IN | G_IO_HUP, read_cb, greeter); - - /* Let the greeter session know how to communicate with the daemon */ - value = g_strdup_printf ("%d", greeter->priv->from_greeter_pipe[1]); - session_set_env (greeter->priv->session, "LIGHTDM_TO_SERVER_FD", value); - g_free (value); - value = g_strdup_printf ("%d", greeter->priv->to_greeter_pipe[0]); - session_set_env (greeter->priv->session, "LIGHTDM_FROM_SERVER_FD", value); - g_free (value); - - /* Don't allow the daemon end of the pipes to be accessed in child processes */ - fcntl (greeter->priv->to_greeter_pipe[1], F_SETFD, FD_CLOEXEC); - fcntl (greeter->priv->from_greeter_pipe[0], F_SETFD, FD_CLOEXEC); - return greeter; } @@ -650,6 +622,47 @@ greeter_get_start_session (Greeter *greeter) return greeter->priv->start_session; } +gboolean +greeter_start (Greeter *greeter, const gchar *service, const gchar *username) +{ + int to_greeter_pipe[2], from_greeter_pipe[2]; + gboolean result = FALSE; + gchar *value; + + /* Create a pipe to talk with the greeter */ + if (pipe (to_greeter_pipe) != 0 || pipe (from_greeter_pipe) != 0) + { + g_warning ("Failed to create pipes: %s", strerror (errno)); + return FALSE; + } + greeter->priv->to_greeter_channel = g_io_channel_unix_new (to_greeter_pipe[1]); + g_io_channel_set_encoding (greeter->priv->to_greeter_channel, NULL, NULL); + greeter->priv->from_greeter_channel = g_io_channel_unix_new (from_greeter_pipe[0]); + g_io_channel_set_encoding (greeter->priv->from_greeter_channel, NULL, NULL); + g_io_channel_set_buffered (greeter->priv->from_greeter_channel, FALSE); + g_io_add_watch (greeter->priv->from_greeter_channel, G_IO_IN | G_IO_HUP, read_cb, greeter); + + /* Let the greeter session know how to communicate with the daemon */ + value = g_strdup_printf ("%d", from_greeter_pipe[1]); + session_set_env (greeter->priv->session, "LIGHTDM_TO_SERVER_FD", value); + g_free (value); + value = g_strdup_printf ("%d", to_greeter_pipe[0]); + session_set_env (greeter->priv->session, "LIGHTDM_FROM_SERVER_FD", value); + g_free (value); + + /* Don't allow the daemon end of the pipes to be accessed in child processes */ + fcntl (to_greeter_pipe[1], F_SETFD, FD_CLOEXEC); + fcntl (from_greeter_pipe[0], F_SETFD, FD_CLOEXEC); + + result = session_start (greeter->priv->session, service, username, FALSE, FALSE); + + /* Close the session ends of the pipe */ + close (to_greeter_pipe[0]); + close (from_greeter_pipe[1]); + + return result; +} + static Session * greeter_real_start_authentication (Greeter *greeter, const gchar *username) { diff --git a/src/greeter.h b/src/greeter.h index 56eea002..88fb2bc8 100644 --- a/src/greeter.h +++ b/src/greeter.h @@ -49,6 +49,8 @@ Session *greeter_get_authentication_session (Greeter *greeter); gboolean greeter_get_start_session (Greeter *greeter); +gboolean greeter_start (Greeter *greeter, const gchar *service, const gchar *username); + G_END_DECLS #endif /* _GREETER_H_ */ diff --git a/src/lightdm.c b/src/lightdm.c index 4bc5c0c1..e2b9f8d2 100644 --- a/src/lightdm.c +++ b/src/lightdm.c @@ -124,6 +124,7 @@ log_init (void) g_free (log_dir); log_fd = open (path, O_WRONLY | O_CREAT | O_TRUNC, 0600); + fcntl (log_fd, F_SETFD, FD_CLOEXEC); g_log_set_default_handler (log_cb, NULL); g_debug ("Logging to %s", path); diff --git a/src/process.c b/src/process.c index 5236ab8d..2910cd99 100644 --- a/src/process.c +++ b/src/process.c @@ -377,6 +377,8 @@ process_class_init (ProcessClass *klass) processes = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref); if (pipe (signal_pipe) != 0) g_critical ("Failed to create signal pipe"); + fcntl (signal_pipe[0], F_SETFD, FD_CLOEXEC); + fcntl (signal_pipe[1], F_SETFD, FD_CLOEXEC); g_io_add_watch (g_io_channel_unix_new (signal_pipe[0]), G_IO_IN, handle_signal, NULL); action.sa_sigaction = signal_cb; sigemptyset (&action.sa_mask); diff --git a/src/session-child.c b/src/session-child.c index 9ea86deb..7eaa645c 100644 --- a/src/session-child.c +++ b/src/session-child.c @@ -170,7 +170,7 @@ session_child_run (int argc, char **argv) GDBusConnection *bus; gchar *console_kit_cookie; GError *error = NULL; - + g_type_init (); /* Make input non-blocking */ @@ -193,10 +193,13 @@ session_child_run (int argc, char **argv) to_daemon_input = atoi (argv[3]); if (from_daemon_output == 0 || to_daemon_input == 0) { - g_printerr ("Invalid LIGHTDM_DAEMON_PIPE\n"); + g_printerr ("Invalid file descriptors %s %s\n", argv[2], argv[3]); return EXIT_FAILURE; } - g_unsetenv ("LIGHTDM_DAEMON_PIPE"); + + /* Don't let these pipes leak to the command we will run */ + fcntl (from_daemon_output, F_SETFD, FD_CLOEXEC); + fcntl (to_daemon_input, F_SETFD, FD_CLOEXEC); /* Read a version number so we can handle upgrades (i.e. a newer version of session child is run for an old daemon */ read_data (&version, sizeof (version)); diff --git a/src/session.c b/src/session.c index cb300d65..c2b4e7ad 100644 --- a/src/session.c +++ b/src/session.c @@ -326,7 +326,7 @@ session_start (Session *session, const gchar *service, const gchar *username, gb /* Create pipes to talk to the child */ if (pipe (to_child_pipe) < 0 || pipe (from_child_pipe) < 0) { - g_warning ("Failed to create pipe to communicated with session process: %s", strerror (errno)); + g_warning ("Failed to create pipe to communicate with session process: %s", strerror (errno)); return FALSE; } to_child_output = to_child_pipe[0]; |