diff options
Diffstat (limited to 'openbsd-compat/port-linux.c')
-rw-r--r-- | openbsd-compat/port-linux.c | 98 |
1 files changed, 96 insertions, 2 deletions
diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c index ad262758e..89b9a7340 100644 --- a/openbsd-compat/port-linux.c +++ b/openbsd-compat/port-linux.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $Id: port-linux.c,v 1.5 2008/03/26 20:27:21 dtucker Exp $ */ | 1 | /* $Id: port-linux.c,v 1.8 2010/03/01 04:52:50 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,14 +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" |
33 | #include "xmalloc.h" | ||
32 | #include "port-linux.h" | 34 | #include "port-linux.h" |
33 | 35 | ||
36 | #ifdef WITH_SELINUX | ||
34 | #include <selinux/selinux.h> | 37 | #include <selinux/selinux.h> |
35 | #include <selinux/flask.h> | 38 | #include <selinux/flask.h> |
36 | #include <selinux/get_context_list.h> | 39 | #include <selinux/get_context_list.h> |
@@ -168,4 +171,95 @@ ssh_selinux_setup_pty(char *pwname, const char *tty) | |||
168 | freecon(user_ctx); | 171 | freecon(user_ctx); |
169 | debug3("%s: done", __func__); | 172 | debug3("%s: done", __func__); |
170 | } | 173 | } |
174 | |||
175 | void | ||
176 | ssh_selinux_change_context(const char *newname) | ||
177 | { | ||
178 | int len, newlen; | ||
179 | char *oldctx, *newctx, *cx; | ||
180 | |||
181 | if (!ssh_selinux_enabled()) | ||
182 | return; | ||
183 | |||
184 | if (getcon((security_context_t *)&oldctx) < 0) { | ||
185 | logit("%s: getcon failed with %s", __func__, strerror (errno)); | ||
186 | return; | ||
187 | } | ||
188 | if ((cx = index(oldctx, ':')) == NULL || (cx = index(cx + 1, ':')) == | ||
189 | NULL) { | ||
190 | logit ("%s: unparseable context %s", __func__, oldctx); | ||
191 | return; | ||
192 | } | ||
193 | |||
194 | newlen = strlen(oldctx) + strlen(newname) + 1; | ||
195 | newctx = xmalloc(newlen); | ||
196 | len = cx - oldctx + 1; | ||
197 | memcpy(newctx, oldctx, len); | ||
198 | strlcpy(newctx + len, newname, newlen - len); | ||
199 | if ((cx = index(cx + 1, ':'))) | ||
200 | strlcat(newctx, cx, newlen); | ||
201 | debug3("%s: setting context from '%s' to '%s'", __func__, oldctx, | ||
202 | newctx); | ||
203 | if (setcon(newctx) < 0) | ||
204 | logit("%s: setcon failed with %s", __func__, strerror (errno)); | ||
205 | xfree(oldctx); | ||
206 | xfree(newctx); | ||
207 | } | ||
171 | #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 | verbose("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 | verbose("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 | verbose("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 */ | ||