diff options
author | Darren Tucker <dtucker@zip.com.au> | 2009-12-08 13:39:48 +1100 |
---|---|---|
committer | Darren Tucker <dtucker@zip.com.au> | 2009-12-08 13:39:48 +1100 |
commit | c8802aac28470714ec204d00342f6ecbca45908f (patch) | |
tree | 2732966739075d569e733d65ce0cb6eb1c7a4ac6 | |
parent | d35e0ef61658aa3116eebb1606fcfe6f849fdcca (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-- | ChangeLog | 4 | ||||
-rw-r--r-- | configure.ac | 5 | ||||
-rw-r--r-- | openbsd-compat/port-linux.c | 63 | ||||
-rw-r--r-- | openbsd-compat/port-linux.h | 7 | ||||
-rw-r--r-- | platform.c | 14 | ||||
-rw-r--r-- | platform.h | 3 | ||||
-rw-r--r-- | sshd.c | 1 |
7 files changed, 90 insertions, 7 deletions
@@ -1,3 +1,7 @@ | |||
1 | 20091208 | ||
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 | |||
1 | 20091207 | 5 | 20091207 |
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 | ||
17 | AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) | 17 | AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) |
18 | AC_REVISION($Revision: 1.431 $) | 18 | AC_REVISION($Revision: 1.432 $) |
19 | AC_CONFIG_SRCDIR([ssh.c]) | 19 | AC_CONFIG_SRCDIR([ssh.c]) |
20 | 20 | ||
21 | AC_CONFIG_HEADER(config.h) | 21 | AC_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 | |||
218 | static 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 | */ | ||
224 | void | ||
225 | oom_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 */ | ||
247 | void | ||
248 | oom_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 *); | |||
26 | void ssh_selinux_change_context(const char *); | 26 | void ssh_selinux_change_context(const char *); |
27 | #endif | 27 | #endif |
28 | 28 | ||
29 | #ifdef LINUX_OOM_ADJUST | ||
30 | void oom_adjust_restore(void); | ||
31 | void 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 | ||
24 | void | 24 | void |
25 | platform_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 | |||
33 | void | ||
25 | platform_pre_fork(void) | 34 | platform_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 | ||
21 | void platform_pre_listen(void); | ||
21 | void platform_pre_fork(void); | 22 | void platform_pre_fork(void); |
22 | void platform_post_fork_parent(pid_t child_pid); | 23 | void platform_post_fork_parent(pid_t child_pid); |
23 | void platform_post_fork_child(void); | 24 | void platform_post_fork_child(void); |
@@ -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) |