summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2008-05-25 22:32:48 +0000
committerColin Watson <cjwatson@debian.org>2008-05-25 22:32:48 +0000
commit1c35a89108e4c8a0913a408f0885d53c4899351a (patch)
tree790d2867539c5952fb0c7615cb1188369a6ef599
parent8f03e38340e0da0aa566551a71770f0fbc4a8e8d (diff)
Restore OOM killer adjustment for child processes (thanks, Vaclav Ovsik;
closes: #480020).
-rw-r--r--config.h.in3
-rwxr-xr-xconfigure5
-rw-r--r--configure.ac1
-rw-r--r--debian/changelog2
-rw-r--r--debian/openssh-server.init13
-rw-r--r--openbsd-compat/port-linux.c56
-rw-r--r--openbsd-compat/port-linux.h6
-rw-r--r--sshd.c39
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
diff --git a/configure b/configure
index 3e578307d..3d3d60262 100755
--- a/configure
+++ b/configure
@@ -7773,6 +7773,11 @@ cat >>confdefs.h <<\_ACEOF
7773_ACEOF 7773_ACEOF
7774 7774
7775 fi 7775 fi
7776
7777cat >>confdefs.h <<\_ACEOF
7778#define OOM_ADJUST 1
7779_ACEOF
7780
7776 ;; 7781 ;;
7777mips-sony-bsd|mips-sony-newsos4) 7782mips-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 ;;
563mips-sony-bsd|mips-sony-newsos4) 564mips-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
16test -x /usr/sbin/sshd || exit 0 16test -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
19SSHD_OOM_ADJUST=-17 19export SSHD_OOM_ADJUST=-17
20if test -f /etc/default/ssh; then 20if test -f /etc/default/ssh; then
21 . /etc/default/ssh 21 . /etc/default/ssh
22fi 22fi
@@ -71,15 +71,6 @@ check_config() {
71 fi 71 fi
72} 72}
73 73
74adjust_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
83export PATH="${PATH:+$PATH:}/usr/sbin:/sbin" 74export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"
84 75
85case "$1" in 76case "$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 */
200int
201oom_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 */
210int
211oom_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 */
227int
228oom_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 *);
24void ssh_selinux_setup_exec_context(char *); 24void ssh_selinux_setup_exec_context(char *);
25#endif 25#endif
26 26
27#ifdef OOM_ADJUST
28int oom_adj_open(void);
29int oom_adj_get(char *buf, size_t maxlen);
30int oom_adj_set(const char *buf);
31#endif
32
27#endif /* ! _PORT_LINUX_H */ 33#endif /* ! _PORT_LINUX_H */
diff --git a/sshd.c b/sshd.c
index 2d428967c..1d2769a56 100644
--- a/sshd.c
+++ b/sshd.c
@@ -251,6 +251,11 @@ Buffer loginmsg;
251/* Unprivileged user */ 251/* Unprivileged user */
252struct passwd *privsep_pw = NULL; 252struct passwd *privsep_pw = NULL;
253 253
254#ifdef OOM_ADJUST
255/* Linux out-of-memory killer adjustment */
256static 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. */
255void destroy_sensitive_data(void); 260void destroy_sensitive_data(void);
256void demote_sensitive_data(void); 261void 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 */
919static void
920oom_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
930static void
931oom_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 */
909static void 939static void
910server_accept_inetd(int *sock_in, int *sock_out) 940server_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