From 429d9433914ec77f3822b28d4f4d55c66b918ab6 Mon Sep 17 00:00:00 2001 From: George Lebl Date: Jul 14 2003 23:55:47 +0000 Subject: Fix #97774 by resetting the rlimits back to infinity after we fork the Mon Jul 14 16:44:19 2003 George Lebl * daemon/misc.[ch], daemon/slave.c: Fix #97774 by resetting the rlimits back to infinity after we fork the user session. * config/gdm.conf.in, daemon/gdm.h: The default for AlwaysRestartServer is now again false, since it turns out to be a LOT nicer with buggy X servers (and it turns out quite a lot of people have these). * daemon/slave.c: properly guess the failsafeness of a session and don't re-guess it again * daemon/slave.c: when under the influence of rlimits never ABORT a display since it really could just be that we're hitting stupid limits (definately set way too low). * daemon/slave.c, daemon/server.c, daemon/misc.c: Be extra careful about when to reset signals to avoid races (unlikely though they may be) --- diff --git a/ChangeLog b/ChangeLog index 5cd95af..d164703 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +Mon Jul 14 16:44:19 2003 George Lebl + + * daemon/misc.[ch], daemon/slave.c: Fix #97774 by resetting the + rlimits back to infinity after we fork the user session. + + * config/gdm.conf.in, daemon/gdm.h: The default for + AlwaysRestartServer is now again false, since it turns out to be + a LOT nicer with buggy X servers (and it turns out quite a lot of + people have these). + + * daemon/slave.c: properly guess the failsafeness of a session and + don't re-guess it again + + * daemon/slave.c: when under the influence of rlimits never + ABORT a display since it really could just be that we're hitting + stupid limits (definately set way too low). + + * daemon/slave.c, daemon/server.c, daemon/misc.c: Be extra careful + about when to reset signals to avoid races (unlikely though they + may be) + Mon Jul 14 12:04:13 2003 George Lebl * config/XKeepsCrashing, config/extract-shell.sh: Fix RH #84247 by diff --git a/NEWS b/NEWS index b136b3a..d66b667 100644 --- a/NEWS +++ b/NEWS @@ -18,6 +18,10 @@ Ahh news... - If a greeter crashes within 10 seconds of display start, try running a different greeter (and telling the user that) +- Fix #97774 by resetting the rlimits back after we fork the + user session. Also make AlwaysRestartServer default to false + again since it was a workaround for this bug. + - Checking for free display numbers was only taking into account servers listening on tcp. @@ -57,6 +61,11 @@ Ahh news... - Random other minor fixes +- Translation updates (Danilo Segan, Serbian team, Metin Amiroff, + Christian Rose, Kjartan Maraas, Artur Flinta, Vincent van Adrighem, + Valek Filippov, Laurent Dhima, Christophe Merlet, Mohammad DAMT, + Dafydd Harries) + 2.4.2.96 stuff: - When you log in twice on a different server, gdm warns you and if diff --git a/config/gdm.conf.in b/config/gdm.conf.in index cd21179..7dc6305 100644 --- a/config/gdm.conf.in +++ b/config/gdm.conf.in @@ -25,11 +25,7 @@ TimedLogin= TimedLoginDelay=30 # If you are having trouble with using a single server for a long time and # want gdm to kill/restart the server, turn this on -# Note: I've made this default to true now because there seem to be some -# issues ranging from some things not being reset in the X server to -# pam issues with the slave. It is likely that this feature may be removed -# in the future and we're always going to do server restarts. -AlwaysRestartServer=true +AlwaysRestartServer=false # The gdm configuration program that is run from the login screen, you should # probably leave this alone Configurator=@EXPANDED_GDMCONFIGDIR@/gdmsetup --disable-sound --disable-crash-dialog diff --git a/daemon/gdm.h b/daemon/gdm.h index d4899dc..0deb361 100644 --- a/daemon/gdm.h +++ b/daemon/gdm.h @@ -130,7 +130,7 @@ enum { * to nothing */ #define GDM_KEY_AUTOMATICLOGIN_ENABLE "daemon/AutomaticLoginEnable=true" #define GDM_KEY_AUTOMATICLOGIN "daemon/AutomaticLogin=" -#define GDM_KEY_ALWAYSRESTARTSERVER "daemon/AlwaysRestartServer=true" +#define GDM_KEY_ALWAYSRESTARTSERVER "daemon/AlwaysRestartServer=false" #define GDM_KEY_GREETER "daemon/Greeter=" EXPANDED_BINDIR "/gdmlogin" #define GDM_KEY_REMOTEGREETER "daemon/RemoteGreeter=" EXPANDED_BINDIR "/gdmlogin" #define GDM_KEY_ADD_GTK_MODULES "daemon/AddGtkModules=false" diff --git a/daemon/misc.c b/daemon/misc.c index b8f0fb9..87c2dab 100644 --- a/daemon/misc.c +++ b/daemon/misc.c @@ -699,14 +699,20 @@ pid_t gdm_fork_extra (void) { pid_t pid; - gdm_sigchld_block_push (); + gdm_sigchld_block_push (); gdm_sigterm_block_push (); + pid = extra_process = fork (); if (pid < 0) extra_process = 0; - gdm_sigterm_block_pop (); + else if (pid == 0) + /* unset signals here, and yet again + later as the block_pop will whack + our signal mask*/ + gdm_unset_signals (); + gdm_sigterm_block_pop (); gdm_sigchld_block_pop (); if (pid == 0) { @@ -1343,4 +1349,56 @@ gdm_safe_fopen_ap (const char *file) return fdopen (fd, "a+"); } +void +gdm_reset_limits (void) +{ + struct rlimit unlim = { RLIM_INFINITY, RLIM_INFINITY }; + + /* Note: I don't really know which ones are really very standard + and which ones are not, so I just test for them all one by one */ + +#ifdef RLIMIT_CPU + setrlimit (RLIMIT_CPU, &unlim); +#endif +#ifdef RLIMIT_DATA + setrlimit (RLIMIT_DATA, &unlim); +#endif +#ifdef RLIMIT_FSIZE + setrlimit (RLIMIT_FSIZE, &unlim); +#endif +#ifdef RLIMIT_LOCKS + setrlimit (RLIMIT_LOCKS, &unlim); +#endif +#ifdef RLIMIT_MEMLOCK + setrlimit (RLIMIT_MEMLOCK, &unlim); +#endif +#ifdef RLIMIT_NOFILE + setrlimit (RLIMIT_NOFILE, &unlim); +#endif +#ifdef RLIMIT_OFILE + setrlimit (RLIMIT_OFILE, &unlim); +#endif +#ifdef RLIMIT_NPROC + setrlimit (RLIMIT_NPROC, &unlim); +#endif +#ifdef RLIMIT_RSS + setrlimit (RLIMIT_RSS, &unlim); +#endif +#ifdef RLIMIT_STACK + setrlimit (RLIMIT_STACK, &unlim); +#endif +#ifdef RLIMIT_CORE + setrlimit (RLIMIT_CORE, &unlim); +#endif +#ifdef RLIMIT_AS + setrlimit (RLIMIT_AS, &unlim); +#endif +#ifdef RLIMIT_VMEM + setrlimit (RLIMIT_VMEM, &unlim); +#endif +#ifdef RLIMIT_PTHREAD + setrlimit (RLIMIT_PTHREAD, &unlim); +#endif +} + /* EOF */ diff --git a/daemon/misc.h b/daemon/misc.h index 5526b5e..6ad46cb 100644 --- a/daemon/misc.h +++ b/daemon/misc.h @@ -106,6 +106,8 @@ FILE * gdm_safe_fopen_w (const char *file); /* like fopen with "a+" and uses O_EXCL and O_NOFOLLOW */ FILE * gdm_safe_fopen_ap (const char *file); +void gdm_reset_limits (void); + #endif /* GDM_MISC_H */ /* EOF */ diff --git a/daemon/server.c b/daemon/server.c index 4bb1d28..de8f092 100644 --- a/daemon/server.c +++ b/daemon/server.c @@ -992,6 +992,8 @@ gdm_server_spawn (GdmDisplay *d, const char *vtarg) gdm_sigterm_block_push (); pid = d->servpid = fork (); + if (pid == 0) + gdm_unset_signals (); gdm_sigterm_block_pop (); gdm_sigchld_block_pop (); diff --git a/daemon/slave.c b/daemon/slave.c index 458b549..a4b5ea3 100644 --- a/daemon/slave.c +++ b/daemon/slave.c @@ -1029,6 +1029,8 @@ run_config (GdmDisplay *display, struct passwd *pwent) gdm_sigchld_block_push (); gdm_sigterm_block_push (); pid = d->sesspid = fork (); + if (pid == 0) + gdm_unset_signals (); gdm_sigterm_block_pop (); gdm_sigchld_block_pop (); @@ -1677,6 +1679,8 @@ gdm_slave_greeter (void) gdm_sigterm_block_push (); greet = TRUE; pid = d->greetpid = fork (); + if (pid == 0) + gdm_unset_signals (); gdm_sigterm_block_pop (); gdm_sigchld_block_pop (); @@ -2099,6 +2103,8 @@ gdm_slave_chooser (void) gdm_sigchld_block_push (); gdm_sigterm_block_push (); pid = d->chooserpid = fork (); + if (pid == 0) + gdm_unset_signals (); gdm_sigterm_block_pop (); gdm_sigchld_block_pop (); @@ -2450,6 +2456,7 @@ find_prog (const char *name) static void session_child_run (struct passwd *pwent, + gboolean failsafe, const char *home_dir, gboolean home_dir_ok, const char *session, @@ -2458,11 +2465,9 @@ session_child_run (struct passwd *pwent, const char *gnome_session, gboolean usrcfgok, gboolean savesess, - gboolean savelang, - gboolean savegnomesess) + gboolean savelang) { int logfd; - gboolean failsafe = FALSE; char *exec; const char *shell = NULL; VeConfig *dmrc = NULL; @@ -2491,14 +2496,6 @@ session_child_run (struct passwd *pwent, XCloseDisplay (disp); } - if (strcmp (session, GDM_SESSION_FAILSAFE_GNOME) == 0 || - strcmp (session, GDM_SESSION_FAILSAFE_XTERM) == 0 || - /* hack */ - g_ascii_strcasecmp (session, "Failsafe") == 0 || - g_ascii_strcasecmp (session, "Failsafe.desktop") == 0) { - failsafe = TRUE; - } - /* Here we setup our 0,1,2 descriptors, we do it here * nowdays rather then later on so that we get errors even * from the PreSession script */ @@ -2855,7 +2852,7 @@ gdm_slave_session_start (void) struct passwd *pwent; char *save_session = NULL, *session = NULL, *language = NULL, *usrsess, *usrlang; char *gnome_session = NULL; - gboolean savesess = FALSE, savelang = FALSE, savegnomesess = FALSE; + gboolean savesess = FALSE, savelang = FALSE; gboolean usrcfgok = FALSE, authok = FALSE; const char *home_dir = NULL; gboolean home_dir_ok = FALSE; @@ -3073,6 +3070,14 @@ gdm_slave_session_start (void) g_ascii_strcasecmp (session, "Failsafe.desktop") == 0 /* hack */) failsafe = TRUE; + if ( ! failsafe) { + char *exec = get_session_exec (session); + if ( ! ve_string_empty (exec) && + strcmp (exec, "failsafe") == 0) + failsafe = TRUE; + g_free (exec); + } + /* Write out the Xservers file */ gdm_slave_send_num (GDM_SOP_WRITE_X_SERVERS, 0 /* bogus */); @@ -3084,17 +3089,20 @@ gdm_slave_session_start (void) gdm_sigchld_block_push (); gdm_sigterm_block_push (); pid = d->sesspid = fork (); + if (pid == 0) + gdm_unset_signals (); gdm_sigterm_block_pop (); gdm_sigchld_block_pop (); switch (pid) { case -1: - gdm_slave_exit (DISPLAY_ABORT, _("gdm_slave_session_start: Error forking user session")); + gdm_slave_exit (DISPLAY_REMANAGE, _("gdm_slave_session_start: Error forking user session")); case 0: /* Never returns */ session_child_run (pwent, + failsafe, home_dir, home_dir_ok, session, @@ -3103,14 +3111,20 @@ gdm_slave_session_start (void) gnome_session, usrcfgok, savesess, - savelang, - savegnomesess); + savelang); g_assert_not_reached (); default: break; } + /* We must be root for this, and we are, but just to make sure */ + seteuid (0); + setegid (GdmGroupId); + /* Reset all the process limits, pam may have set some up for our process and that + is quite evil. But pam is generally evil, so this is to be expected. */ + gdm_reset_limits (); + g_free (session); g_free (save_session); g_free (language);