]> git.ipfire.org Git - thirdparty/util-linux.git/blob - lib/env.c
lib: remove _RLD_ from forbid environment variable list
[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 "BASH_ENV=", /* GNU creeping featurism strikes again... */
30 "ENV=",
31 "HOME=",
32 "IFS=",
33 "KRB_CONF=",
34 "LD_", /* anything with the LD_ prefix */
35 "LIBPATH=",
36 "MAIL=",
37 "NLSPATH=",
38 "PATH=",
39 "SHELL=",
40 "SHLIB_PATH=",
41 (char *) 0
42 };
43
44 /* these are allowed, but with no slashes inside
45 (to work around security problems in GNU gettext) */
46 static char * const noslash[] = {
47 "LANG=",
48 "LANGUAGE=",
49 "LC_", /* anything with the LC_ prefix */
50 (char *) 0
51 };
52
53 void
54 sanitize_env(void)
55 {
56 char **envp = environ;
57 char * const *bad;
58 char **cur;
59 char **move;
60
61 for (cur = envp; *cur; cur++) {
62 for (bad = forbid; *bad; bad++) {
63 if (strncmp(*cur, *bad, strlen(*bad)) == 0) {
64 for (move = cur; *move; move++)
65 *move = *(move + 1);
66 cur--;
67 break;
68 }
69 }
70 }
71
72 for (cur = envp; *cur; cur++) {
73 for (bad = noslash; *bad; bad++) {
74 if (strncmp(*cur, *bad, strlen(*bad)) != 0)
75 continue;
76 if (!strchr(*cur, '/'))
77 continue; /* OK */
78 for (move = cur; *move; move++)
79 *move = *(move + 1);
80 cur--;
81 break;
82 }
83 }
84 }
85
86
87 char *safe_getenv(const char *arg)
88 {
89 uid_t ruid = getuid();
90
91 if (ruid != 0 || (ruid != geteuid()) || (getgid() != getegid()))
92 return NULL;
93 #ifdef HAVE_PRCTL
94 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 0)
95 return NULL;
96 #else
97 #if (defined(linux) && defined(SYS_prctl))
98 if (syscall(SYS_prctl, PR_GET_DUMPABLE, 0, 0, 0, 0) == 0)
99 return NULL;
100 #endif
101 #endif
102 #ifdef HAVE_SECURE_GETENV
103 return secure_getenv(arg);
104 #elif HAVE___SECURE_GETENV
105 return __secure_getenv(arg);
106 #else
107 return getenv(arg);
108 #endif
109 }