[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    Re: OOM-killer prevention for master kdeinit process
From:       Lubos Lunak <l.lunak () suse ! cz>
Date:       2006-08-02 15:07:08
Message-ID: 200608021707.08725.l.lunak () suse ! cz
[Download RAW message or body]

On Wednesday 02 August 2006 15:09, Lubos Lunak wrote:
>  Hello,
>
>  short summary: Out Of Memory handling on Linux sucks, KDE can suffer badly
> from it, kernel devels are unable to do anything about it, so let's again
> work around things ourselves.
...
>  Now, who's the setuid guru here :)? Is the attached (KDE3) patch ok? I'd
> prefer not to have security people going after me. The setuid stuff is
> copied from artswrapper, the privileges are dropped immediately so I hope
> there's no problem.

 Ok, scratch the patch, I wasn't able to attach gdb to processes launched via 
such kdeinit (and I was wondering why people use wrappers for it). Here's 
another attempt with a wrapper, again more or less copy&paste from 
artswrapper. This way kdeinit is only affected when launched during KDE 
startup, but that's hopefully enough.

On Wednesday 02 August 2006 15:59, Robert Knight wrote:
> > PS: Just in case somebody wonders why I hate OOM handling on Linux so
> > much then the answer is that my 1G RAM work machine with no swap at all
> > being trashed to death is probably the top reason why I reboot it (not
> > that I reboot that often otherwise).
>
> What on earth is using up that 1GB?

 Whatever happens to fill it up, e.g. accidental parallel linking when 
building kdebase is good for that. But that's not the point at all, the 
problem is that instead of killing whatever is responsible for running short 
on memory it instead kills kdeinit.

-- 
Lubos Lunak
KDE developer
---------------------------------------------------------------------
SuSE CR, s.r.o.  e-mail: l.lunak@suse.cz , l.lunak@kde.org
Drahobejlova 27  tel: +420 2 9654 2373
190 00 Praha 9   fax: +420 2 9654 2374
Czech Republic   http://www.suse.cz/

["kinit.patch" (text/x-diff)]

--- kinit/kinit.cpp.sav	2006-05-24 18:34:48.000000000 +0200
+++ kinit/kinit.cpp	2006-08-02 15:07:33.000000000 +0200
@@ -1654,6 +1654,27 @@ int main(int argc, char **argv, char **e
    int keep_running = 1;
    int new_startup = 0;
    d.suicide = false;
+   
+#ifdef __linux__
+/* prevent getting killed by bad heuristic in Linux OOM-killer and drop root \
privileges */ +   FILE* procfile = fopen( "/proc/self/oom_adj", "w" );
+   if( procfile ) {
+      fprintf( procfile, "-10" );
+      fclose( procfile );
+   }
+   if (geteuid() != getuid()) 
+   {
+#if defined (HAVE_SETEUID) && !defined (HAVE_SETEUID_FAKE) 
+      seteuid(getuid());
+#else
+      setreuid(-1, getuid());
+#endif
+      if (geteuid() != getuid()) {
+         perror("setuid()");
+         exit(1);
+      }
+   }
+#endif   
 
    /** Save arguments first... **/
    char **safe_argv = (char **) malloc( sizeof(char *) * argc);
--- kinit/Makefile.am.sav	2005-09-29 21:31:28.000000000 +0200
+++ kinit/Makefile.am	2006-08-02 16:56:11.000000000 +0200
@@ -20,7 +20,7 @@ INCLUDES = -I$(srcdir)/../libltdl/ $(all
 SUBDIRS = . tests
 
 bin_PROGRAMS = kdeinit kdeinit_wrapper kshell kdeinit_shutdown lnusertemp kwrapper \
                kioslave \
-               kstartupconfig kdostartupconfig
+               kstartupconfig kdostartupconfig start_kdeinit
 
 lib_LTLIBRARIES = 
 kdeinit_LTLIBRARIES = klauncher.la
@@ -66,6 +66,11 @@ kdostartupconfig_LDFLAGS = $(KDE_MT_LDFL
                            $(KDE_RPATH)
 kdostartupconfig_LDADD  = $(LIB_KDECORE)
 
+start_kdeinit_SOURCES = start_kdeinit.c
+kdeinitpath = $(bindir)/kdeinit
+start_kdeinit_CFLAGS = $(KDE_USE_FPIE) -DEXECUTE=\"$(kdeinitpath)\"
+start_kdeinit_LDFLAGS = $(KDE_USE_PIE)
+
 METASOURCES = AUTO
 
 noinst_HEADERS = klauncher.h autostart.h klauncher_cmds.h setproctitle.h
@@ -77,6 +82,14 @@ shell.o: wrapper.c
 dummy.cpp:
 	echo > dummy.cpp
 
+if KDEINIT_SETUID
+# start_kdeinit needs to be installed setuid root on Linux
+install-exec-hook:
+	@(chown 0 $(DESTDIR)$(bindir)/start_kdeinit && chmod 4755 \
$(DESTDIR)$(bindir)/start_kdeinit) || echo "Please make start_kdeinit setuid root" \
>&2 +	@echo ""
+	@echo "start_kdeinit is by default installed on Linux with a set SETUID root bit!"
+	@echo "This is needed to prevent kdeinit from being killed by a bad heuristic in \
the OOM-killer when running out of memory." +	@echo ""
+endif
 
 include $(top_srcdir)/admin/Doxyfile.am
-
--- kinit/configure.in.in.sav	2005-05-04 12:52:23.000000000 +0200
+++ kinit/configure.in.in	2006-08-02 14:57:00.000000000 +0200
@@ -43,3 +43,15 @@ if test -n "$KDEINIT_FONTCONFIG"; then
     AC_DEFINE(KDEINIT_USE_FONTCONFIG,1,[Use FontConfig in kdeinit])
 fi
 AC_SUBST(KDEINIT_XFT_INCLUDES)
+
+AC_MSG_CHECKING(whether to make kdeinit setuid root in order to protect it from bad \
Linux OOM-killer) +kdeinit_setuid=
+case $target_os in
+    linux*)
+        AC_MSG_RESULT(yes)
+        kdeinit_setuid=1
+        ;;
+    *)  AC_MSG_RESULT(no)
+        ;;
+esac
+AM_CONDITIONAL(KDEINIT_SETUID, test -n "$kdeinit_setuid" )
--- kinit/start_kdeinit.c.sav	2006-08-02 16:48:54.000000000 +0200
+++ kinit/start_kdeinit.c	2006-08-02 16:56:40.000000000 +0200
@@ -0,0 +1,53 @@
+/*
+ * This file is part of the KDE libraries
+ * Copyright (c) 2006 Lubos Lunak <l.lunak@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <unistd.h>
+
+int main(int argc, char **argv)
+{
+#ifdef __linux__
+/* prevent getting killed by bad heuristic in Linux OOM-killer and drop root \
privileges */ +   FILE* procfile = fopen( "/proc/self/oom_adj", "w" );
+   if( procfile ) {
+      fprintf( procfile, "-10" );
+      fclose( procfile );
+   }
+   if (geteuid() != getuid()) 
+   {
+#if defined (HAVE_SETEUID) && !defined (HAVE_SETEUID_FAKE) 
+      seteuid(getuid());
+#else
+      setreuid(-1, getuid());
+#endif
+      if (geteuid() != getuid()) {
+         perror("setuid()");
+         return 1;
+      }
+   }
+#endif   
+   if(argc == 0)
+      return 1;
+   argv[0] = (char*)EXECUTE;
+   execv(EXECUTE,argv);
+   perror(EXECUTE);
+   return 1;
+}


["startkde.patch" (text/x-diff)]

--- startkde.sav	2006-08-01 14:29:55.000000000 +0200
+++ startkde	2006-08-02 16:57:23.000000000 +0200
@@ -303,7 +303,7 @@ export KDE_FULL_SESSION
 
 # We set LD_BIND_NOW to increase the efficiency of kdeinit.
 # kdeinit unsets this variable before loading applications.
-LD_BIND_NOW=true kdeinit --new-startup +kcminit_startup
+LD_BIND_NOW=true start_kdeinit --new-startup +kcminit_startup
 if test $? -ne 0; then
   # Startup error
   echo 'startkde: Could not start kdeinit. Check your installation.'  1>&2


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic