summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@zip.com.au>2009-12-08 13:39:48 +1100
committerDarren Tucker <dtucker@zip.com.au>2009-12-08 13:39:48 +1100
commitc8802aac28470714ec204d00342f6ecbca45908f (patch)
tree2732966739075d569e733d65ce0cb6eb1c7a4ac6
parentd35e0ef61658aa3116eebb1606fcfe6f849fdcca (diff)
- (dtucker) Bug #1470: Disable OOM-killing of the listening sshd on Linux,
based on a patch from Vaclav Ovsik and Colin Watson. ok djm.
-rw-r--r--ChangeLog4
-rw-r--r--configure.ac5
-rw-r--r--openbsd-compat/port-linux.c63
-rw-r--r--openbsd-compat/port-linux.h7
-rw-r--r--platform.c14
-rw-r--r--platform.h3
-rw-r--r--sshd.c1
7 files changed, 90 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 53d89c905..7f95697f4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
120091208
2 - (dtucker) Bug #1470: Disable OOM-killing of the listening sshd on Linux,
3 based on a patch from Vaclav Ovsik and Colin Watson. ok djm.
4
120091207 520091207
2 - (dtucker) Bug #1160: use pkg-config for opensc config if it's available. 6 - (dtucker) Bug #1160: use pkg-config for opensc config if it's available.
3 Tested by Martin Paljak. 7 Tested by Martin Paljak.
diff --git a/configure.ac b/configure.ac
index 88a248fb5..94f049fc6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
1# $Id: configure.ac,v 1.431 2009/12/07 00:15:43 dtucker Exp $ 1# $Id: configure.ac,v 1.432 2009/12/08 02:39:48 dtucker Exp $
2# 2#
3# Copyright (c) 1999-2004 Damien Miller 3# Copyright (c) 1999-2004 Damien Miller
4# 4#
@@ -15,7 +15,7 @@
15# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 16
17AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) 17AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org)
18AC_REVISION($Revision: 1.431 $) 18AC_REVISION($Revision: 1.432 $)
19AC_CONFIG_SRCDIR([ssh.c]) 19AC_CONFIG_SRCDIR([ssh.c])
20 20
21AC_CONFIG_HEADER(config.h) 21AC_CONFIG_HEADER(config.h)
@@ -589,6 +589,7 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
589 if it doesn't return EOPNOTSUPP.]) 589 if it doesn't return EOPNOTSUPP.])
590 AC_DEFINE(_PATH_BTMP, "/var/log/btmp", [log for bad login attempts]) 590 AC_DEFINE(_PATH_BTMP, "/var/log/btmp", [log for bad login attempts])
591 AC_DEFINE(USE_BTMP) 591 AC_DEFINE(USE_BTMP)
592 AC_DEFINE(LINUX_OOM_ADJUST, 1, [Adjust Linux out-of-memory killer])
592 inet6_default_4in6=yes 593 inet6_default_4in6=yes
593 case `uname -r` in 594 case `uname -r` in
594 1.*|2.0.*) 595 1.*|2.0.*)
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 @@
1/* $Id: port-linux.c,v 1.6 2009/10/24 04:04:13 dtucker Exp $ */ 1/* $Id: port-linux.c,v 1.7 2009/12/08 02:39:48 dtucker Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com> 4 * Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com>
@@ -23,15 +23,17 @@
23 23
24#include "includes.h" 24#include "includes.h"
25 25
26#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST)
26#include <errno.h> 27#include <errno.h>
27#include <stdarg.h> 28#include <stdarg.h>
28#include <string.h> 29#include <string.h>
30#include <stdio.h>
29 31
30#ifdef WITH_SELINUX
31#include "log.h" 32#include "log.h"
32#include "xmalloc.h" 33#include "xmalloc.h"
33#include "port-linux.h" 34#include "port-linux.h"
34 35
36#ifdef WITH_SELINUX
35#include <selinux/selinux.h> 37#include <selinux/selinux.h>
36#include <selinux/flask.h> 38#include <selinux/flask.h>
37#include <selinux/get_context_list.h> 39#include <selinux/get_context_list.h>
@@ -204,3 +206,60 @@ ssh_selinux_change_context(const char *newname)
204 xfree(newctx); 206 xfree(newctx);
205} 207}
206#endif /* WITH_SELINUX */ 208#endif /* WITH_SELINUX */
209
210#ifdef LINUX_OOM_ADJUST
211#define OOM_ADJ_PATH "/proc/self/oom_adj"
212/*
213 * The magic "don't kill me", as documented in eg:
214 * http://lxr.linux.no/#linux+v2.6.32/Documentation/filesystems/proc.txt
215 */
216#define OOM_ADJ_NOKILL -17
217
218static int oom_adj_save = INT_MIN;
219
220/*
221 * Tell the kernel's out-of-memory killer to avoid sshd.
222 * Returns the previous oom_adj value or zero.
223 */
224void
225oom_adjust_setup(void)
226{
227 FILE *fp;
228
229 debug3("%s", __func__);
230 if ((fp = fopen(OOM_ADJ_PATH, "r+")) != NULL) {
231 if (fscanf(fp, "%d", &oom_adj_save) != 1)
232 logit("error reading %s: %s", OOM_ADJ_PATH, strerror(errno));
233 else {
234 rewind(fp);
235 if (fprintf(fp, "%d\n", OOM_ADJ_NOKILL) <= 0)
236 logit("error writing %s: %s",
237 OOM_ADJ_PATH, strerror(errno));
238 else
239 verbose("Set %s from %d to %d",
240 OOM_ADJ_PATH, oom_adj_save, OOM_ADJ_NOKILL);
241 }
242 fclose(fp);
243 }
244}
245
246/* Restore the saved OOM adjustment */
247void
248oom_adjust_restore(void)
249{
250 FILE *fp;
251
252 debug3("%s", __func__);
253 if (oom_adj_save == INT_MIN || (fp = fopen(OOM_ADJ_PATH, "w")) == NULL)
254 return;
255
256 if (fprintf(fp, "%d\n", oom_adj_save) <= 0)
257 logit("error writing %s: %s", OOM_ADJ_PATH, strerror(errno));
258 else
259 verbose("Set %s to %d", OOM_ADJ_PATH, oom_adj_save);
260
261 fclose(fp);
262 return;
263}
264#endif /* LINUX_OOM_ADJUST */
265#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 @@
1/* $Id: port-linux.h,v 1.3 2009/10/24 04:04:13 dtucker Exp $ */ 1/* $Id: port-linux.h,v 1.4 2009/12/08 02:39:48 dtucker Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2006 Damien Miller <djm@openbsd.org> 4 * Copyright (c) 2006 Damien Miller <djm@openbsd.org>
@@ -26,4 +26,9 @@ void ssh_selinux_setup_exec_context(char *);
26void ssh_selinux_change_context(const char *); 26void ssh_selinux_change_context(const char *);
27#endif 27#endif
28 28
29#ifdef LINUX_OOM_ADJUST
30void oom_adjust_restore(void);
31void oom_adjust_setup(void);
32#endif
33
29#endif /* ! _PORT_LINUX_H */ 34#endif /* ! _PORT_LINUX_H */
diff --git a/platform.c b/platform.c
index aee4b01e7..2dc4352f4 100644
--- a/platform.c
+++ b/platform.c
@@ -1,4 +1,4 @@
1/* $Id: platform.c,v 1.1 2006/08/30 17:24:41 djm Exp $ */ 1/* $Id: platform.c,v 1.2 2009/12/08 02:39:48 dtucker Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2006 Darren Tucker. All rights reserved. 4 * Copyright (c) 2006 Darren Tucker. All rights reserved.
@@ -22,6 +22,15 @@
22#include "openbsd-compat/openbsd-compat.h" 22#include "openbsd-compat/openbsd-compat.h"
23 23
24void 24void
25platform_pre_listen(void)
26{
27#ifdef LINUX_OOM_ADJUST
28 /* Adjust out-of-memory killer so listening process is not killed */
29 oom_adjust_setup();
30#endif
31}
32
33void
25platform_pre_fork(void) 34platform_pre_fork(void)
26{ 35{
27#ifdef USE_SOLARIS_PROCESS_CONTRACTS 36#ifdef USE_SOLARIS_PROCESS_CONTRACTS
@@ -43,4 +52,7 @@ platform_post_fork_child(void)
43#ifdef USE_SOLARIS_PROCESS_CONTRACTS 52#ifdef USE_SOLARIS_PROCESS_CONTRACTS
44 solaris_contract_post_fork_child(); 53 solaris_contract_post_fork_child();
45#endif 54#endif
55#ifdef LINUX_OOM_ADJUST
56 oom_adjust_restore();
57#endif
46} 58}
diff --git a/platform.h b/platform.h
index cf93bc57c..8a34e364e 100644
--- a/platform.h
+++ b/platform.h
@@ -1,4 +1,4 @@
1/* $Id: platform.h,v 1.1 2006/08/30 17:24:41 djm Exp $ */ 1/* $Id: platform.h,v 1.2 2009/12/08 02:39:48 dtucker Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2006 Darren Tucker. All rights reserved. 4 * Copyright (c) 2006 Darren Tucker. All rights reserved.
@@ -18,6 +18,7 @@
18 18
19#include <sys/types.h> 19#include <sys/types.h>
20 20
21void platform_pre_listen(void);
21void platform_pre_fork(void); 22void platform_pre_fork(void);
22void platform_post_fork_parent(pid_t child_pid); 23void platform_post_fork_parent(pid_t child_pid);
23void platform_post_fork_child(void); 24void platform_post_fork_child(void);
diff --git a/sshd.c b/sshd.c
index 04d8f9fa0..38aaa1820 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1656,6 +1656,7 @@ main(int ac, char **av)
1656 if (inetd_flag) { 1656 if (inetd_flag) {
1657 server_accept_inetd(&sock_in, &sock_out); 1657 server_accept_inetd(&sock_in, &sock_out);
1658 } else { 1658 } else {
1659 platform_pre_listen();
1659 server_listen(); 1660 server_listen();
1660 1661
1661 if (options.protocol & SSH_PROTO_1) 1662 if (options.protocol & SSH_PROTO_1)