summaryrefslogtreecommitdiff
path: root/debian/patches/oom-adjust.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/oom-adjust.patch')
-rw-r--r--debian/patches/oom-adjust.patch212
1 files changed, 212 insertions, 0 deletions
diff --git a/debian/patches/oom-adjust.patch b/debian/patches/oom-adjust.patch
new file mode 100644
index 000000000..d01f1f3ad
--- /dev/null
+++ b/debian/patches/oom-adjust.patch
@@ -0,0 +1,212 @@
1Index: b/config.h.in
2===================================================================
3--- a/config.h.in
4+++ b/config.h.in
5@@ -1238,6 +1238,9 @@
6 /* Define if X11 doesn't support AF_UNIX sockets on that system */
7 #undef NO_X11_UNIX_SOCKETS
8
9+/* Adjust Linux out-of-memory killer */
10+#undef OOM_ADJUST
11+
12 /* Define if EVP_DigestUpdate returns void */
13 #undef OPENSSL_EVP_DIGESTUPDATE_VOID
14
15Index: b/configure
16===================================================================
17--- a/configure
18+++ b/configure
19@@ -8369,6 +8369,11 @@
20 _ACEOF
21
22 fi
23+
24+cat >>confdefs.h <<\_ACEOF
25+#define OOM_ADJUST 1
26+_ACEOF
27+
28 ;;
29 mips-sony-bsd|mips-sony-newsos4)
30
31Index: b/configure.ac
32===================================================================
33--- a/configure.ac
34+++ b/configure.ac
35@@ -630,6 +630,7 @@
36 AC_DEFINE(SSH_TUN_PREPEND_AF, 1,
37 [Prepend the address family to IP tunnel traffic])
38 fi
39+ AC_DEFINE(OOM_ADJUST, 1, [Adjust Linux out-of-memory killer])
40 ;;
41 mips-sony-bsd|mips-sony-newsos4)
42 AC_DEFINE(NEED_SETPGRP, 1, [Need setpgrp to acquire controlling tty])
43Index: b/openbsd-compat/port-linux.c
44===================================================================
45--- a/openbsd-compat/port-linux.c
46+++ b/openbsd-compat/port-linux.c
47@@ -18,7 +18,7 @@
48 */
49
50 /*
51- * Linux-specific portability code - just SELinux support at present
52+ * Linux-specific portability code
53 */
54
55 #include "includes.h"
56@@ -27,6 +27,15 @@
57 #include <stdarg.h>
58 #include <string.h>
59
60+#ifdef OOM_ADJUST
61+#include <sys/types.h>
62+#include <sys/stat.h>
63+#include <fcntl.h>
64+#include <unistd.h>
65+#endif
66+
67+#include "log.h"
68+
69 #ifdef WITH_SELINUX
70 #include "key.h"
71 #include "hostfile.h"
72@@ -34,7 +43,6 @@
73 #ifdef HAVE_GETSEUSERBYNAME
74 #include "xmalloc.h"
75 #endif
76-#include "log.h"
77 #include "port-linux.h"
78
79 #include <selinux/selinux.h>
80@@ -186,3 +194,47 @@
81 debug3("%s: done", __func__);
82 }
83 #endif /* WITH_SELINUX */
84+
85+#ifdef OOM_ADJUST
86+/* Get the out-of-memory adjustment file for the current process */
87+static int
88+oom_adj_open(int oflag)
89+{
90+ int fd = open("/proc/self/oom_adj", oflag);
91+ if (fd < 0)
92+ logit("error opening /proc/self/oom_adj: %s", strerror(errno));
93+ return fd;
94+}
95+
96+/* Get the current OOM adjustment */
97+int
98+oom_adj_get(char *buf, size_t maxlen)
99+{
100+ ssize_t n;
101+ int fd = oom_adj_open(O_RDONLY);
102+ if (fd < 0)
103+ return -1;
104+ n = read(fd, buf, maxlen);
105+ if (n < 0)
106+ logit("error reading /proc/self/oom_adj: %s", strerror(errno));
107+ else
108+ buf[n] = '\0';
109+ close(fd);
110+ return n < 0 ? -1 : 0;
111+}
112+
113+/* Set the current OOM adjustment */
114+int
115+oom_adj_set(const char *buf)
116+{
117+ ssize_t n;
118+ int fd = oom_adj_open(O_WRONLY);
119+ if (fd < 0)
120+ return -1;
121+ n = write(fd, buf, strlen(buf));
122+ if (n < 0)
123+ logit("error writing /proc/self/oom_adj: %s", strerror(errno));
124+ close(fd);
125+ return n < 0 ? -1 : 0;
126+}
127+#endif
128Index: b/openbsd-compat/port-linux.h
129===================================================================
130--- a/openbsd-compat/port-linux.h
131+++ b/openbsd-compat/port-linux.h
132@@ -25,4 +25,9 @@
133 void ssh_selinux_setup_exec_context(char *);
134 #endif
135
136+#ifdef OOM_ADJUST
137+int oom_adj_get(char *buf, size_t maxlen);
138+int oom_adj_set(const char *buf);
139+#endif
140+
141 #endif /* ! _PORT_LINUX_H */
142Index: b/sshd.c
143===================================================================
144--- a/sshd.c
145+++ b/sshd.c
146@@ -254,6 +254,11 @@
147 /* Unprivileged user */
148 struct passwd *privsep_pw = NULL;
149
150+#ifdef OOM_ADJUST
151+/* Linux out-of-memory killer adjustment */
152+static char oom_adj_save[8];
153+#endif
154+
155 /* Prototypes for various functions defined later in this file. */
156 void destroy_sensitive_data(void);
157 void demote_sensitive_data(void);
158@@ -908,6 +913,31 @@
159 debug3("%s: done", __func__);
160 }
161
162+#ifdef OOM_ADJUST
163+/*
164+ * If requested in the environment, tell the Linux kernel's out-of-memory
165+ * killer to avoid sshd. The old state will be restored when forking child
166+ * processes.
167+ */
168+static void
169+oom_adjust_startup(void)
170+{
171+ const char *oom_adj = getenv("SSHD_OOM_ADJUST");
172+
173+ if (!oom_adj || !*oom_adj)
174+ return;
175+ oom_adj_get(oom_adj_save, sizeof(oom_adj_save));
176+ oom_adj_set(oom_adj);
177+}
178+
179+static void
180+oom_restore(void)
181+{
182+ if (oom_adj_save[0])
183+ oom_adj_set(oom_adj_save);
184+}
185+#endif
186+
187 /* Accept a connection from inetd */
188 static void
189 server_accept_inetd(int *sock_in, int *sock_out)
190@@ -1670,6 +1700,11 @@
191 /* ignore SIGPIPE */
192 signal(SIGPIPE, SIG_IGN);
193
194+#ifdef OOM_ADJUST
195+ /* Adjust out-of-memory killer */
196+ oom_adjust_startup();
197+#endif
198+
199 /* Get a connection, either from inetd or a listening TCP socket */
200 if (inetd_flag) {
201 server_accept_inetd(&sock_in, &sock_out);
202@@ -1708,6 +1743,10 @@
203 /* This is the child processing a new connection. */
204 setproctitle("%s", "[accepted]");
205
206+#ifdef OOM_ADJUST
207+ oom_restore();
208+#endif
209+
210 /*
211 * Create a new session and process group since the 4.4BSD
212 * setlogin() affects the entire process group. We don't