blob: c79e0e0de04b170664b9ecbe826d17e57f6e84a6 [file] [log] [blame]
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001/*
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
25extern char **environ;
26#endif
27
28static 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) */
47static char * const noslash[] = {
48 "LANG=",
49 "LANGUAGE=",
50 "LC_", /* anything with the LC_ prefix */
51 (char *) 0
52};
53
54void
55sanitize_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
88char *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#ifdef HAVE_SECURE_GETENV
104return secure_getenv(arg);
105#elif HAVE___SECURE_GETENV
106 return __secure_getenv(arg);
107#else
108 return getenv(arg);
109#endif
110}