diff options
author | Darren Tucker <dtucker@zip.com.au> | 2009-12-08 03:39:48 +0100 |
---|---|---|
committer | Darren Tucker <dtucker@zip.com.au> | 2009-12-08 03:39:48 +0100 |
commit | c8802aac28470714ec204d00342f6ecbca45908f (patch) | |
tree | 2732966739075d569e733d65ce0cb6eb1c7a4ac6 /openbsd-compat | |
parent | - (dtucker) Bug #1677: add conditionals around the source for ssh-askpass. (diff) | |
download | openssh-c8802aac28470714ec204d00342f6ecbca45908f.tar.xz openssh-c8802aac28470714ec204d00342f6ecbca45908f.zip |
- (dtucker) Bug #1470: Disable OOM-killing of the listening sshd on Linux,
based on a patch from Vaclav Ovsik and Colin Watson. ok djm.
Diffstat (limited to 'openbsd-compat')
-rw-r--r-- | openbsd-compat/port-linux.c | 63 | ||||
-rw-r--r-- | openbsd-compat/port-linux.h | 7 |
2 files changed, 67 insertions, 3 deletions
diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c index 88c601e20..cda751dea 100644 --- a/openbsd-compat/port-linux.c +++ b/openbsd-compat/port-linux.c @@ -1,4 +1,4 @@ -/* $Id: port-linux.c,v 1.6 2009/10/24 04:04:13 dtucker Exp $ */ +/* $Id: port-linux.c,v 1.7 2009/12/08 02:39:48 dtucker Exp $ */ /* * Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com> @@ -23,15 +23,17 @@ #include "includes.h" +#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST) #include <errno.h> #include <stdarg.h> #include <string.h> +#include <stdio.h> -#ifdef WITH_SELINUX #include "log.h" #include "xmalloc.h" #include "port-linux.h" +#ifdef WITH_SELINUX #include <selinux/selinux.h> #include <selinux/flask.h> #include <selinux/get_context_list.h> @@ -204,3 +206,60 @@ ssh_selinux_change_context(const char *newname) xfree(newctx); } #endif /* WITH_SELINUX */ + +#ifdef LINUX_OOM_ADJUST +#define OOM_ADJ_PATH "/proc/self/oom_adj" +/* + * The magic "don't kill me", as documented in eg: + * http://lxr.linux.no/#linux+v2.6.32/Documentation/filesystems/proc.txt + */ +#define OOM_ADJ_NOKILL -17 + +static int oom_adj_save = INT_MIN; + +/* + * Tell the kernel's out-of-memory killer to avoid sshd. + * Returns the previous oom_adj value or zero. + */ +void +oom_adjust_setup(void) +{ + FILE *fp; + + debug3("%s", __func__); + if ((fp = fopen(OOM_ADJ_PATH, "r+")) != NULL) { + if (fscanf(fp, "%d", &oom_adj_save) != 1) + logit("error reading %s: %s", OOM_ADJ_PATH, strerror(errno)); + else { + rewind(fp); + if (fprintf(fp, "%d\n", OOM_ADJ_NOKILL) <= 0) + logit("error writing %s: %s", + OOM_ADJ_PATH, strerror(errno)); + else + verbose("Set %s from %d to %d", + OOM_ADJ_PATH, oom_adj_save, OOM_ADJ_NOKILL); + } + fclose(fp); + } +} + +/* Restore the saved OOM adjustment */ +void +oom_adjust_restore(void) +{ + FILE *fp; + + debug3("%s", __func__); + if (oom_adj_save == INT_MIN || (fp = fopen(OOM_ADJ_PATH, "w")) == NULL) + return; + + if (fprintf(fp, "%d\n", oom_adj_save) <= 0) + logit("error writing %s: %s", OOM_ADJ_PATH, strerror(errno)); + else + verbose("Set %s to %d", OOM_ADJ_PATH, oom_adj_save); + + fclose(fp); + return; +} +#endif /* LINUX_OOM_ADJUST */ +#endif /* WITH_SELINUX || LINUX_OOM_ADJUST */ diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h index 6ad4a49f6..209d9a7a2 100644 --- a/openbsd-compat/port-linux.h +++ b/openbsd-compat/port-linux.h @@ -1,4 +1,4 @@ -/* $Id: port-linux.h,v 1.3 2009/10/24 04:04:13 dtucker Exp $ */ +/* $Id: port-linux.h,v 1.4 2009/12/08 02:39:48 dtucker Exp $ */ /* * Copyright (c) 2006 Damien Miller <djm@openbsd.org> @@ -26,4 +26,9 @@ void ssh_selinux_setup_exec_context(char *); void ssh_selinux_change_context(const char *); #endif +#ifdef LINUX_OOM_ADJUST +void oom_adjust_restore(void); +void oom_adjust_setup(void); +#endif + #endif /* ! _PORT_LINUX_H */ |