| /* |
| * Security checks of environment |
| * Added from shadow-utils package |
| * by Arkadiusz MiĆkiewicz <misiek@pld.ORG.PL> |
| * |
| */ |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #ifdef HAVE_SYS_PRCTL_H |
| #include <sys/prctl.h> |
| #else |
| #define PR_GET_DUMPABLE 3 |
| #endif |
| #if (!defined(HAVE_PRCTL) && defined(linux)) |
| #include <sys/syscall.h> |
| #endif |
| #include <unistd.h> |
| #include <sys/types.h> |
| |
| #include "env.h" |
| |
| #ifndef HAVE_ENVIRON_DECL |
| extern char **environ; |
| #endif |
| |
| static char * const forbid[] = { |
| "_RLD_=", |
| "BASH_ENV=", /* GNU creeping featurism strikes again... */ |
| "ENV=", |
| "HOME=", |
| "IFS=", |
| "KRB_CONF=", |
| "LD_", /* anything with the LD_ prefix */ |
| "LIBPATH=", |
| "MAIL=", |
| "NLSPATH=", |
| "PATH=", |
| "SHELL=", |
| "SHLIB_PATH=", |
| (char *) 0 |
| }; |
| |
| /* these are allowed, but with no slashes inside |
| (to work around security problems in GNU gettext) */ |
| static char * const noslash[] = { |
| "LANG=", |
| "LANGUAGE=", |
| "LC_", /* anything with the LC_ prefix */ |
| (char *) 0 |
| }; |
| |
| void |
| sanitize_env(void) |
| { |
| char **envp = environ; |
| char * const *bad; |
| char **cur; |
| char **move; |
| |
| for (cur = envp; *cur; cur++) { |
| for (bad = forbid; *bad; bad++) { |
| if (strncmp(*cur, *bad, strlen(*bad)) == 0) { |
| for (move = cur; *move; move++) |
| *move = *(move + 1); |
| cur--; |
| break; |
| } |
| } |
| } |
| |
| for (cur = envp; *cur; cur++) { |
| for (bad = noslash; *bad; bad++) { |
| if (strncmp(*cur, *bad, strlen(*bad)) != 0) |
| continue; |
| if (!strchr(*cur, '/')) |
| continue; /* OK */ |
| for (move = cur; *move; move++) |
| *move = *(move + 1); |
| cur--; |
| break; |
| } |
| } |
| } |
| |
| |
| char *safe_getenv(const char *arg) |
| { |
| uid_t ruid = getuid(); |
| |
| if (ruid != 0 || (ruid != geteuid()) || (getgid() != getegid())) |
| return NULL; |
| #ifdef HAVE_PRCTL |
| if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 0) |
| return NULL; |
| #else |
| #if (defined(linux) && defined(SYS_prctl)) |
| if (syscall(SYS_prctl, PR_GET_DUMPABLE, 0, 0, 0, 0) == 0) |
| return NULL; |
| #endif |
| #endif |
| #ifdef HAVE_SECURE_GETENV |
| return secure_getenv(arg); |
| #elif HAVE___SECURE_GETENV |
| return __secure_getenv(arg); |
| #else |
| return getenv(arg); |
| #endif |
| } |