diff options
author | Colin Watson <cjwatson@debian.org> | 2008-05-25 22:32:48 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2008-05-25 22:32:48 +0000 |
commit | 1c35a89108e4c8a0913a408f0885d53c4899351a (patch) | |
tree | 790d2867539c5952fb0c7615cb1188369a6ef599 | |
parent | 8f03e38340e0da0aa566551a71770f0fbc4a8e8d (diff) |
Restore OOM killer adjustment for child processes (thanks, Vaclav Ovsik;
closes: #480020).
-rw-r--r-- | config.h.in | 3 | ||||
-rwxr-xr-x | configure | 5 | ||||
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | debian/changelog | 2 | ||||
-rw-r--r-- | debian/openssh-server.init | 13 | ||||
-rw-r--r-- | openbsd-compat/port-linux.c | 56 | ||||
-rw-r--r-- | openbsd-compat/port-linux.h | 6 | ||||
-rw-r--r-- | sshd.c | 39 |
8 files changed, 111 insertions, 14 deletions
diff --git a/config.h.in b/config.h.in index 9577c0e5f..d2641866c 100644 --- a/config.h.in +++ b/config.h.in | |||
@@ -1163,6 +1163,9 @@ | |||
1163 | /* Define if X11 doesn't support AF_UNIX sockets on that system */ | 1163 | /* Define if X11 doesn't support AF_UNIX sockets on that system */ |
1164 | #undef NO_X11_UNIX_SOCKETS | 1164 | #undef NO_X11_UNIX_SOCKETS |
1165 | 1165 | ||
1166 | /* Adjust Linux out-of-memory killer */ | ||
1167 | #undef OOM_ADJUST | ||
1168 | |||
1166 | /* libcrypto is missing AES 192 and 256 bit functions */ | 1169 | /* libcrypto is missing AES 192 and 256 bit functions */ |
1167 | #undef OPENSSL_LOBOTOMISED_AES | 1170 | #undef OPENSSL_LOBOTOMISED_AES |
1168 | 1171 | ||
@@ -7773,6 +7773,11 @@ cat >>confdefs.h <<\_ACEOF | |||
7773 | _ACEOF | 7773 | _ACEOF |
7774 | 7774 | ||
7775 | fi | 7775 | fi |
7776 | |||
7777 | cat >>confdefs.h <<\_ACEOF | ||
7778 | #define OOM_ADJUST 1 | ||
7779 | _ACEOF | ||
7780 | |||
7776 | ;; | 7781 | ;; |
7777 | mips-sony-bsd|mips-sony-newsos4) | 7782 | mips-sony-bsd|mips-sony-newsos4) |
7778 | 7783 | ||
diff --git a/configure.ac b/configure.ac index 487a9d6ae..5a7f83bf9 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -559,6 +559,7 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) | |||
559 | AC_DEFINE(SSH_TUN_PREPEND_AF, 1, | 559 | AC_DEFINE(SSH_TUN_PREPEND_AF, 1, |
560 | [Prepend the address family to IP tunnel traffic]) | 560 | [Prepend the address family to IP tunnel traffic]) |
561 | fi | 561 | fi |
562 | AC_DEFINE(OOM_ADJUST, 1, [Adjust Linux out-of-memory killer]) | ||
562 | ;; | 563 | ;; |
563 | mips-sony-bsd|mips-sony-newsos4) | 564 | mips-sony-bsd|mips-sony-newsos4) |
564 | AC_DEFINE(NEED_SETPGRP, 1, [Need setpgrp to acquire controlling tty]) | 565 | AC_DEFINE(NEED_SETPGRP, 1, [Need setpgrp to acquire controlling tty]) |
diff --git a/debian/changelog b/debian/changelog index f0c715daf..99640e763 100644 --- a/debian/changelog +++ b/debian/changelog | |||
@@ -33,6 +33,8 @@ openssh (1:4.7p1-11) UNRELEASED; urgency=low | |||
33 | glitches (thanks, Petter Reinholdtsen; closes: #481018). | 33 | glitches (thanks, Petter Reinholdtsen; closes: #481018). |
34 | * Remove 0 and 6 from Default-Stop in init script (thanks, Kel Modderman; | 34 | * Remove 0 and 6 from Default-Stop in init script (thanks, Kel Modderman; |
35 | closes: #481151). | 35 | closes: #481151). |
36 | * Restore OOM killer adjustment for child processes (thanks, Vaclav Ovsik; | ||
37 | closes: #480020). | ||
36 | 38 | ||
37 | -- Colin Watson <cjwatson@debian.org> Sat, 17 May 2008 08:48:45 +0200 | 39 | -- Colin Watson <cjwatson@debian.org> Sat, 17 May 2008 08:48:45 +0200 |
38 | 40 | ||
diff --git a/debian/openssh-server.init b/debian/openssh-server.init index ddd1e292c..01f00dc0a 100644 --- a/debian/openssh-server.init +++ b/debian/openssh-server.init | |||
@@ -16,7 +16,7 @@ set -e | |||
16 | test -x /usr/sbin/sshd || exit 0 | 16 | test -x /usr/sbin/sshd || exit 0 |
17 | ( /usr/sbin/sshd -\? 2>&1 | grep -q OpenSSH ) 2>/dev/null || exit 0 | 17 | ( /usr/sbin/sshd -\? 2>&1 | grep -q OpenSSH ) 2>/dev/null || exit 0 |
18 | 18 | ||
19 | SSHD_OOM_ADJUST=-17 | 19 | export SSHD_OOM_ADJUST=-17 |
20 | if test -f /etc/default/ssh; then | 20 | if test -f /etc/default/ssh; then |
21 | . /etc/default/ssh | 21 | . /etc/default/ssh |
22 | fi | 22 | fi |
@@ -71,15 +71,6 @@ check_config() { | |||
71 | fi | 71 | fi |
72 | } | 72 | } |
73 | 73 | ||
74 | adjust_oom() { | ||
75 | if [ -e /var/run/sshd.pid ]; then | ||
76 | PID="$(head -n1 /var/run/sshd.pid)" | ||
77 | if [ -e "/proc/$PID/oom_adj" ]; then | ||
78 | printf '%s' "$SSHD_OOM_ADJUST" >"/proc/$PID/oom_adj" || true | ||
79 | fi | ||
80 | fi | ||
81 | } | ||
82 | |||
83 | export PATH="${PATH:+$PATH:}/usr/sbin:/sbin" | 74 | export PATH="${PATH:+$PATH:}/usr/sbin:/sbin" |
84 | 75 | ||
85 | case "$1" in | 76 | case "$1" in |
@@ -90,7 +81,6 @@ case "$1" in | |||
90 | log_daemon_msg "Starting OpenBSD Secure Shell server" "sshd" | 81 | log_daemon_msg "Starting OpenBSD Secure Shell server" "sshd" |
91 | if start-stop-daemon --start --quiet --oknodo --pidfile /var/run/sshd.pid --exec /usr/sbin/sshd -- $SSHD_OPTS; then | 82 | if start-stop-daemon --start --quiet --oknodo --pidfile /var/run/sshd.pid --exec /usr/sbin/sshd -- $SSHD_OPTS; then |
92 | log_end_msg 0 | 83 | log_end_msg 0 |
93 | adjust_oom | ||
94 | else | 84 | else |
95 | log_end_msg 1 | 85 | log_end_msg 1 |
96 | fi | 86 | fi |
@@ -124,7 +114,6 @@ case "$1" in | |||
124 | check_dev_null log_end_msg | 114 | check_dev_null log_end_msg |
125 | if start-stop-daemon --start --quiet --oknodo --pidfile /var/run/sshd.pid --exec /usr/sbin/sshd -- $SSHD_OPTS; then | 115 | if start-stop-daemon --start --quiet --oknodo --pidfile /var/run/sshd.pid --exec /usr/sbin/sshd -- $SSHD_OPTS; then |
126 | log_end_msg 0 | 116 | log_end_msg 0 |
127 | adjust_oom | ||
128 | else | 117 | else |
129 | log_end_msg 1 | 118 | log_end_msg 1 |
130 | fi | 119 | fi |
diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c index 485929133..a9aa773ef 100644 --- a/openbsd-compat/port-linux.c +++ b/openbsd-compat/port-linux.c | |||
@@ -18,7 +18,7 @@ | |||
18 | */ | 18 | */ |
19 | 19 | ||
20 | /* | 20 | /* |
21 | * Linux-specific portability code - just SELinux support at present | 21 | * Linux-specific portability code |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include "includes.h" | 24 | #include "includes.h" |
@@ -27,11 +27,19 @@ | |||
27 | #include <stdarg.h> | 27 | #include <stdarg.h> |
28 | #include <string.h> | 28 | #include <string.h> |
29 | 29 | ||
30 | #ifdef OOM_ADJUST | ||
31 | #include <sys/types.h> | ||
32 | #include <sys/stat.h> | ||
33 | #include <fcntl.h> | ||
34 | #include <unistd.h> | ||
35 | #endif | ||
36 | |||
37 | #include "log.h" | ||
38 | |||
30 | #ifdef WITH_SELINUX | 39 | #ifdef WITH_SELINUX |
31 | #include "key.h" | 40 | #include "key.h" |
32 | #include "hostfile.h" | 41 | #include "hostfile.h" |
33 | #include "auth.h" | 42 | #include "auth.h" |
34 | #include "log.h" | ||
35 | #ifdef HAVE_GETSEUSERBYNAME | 43 | #ifdef HAVE_GETSEUSERBYNAME |
36 | #include "xmalloc.h" | 44 | #include "xmalloc.h" |
37 | #endif | 45 | #endif |
@@ -186,3 +194,47 @@ ssh_selinux_setup_pty(char *pwname, const char *tty) | |||
186 | debug3("%s: done", __func__); | 194 | debug3("%s: done", __func__); |
187 | } | 195 | } |
188 | #endif /* WITH_SELINUX */ | 196 | #endif /* WITH_SELINUX */ |
197 | |||
198 | #ifdef OOM_ADJUST | ||
199 | /* Get the out-of-memory adjustment file for the current process */ | ||
200 | int | ||
201 | oom_adj_open(void) | ||
202 | { | ||
203 | int fd = open("/proc/self/oom_adj", O_RDWR); | ||
204 | if (fd < 0) | ||
205 | logit("error opening /proc/self/oom_adj: %s", strerror(errno)); | ||
206 | return fd; | ||
207 | } | ||
208 | |||
209 | /* Get the current OOM adjustment */ | ||
210 | int | ||
211 | oom_adj_get(char *buf, size_t maxlen) | ||
212 | { | ||
213 | ssize_t n; | ||
214 | int fd = oom_adj_open(); | ||
215 | if (fd < 0) | ||
216 | return -1; | ||
217 | n = read(fd, buf, maxlen); | ||
218 | if (n < 0) | ||
219 | logit("error reading /proc/self/oom_adj: %s", strerror(errno)); | ||
220 | else | ||
221 | buf[n] = '\0'; | ||
222 | close(fd); | ||
223 | return n < 0 ? -1 : 0; | ||
224 | } | ||
225 | |||
226 | /* Set the current OOM adjustment */ | ||
227 | int | ||
228 | oom_adj_set(const char *buf) | ||
229 | { | ||
230 | ssize_t n; | ||
231 | int fd = oom_adj_open(); | ||
232 | if (fd < 0) | ||
233 | return -1; | ||
234 | n = write(fd, buf, strlen(buf)); | ||
235 | if (n < 0) | ||
236 | logit("error writing /proc/self/oom_adj: %s", strerror(errno)); | ||
237 | close(fd); | ||
238 | return n < 0 ? -1 : 0; | ||
239 | } | ||
240 | #endif | ||
diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h index 05e520e1c..cb8a253c4 100644 --- a/openbsd-compat/port-linux.h +++ b/openbsd-compat/port-linux.h | |||
@@ -24,4 +24,10 @@ void ssh_selinux_setup_pty(char *, const char *); | |||
24 | void ssh_selinux_setup_exec_context(char *); | 24 | void ssh_selinux_setup_exec_context(char *); |
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | #ifdef OOM_ADJUST | ||
28 | int oom_adj_open(void); | ||
29 | int oom_adj_get(char *buf, size_t maxlen); | ||
30 | int oom_adj_set(const char *buf); | ||
31 | #endif | ||
32 | |||
27 | #endif /* ! _PORT_LINUX_H */ | 33 | #endif /* ! _PORT_LINUX_H */ |
@@ -251,6 +251,11 @@ Buffer loginmsg; | |||
251 | /* Unprivileged user */ | 251 | /* Unprivileged user */ |
252 | struct passwd *privsep_pw = NULL; | 252 | struct passwd *privsep_pw = NULL; |
253 | 253 | ||
254 | #ifdef OOM_ADJUST | ||
255 | /* Linux out-of-memory killer adjustment */ | ||
256 | static char oom_adj_save[8]; | ||
257 | #endif | ||
258 | |||
254 | /* Prototypes for various functions defined later in this file. */ | 259 | /* Prototypes for various functions defined later in this file. */ |
255 | void destroy_sensitive_data(void); | 260 | void destroy_sensitive_data(void); |
256 | void demote_sensitive_data(void); | 261 | void demote_sensitive_data(void); |
@@ -905,6 +910,31 @@ recv_rexec_state(int fd, Buffer *conf) | |||
905 | debug3("%s: done", __func__); | 910 | debug3("%s: done", __func__); |
906 | } | 911 | } |
907 | 912 | ||
913 | #ifdef OOM_ADJUST | ||
914 | /* | ||
915 | * If requested in the environment, tell the Linux kernel's out-of-memory | ||
916 | * killer to avoid sshd. The old state will be restored when forking child | ||
917 | * processes. | ||
918 | */ | ||
919 | static void | ||
920 | oom_adjust_startup(void) | ||
921 | { | ||
922 | const char *oom_adj = getenv("SSHD_OOM_ADJUST"); | ||
923 | |||
924 | if (!oom_adj) | ||
925 | return; | ||
926 | oom_adj_get(oom_adj_save, sizeof(oom_adj_save)); | ||
927 | oom_adj_set(oom_adj); | ||
928 | } | ||
929 | |||
930 | static void | ||
931 | oom_restore(void) | ||
932 | { | ||
933 | if (oom_adj_save[0]) | ||
934 | oom_adj_set(oom_adj_save); | ||
935 | } | ||
936 | #endif | ||
937 | |||
908 | /* Accept a connection from inetd */ | 938 | /* Accept a connection from inetd */ |
909 | static void | 939 | static void |
910 | server_accept_inetd(int *sock_in, int *sock_out) | 940 | server_accept_inetd(int *sock_in, int *sock_out) |
@@ -1624,6 +1654,11 @@ main(int ac, char **av) | |||
1624 | /* ignore SIGPIPE */ | 1654 | /* ignore SIGPIPE */ |
1625 | signal(SIGPIPE, SIG_IGN); | 1655 | signal(SIGPIPE, SIG_IGN); |
1626 | 1656 | ||
1657 | #ifdef OOM_ADJUST | ||
1658 | /* Adjust out-of-memory killer */ | ||
1659 | oom_adjust_startup(); | ||
1660 | #endif | ||
1661 | |||
1627 | /* Get a connection, either from inetd or a listening TCP socket */ | 1662 | /* Get a connection, either from inetd or a listening TCP socket */ |
1628 | if (inetd_flag) { | 1663 | if (inetd_flag) { |
1629 | server_accept_inetd(&sock_in, &sock_out); | 1664 | server_accept_inetd(&sock_in, &sock_out); |
@@ -1666,6 +1701,10 @@ main(int ac, char **av) | |||
1666 | /* This is the child processing a new connection. */ | 1701 | /* This is the child processing a new connection. */ |
1667 | setproctitle("%s", "[accepted]"); | 1702 | setproctitle("%s", "[accepted]"); |
1668 | 1703 | ||
1704 | #ifdef OOM_ADJUST | ||
1705 | oom_restore(); | ||
1706 | #endif | ||
1707 | |||
1669 | /* | 1708 | /* |
1670 | * Create a new session and process group since the 4.4BSD | 1709 | * Create a new session and process group since the 4.4BSD |
1671 | * setlogin() affects the entire process group. We don't | 1710 | * setlogin() affects the entire process group. We don't |