]> git.ipfire.org Git - thirdparty/util-linux.git/blob - lib/env.c
build: fix redundant redeclaration warnings
[thirdparty/util-linux.git] / lib / env.c
1 /*
2 * Security checks of environment
3 * Added from shadow-utils package
4 * by Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
5 *
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #ifdef HAVE_SYS_PRCTL_H
12 #include <sys/prctl.h>
13 #else
14 #define PR_GET_DUMPABLE 3
15 #endif
16 #if (!defined(HAVE_PRCTL) && defined(linux))
17 #include <sys/syscall.h>
18 #endif
19 #include <unistd.h>
20 #include <sys/types.h>
21
22 #include "env.h"
23
24 #ifndef HAVE_ENVIRON_DECL
25 extern char **environ;
26 #endif
27
28 static char * const forbid[] = {
29 "_RLD_=",
30 "BASH_ENV=", /* GNU creeping featurism strikes again... */
31 "ENV=",
32 "HOME=",
33 "IFS=",
34 "KRB_CONF=",
35 "LD_", /* anything with the LD_ prefix */
36 "LIBPATH=",
37 "MAIL=",
38 "NLSPATH=",
39 "PATH=",
40 "SHELL=",
41 "SHLIB_PATH=",
42 (char *) 0
43 };
44
45 /* these are allowed, but with no slashes inside
46 (to work around security problems in GNU gettext) */
47 static char * const noslash[] = {
48 "LANG=",
49 "LANGUAGE=",
50 "LC_", /* anything with the LC_ prefix */
51 (char *) 0
52 };
53
54 void
55 sanitize_env(void)
56 {
57 char **envp = environ;
58 char * const *bad;
59 char **cur;
60 char **move;
61
62 for (cur = envp; *cur; cur++) {
63 for (bad = forbid; *bad; bad++) {
64 if (strncmp(*cur, *bad, strlen(*bad)) == 0) {
65 for (move = cur; *move; move++)
66 *move = *(move + 1);
67 cur--;
68 break;
69 }
70 }
71 }
72
73 for (cur = envp; *cur; cur++) {
74 for (bad = noslash; *bad; bad++) {
75 if (strncmp(*cur, *bad, strlen(*bad)) != 0)
76 continue;
77 if (!strchr(*cur, '/'))
78 continue; /* OK */
79 for (move = cur; *move; move++)
80 *move = *(move + 1);
81 cur--;
82 break;
83 }
84 }
85 }
86
87
88 char *safe_getenv(const char *arg)
89 {
90 uid_t ruid = getuid();
91
92 if (ruid != 0 || (ruid != geteuid()) || (getgid() != getegid()))
93 return NULL;
94 #ifdef HAVE_PRCTL
95 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 0)
96 return NULL;
97 #else
98 #if (defined(linux) && defined(SYS_prctl))
99 if (syscall(SYS_prctl, PR_GET_DUMPABLE, 0, 0, 0, 0) == 0)
100 return NULL;
101 #endif
102 #endif
103
104 #ifdef HAVE___SECURE_GETENV
105 return __secure_getenv(arg);
106 #else
107 return getenv(arg);
108 #endif
109 }