OpenCoverage

port-linux.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/openssh/src/openbsd-compat/port-linux.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/*-
2 * Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com>-
3 * Copyright (c) 2006 Damien Miller <djm@openbsd.org>-
4 *-
5 * Permission to use, copy, modify, and distribute this software for any-
6 * purpose with or without fee is hereby granted, provided that the above-
7 * copyright notice and this permission notice appear in all copies.-
8 *-
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES-
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF-
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR-
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES-
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN-
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF-
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.-
16 */-
17-
18/*-
19 * Linux-specific portability code - just SELinux support at present-
20 */-
21-
22#include "includes.h"-
23-
24#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST)-
25#include <errno.h>-
26#include <stdarg.h>-
27#include <string.h>-
28#include <stdio.h>-
29#include <stdlib.h>-
30-
31#include "log.h"-
32#include "xmalloc.h"-
33#include "port-linux.h"-
34-
35#ifdef WITH_SELINUX-
36#include <selinux/selinux.h>-
37#include <selinux/get_context_list.h>-
38-
39#ifndef SSH_SELINUX_UNCONFINED_TYPE-
40# define SSH_SELINUX_UNCONFINED_TYPE ":unconfined_t:"-
41#endif-
42-
43/* Wrapper around is_selinux_enabled() to log its return value once only */-
44int-
45ssh_selinux_enabled(void)-
46{-
47 static int enabled = -1;-
48-
49 if (enabled == -1) {-
50 enabled = (is_selinux_enabled() == 1);-
51 debug("SELinux support %s", enabled ? "enabled" : "disabled");-
52 }-
53-
54 return (enabled);-
55}-
56-
57/* Return the default security context for the given username */-
58static security_context_t-
59ssh_selinux_getctxbyname(char *pwname)-
60{-
61 security_context_t sc = NULL;-
62 char *sename = NULL, *lvl = NULL;-
63 int r;-
64-
65#ifdef HAVE_GETSEUSERBYNAME-
66 if (getseuserbyname(pwname, &sename, &lvl) != 0)-
67 return NULL;-
68#else-
69 sename = pwname;-
70 lvl = NULL;-
71#endif-
72-
73#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL-
74 r = get_default_context_with_level(sename, lvl, NULL, &sc);-
75#else-
76 r = get_default_context(sename, NULL, &sc);-
77#endif-
78-
79 if (r != 0) {-
80 switch (security_getenforce()) {-
81 case -1:-
82 fatal("%s: ssh_selinux_getctxbyname: "-
83 "security_getenforce() failed", __func__);-
84 case 0:-
85 error("%s: Failed to get default SELinux security "-
86 "context for %s", __func__, pwname);-
87 sc = NULL;-
88 break;-
89 default:-
90 fatal("%s: Failed to get default SELinux security "-
91 "context for %s (in enforcing mode)",-
92 __func__, pwname);-
93 }-
94 }-
95-
96#ifdef HAVE_GETSEUSERBYNAME-
97 free(sename);-
98 free(lvl);-
99#endif-
100-
101 return sc;-
102}-
103-
104/* Set the execution context to the default for the specified user */-
105void-
106ssh_selinux_setup_exec_context(char *pwname)-
107{-
108 security_context_t user_ctx = NULL;-
109-
110 if (!ssh_selinux_enabled())-
111 return;-
112-
113 debug3("%s: setting execution context", __func__);-
114-
115 user_ctx = ssh_selinux_getctxbyname(pwname);-
116 if (setexeccon(user_ctx) != 0) {-
117 switch (security_getenforce()) {-
118 case -1:-
119 fatal("%s: security_getenforce() failed", __func__);-
120 case 0:-
121 error("%s: Failed to set SELinux execution "-
122 "context for %s", __func__, pwname);-
123 break;-
124 default:-
125 fatal("%s: Failed to set SELinux execution context "-
126 "for %s (in enforcing mode)", __func__, pwname);-
127 }-
128 }-
129 if (user_ctx != NULL)-
130 freecon(user_ctx);-
131-
132 debug3("%s: done", __func__);-
133}-
134-
135/* Set the TTY context for the specified user */-
136void-
137ssh_selinux_setup_pty(char *pwname, const char *tty)-
138{-
139 security_context_t new_tty_ctx = NULL;-
140 security_context_t user_ctx = NULL;-
141 security_context_t old_tty_ctx = NULL;-
142 security_class_t chrclass;-
143-
144 if (!ssh_selinux_enabled())-
145 return;-
146-
147 debug3("%s: setting TTY context on %s", __func__, tty);-
148-
149 user_ctx = ssh_selinux_getctxbyname(pwname);-
150-
151 /* XXX: should these calls fatal() upon failure in enforcing mode? */-
152-
153 if (getfilecon(tty, &old_tty_ctx) == -1) {-
154 error("%s: getfilecon: %s", __func__, strerror(errno));-
155 goto out;-
156 }-
157 if ((chrclass = string_to_security_class("chr_file")) == 0) {-
158 error("%s: couldn't get security class for chr_file", __func__);-
159 goto out;-
160 }-
161 if (security_compute_relabel(user_ctx, old_tty_ctx,-
162 chrclass, &new_tty_ctx) != 0) {-
163 error("%s: security_compute_relabel: %s",-
164 __func__, strerror(errno));-
165 goto out;-
166 }-
167-
168 if (setfilecon(tty, new_tty_ctx) != 0)-
169 error("%s: setfilecon: %s", __func__, strerror(errno));-
170 out:-
171 if (new_tty_ctx != NULL)-
172 freecon(new_tty_ctx);-
173 if (old_tty_ctx != NULL)-
174 freecon(old_tty_ctx);-
175 if (user_ctx != NULL)-
176 freecon(user_ctx);-
177 debug3("%s: done", __func__);-
178}-
179-
180void-
181ssh_selinux_change_context(const char *newname)-
182{-
183 int len, newlen;-
184 char *oldctx, *newctx, *cx;-
185 void (*switchlog) (const char *fmt,...) = logit;-
186-
187 if (!ssh_selinux_enabled())-
188 return;-
189-
190 if (getcon((security_context_t *)&oldctx) < 0) {-
191 logit("%s: getcon failed with %s", __func__, strerror(errno));-
192 return;-
193 }-
194 if ((cx = index(oldctx, ':')) == NULL || (cx = index(cx + 1, ':')) ==-
195 NULL) {-
196 logit ("%s: unparseable context %s", __func__, oldctx);-
197 return;-
198 }-
199-
200 /*-
201 * Check whether we are attempting to switch away from an unconfined-
202 * security context.-
203 */-
204 if (strncmp(cx, SSH_SELINUX_UNCONFINED_TYPE,-
205 sizeof(SSH_SELINUX_UNCONFINED_TYPE) - 1) == 0)-
206 switchlog = debug3;-
207-
208 newlen = strlen(oldctx) + strlen(newname) + 1;-
209 newctx = xmalloc(newlen);-
210 len = cx - oldctx + 1;-
211 memcpy(newctx, oldctx, len);-
212 strlcpy(newctx + len, newname, newlen - len);-
213 if ((cx = index(cx + 1, ':')))-
214 strlcat(newctx, cx, newlen);-
215 debug3("%s: setting context from '%s' to '%s'", __func__,-
216 oldctx, newctx);-
217 if (setcon(newctx) < 0)-
218 switchlog("%s: setcon %s from %s failed with %s", __func__,-
219 newctx, oldctx, strerror(errno));-
220 free(oldctx);-
221 free(newctx);-
222}-
223-
224void-
225ssh_selinux_setfscreatecon(const char *path)-
226{-
227 security_context_t context;-
228-
229 if (!ssh_selinux_enabled())-
230 return;-
231 if (path == NULL) {-
232 setfscreatecon(NULL);-
233 return;-
234 }-
235 if (matchpathcon(path, 0700, &context) == 0)-
236 setfscreatecon(context);-
237}-
238-
239#endif /* WITH_SELINUX */-
240-
241#ifdef LINUX_OOM_ADJUST-
242/*-
243 * The magic "don't kill me" values, old and new, as documented in eg:-
244 * http://lxr.linux.no/#linux+v2.6.32/Documentation/filesystems/proc.txt-
245 * http://lxr.linux.no/#linux+v2.6.36/Documentation/filesystems/proc.txt-
246 */-
247-
248static int oom_adj_save = INT_MIN;-
249static char *oom_adj_path = NULL;-
250struct {-
251 char *path;-
252 int value;-
253} oom_adjust[] = {-
254 {"/proc/self/oom_score_adj", -1000}, /* kernels >= 2.6.36 */-
255 {"/proc/self/oom_adj", -17}, /* kernels <= 2.6.35 */-
256 {NULL, 0},-
257};-
258-
259/*-
260 * Tell the kernel's out-of-memory killer to avoid sshd.-
261 * Returns the previous oom_adj value or zero.-
262 */-
263void-
264oom_adjust_setup(void)-
265{-
266 int i, value;-
267 FILE *fp;-
268-
269 debug3("%s", __func__);-
270 for (i = 0; oom_adjust[i].path != NULL; i++) {
oom_adjust[i]....!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
271 oom_adj_path = oom_adjust[i].path;-
272 value = oom_adjust[i].value;-
273 if ((fp = fopen(oom_adj_path, "r+")) != NULL) {
(fp = fopen(oo...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
274 if (fscanf(fp, "%d", &oom_adj_save) != 1)
fscanf(fp, "%d...adj_save) != 1Description
TRUEnever evaluated
FALSEnever evaluated
0
275 verbose("error reading %s: %s", oom_adj_path,
never executed: verbose("error reading %s: %s", oom_adj_path, strerror( (*__errno_location ()) ));
0
276 strerror(errno));
never executed: verbose("error reading %s: %s", oom_adj_path, strerror( (*__errno_location ()) ));
0
277 else {-
278 rewind(fp);-
279 if (fprintf(fp, "%d\n", value) <= 0)
fprintf(fp, "%...", value) <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
280 verbose("error writing %s: %s",
never executed: verbose("error writing %s: %s", oom_adj_path, strerror( (*__errno_location ()) ));
0
281 oom_adj_path, strerror(errno));
never executed: verbose("error writing %s: %s", oom_adj_path, strerror( (*__errno_location ()) ));
0
282 else-
283 debug("Set %s from %d to %d",
never executed: debug("Set %s from %d to %d", oom_adj_path, oom_adj_save, value);
0
284 oom_adj_path, oom_adj_save, value);
never executed: debug("Set %s from %d to %d", oom_adj_path, oom_adj_save, value);
0
285 }-
286 fclose(fp);-
287 return;
never executed: return;
0
288 }-
289 }
never executed: end of block
0
290 oom_adj_path = NULL;-
291}
never executed: end of block
0
292-
293/* Restore the saved OOM adjustment */-
294void-
295oom_adjust_restore(void)-
296{-
297 FILE *fp;-
298-
299 debug3("%s", __func__);-
300 if (oom_adj_save == INT_MIN || oom_adj_path == NULL ||
oom_adj_save =...x7fffffff - 1)Description
TRUEnever evaluated
FALSEnever evaluated
oom_adj_path == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
301 (fp = fopen(oom_adj_path, "w")) == NULL)
(fp = fopen(oo...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
302 return;
never executed: return;
0
303-
304 if (fprintf(fp, "%d\n", oom_adj_save) <= 0)
fprintf(fp, "%...adj_save) <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
305 verbose("error writing %s: %s", oom_adj_path, strerror(errno));
never executed: verbose("error writing %s: %s", oom_adj_path, strerror( (*__errno_location ()) ));
0
306 else-
307 debug("Set %s to %d", oom_adj_path, oom_adj_save);
never executed: debug("Set %s to %d", oom_adj_path, oom_adj_save);
0
308-
309 fclose(fp);-
310 return;
never executed: return;
0
311}-
312#endif /* LINUX_OOM_ADJUST */-
313#endif /* WITH_SELINUX || LINUX_OOM_ADJUST */-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.2