Group :: Sistema/Base
RPM: glibc
Main Changelog Spec Patches Sources Download Gear Bugs e FR Repocop
Patch: glibc-2.3.5-owl-alt-sanitize-env.patch
Download
Download
# Sanitize the environment in a paranoid way.
diff -upk.orig glibc-2.3.5.orig/argp/argp-help.c glibc-2.3.5/argp/argp-help.c
--- glibc-2.3.5.orig/argp/argp-help.c 2004-06-01 22:15:24 +0000
+++ glibc-2.3.5/argp/argp-help.c 2005-05-17 13:53:18 +0000
@@ -166,7 +166,7 @@ static const struct uparam_name uparam_n
static void
fill_in_uparams (const struct argp_state *state)
{
- const char *var = getenv ("ARGP_HELP_FMT");
+ const char *var = __secure_getenv ("ARGP_HELP_FMT");
#define SKIPWS(p) do { while (isspace (*p)) p++; } while (0);
diff -upk.orig glibc-2.3.5.orig/catgets/catgets.c glibc-2.3.5/catgets/catgets.c
--- glibc-2.3.5.orig/catgets/catgets.c 2002-05-15 03:46:42 +0000
+++ glibc-2.3.5/catgets/catgets.c 2005-05-17 13:53:18 +0000
@@ -50,7 +50,7 @@ catopen (const char *cat_name, int flag)
|| (__libc_enable_secure && strchr (env_var, '/') != NULL))
env_var = "C";
- nlspath = getenv ("NLSPATH");
+ nlspath = __secure_getenv ("NLSPATH");
if (nlspath != NULL && *nlspath != '\0')
{
/* Append the system dependent directory. */
diff -upk.orig glibc-2.3.5.orig/debug/pcprofile.c glibc-2.3.5/debug/pcprofile.c
--- glibc-2.3.5.orig/debug/pcprofile.c 2001-07-06 04:54:45 +0000
+++ glibc-2.3.5/debug/pcprofile.c 2005-05-17 13:53:18 +0000
@@ -38,7 +38,7 @@ install (void)
{
/* See whether the environment variable `PCPROFILE_OUTPUT' is defined.
If yes, it should name a FIFO. We open it and mark ourself as active. */
- const char *outfile = getenv ("PCPROFILE_OUTPUT");
+ const char *outfile = __secure_getenv ("PCPROFILE_OUTPUT");
if (outfile != NULL && *outfile != '\0')
{
diff -upk.orig glibc-2.3.5.orig/elf/dl-support.c glibc-2.3.5/elf/dl-support.c
--- glibc-2.3.5.orig/elf/dl-support.c 2004-11-06 00:24:49 +0000
+++ glibc-2.3.5/elf/dl-support.c 2005-05-23 02:18:40 +0000
@@ -159,6 +159,7 @@ void
internal_function
_dl_aux_init (ElfW(auxv_t) *av)
{
+ int security_mask = 0;
int seen = 0;
uid_t uid = 0;
gid_t gid = 0;
@@ -192,30 +193,34 @@ _dl_aux_init (ElfW(auxv_t) *av)
break;
#endif
case AT_UID:
+ if (seen & 1) break;
uid ^= av->a_un.a_val;
seen |= 1;
break;
case AT_EUID:
+ if (seen & 2) break;
uid ^= av->a_un.a_val;
seen |= 2;
break;
case AT_GID:
+ if (seen & 4) break;
gid ^= av->a_un.a_val;
seen |= 4;
break;
case AT_EGID:
+ if (seen & 8) break;
gid ^= av->a_un.a_val;
seen |= 8;
break;
case AT_SECURE:
- seen = -1;
- __libc_enable_secure = av->a_un.a_val;
- __libc_enable_secure_decided = 1;
+ security_mask |= av->a_un.a_val != 0;
break;
}
if (seen == 0xf)
{
- __libc_enable_secure = uid != 0 || gid != 0;
+ security_mask |= ((uid != 0) << 1) | ((gid != 0) << 2);
+ __libc_security_mask = security_mask;
+ __libc_enable_secure = __libc_security_mask != 0;
__libc_enable_secure_decided = 1;
}
}
@@ -232,19 +237,19 @@ _dl_non_dynamic_init (void)
if (!_dl_pagesize)
_dl_pagesize = __getpagesize ();
- _dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1;
+ _dl_verbose = *(__secure_getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1;
/* Initialize the data structures for the search paths for shared
objects. */
- _dl_init_paths (getenv ("LD_LIBRARY_PATH"));
+ _dl_init_paths (__secure_getenv ("LD_LIBRARY_PATH"));
- _dl_lazy = *(getenv ("LD_BIND_NOW") ?: "") == '\0';
+ _dl_lazy = *(__secure_getenv ("LD_BIND_NOW") ?: "") == '\0';
- _dl_bind_not = *(getenv ("LD_BIND_NOT") ?: "") != '\0';
+ _dl_bind_not = *(__secure_getenv ("LD_BIND_NOT") ?: "") != '\0';
- _dl_dynamic_weak = *(getenv ("LD_DYNAMIC_WEAK") ?: "") == '\0';
+ _dl_dynamic_weak = *(__secure_getenv ("LD_DYNAMIC_WEAK") ?: "") == '\0';
- _dl_profile_output = getenv ("LD_PROFILE_OUTPUT");
+ _dl_profile_output = __secure_getenv ("LD_PROFILE_OUTPUT");
if (_dl_profile_output == NULL || _dl_profile_output[0] == '\0')
_dl_profile_output
= &"/var/tmp\0/var/profile"[__libc_enable_secure ? 9 : 0];
@@ -257,6 +262,8 @@ _dl_non_dynamic_init (void)
EXTRA_UNSECURE_ENVVARS
#endif
;
+ static const char restricted_envvars[] =
+ RESTRICTED_ENVVARS;
const char *cp = unsecure_envvars;
while (cp < unsecure_envvars + sizeof (unsecure_envvars))
@@ -265,8 +272,31 @@ _dl_non_dynamic_init (void)
cp = (const char *) __rawmemchr (cp, '\0') + 1;
}
- if (__access ("/etc/suid-debug", F_OK) != 0)
- __unsetenv ("MALLOC_CHECK_");
+ if (__libc_security_mask & 2)
+ {
+ static const char unsecure_uid_envvars[] =
+ UNSECURE_UID_ENVVARS;
+
+ cp = unsecure_uid_envvars;
+ while (cp < unsecure_uid_envvars + sizeof (unsecure_uid_envvars))
+ {
+ __unsetenv (cp);
+ cp = (const char *) __rawmemchr (cp, '\0') + 1;
+ }
+ }
+
+ /* This loop is buggy: it will only check the first occurrence of each
+ variable (but will correctly remove all in case of a match). This
+ may be a problem if the list is later re-ordered or accessed by an
+ application with something other than the glibc getenv(). */
+ cp = restricted_envvars;
+ while (cp < restricted_envvars + sizeof (restricted_envvars))
+ {
+ const char *value = getenv (cp);
+ if (value && (value[0] == '.' || strchr(value, '/')))
+ __unsetenv (cp);
+ cp = (const char *) __rawmemchr (cp, '\0') + 1;
+ }
}
#ifdef DL_PLATFORM_INIT
diff -upk.orig glibc-2.3.5.orig/elf/rtld.c glibc-2.3.5/elf/rtld.c
--- glibc-2.3.5.orig/elf/rtld.c 2005-04-06 02:49:51 +0000
+++ glibc-2.3.5/elf/rtld.c 2005-05-23 01:53:37 +0000
@@ -2093,6 +2093,7 @@ process_envvars (enum mode *modep)
GLRO(dl_profile_output)
= &"/var/tmp\0/var/profile"[INTUSE(__libc_enable_secure) ? 9 : 0];
+ if (__builtin_expect (!INTUSE(__libc_enable_secure), 1))
while ((envline = _dl_next_ld_env_entry (&runp)) != NULL)
{
size_t len = 0;
@@ -2154,8 +2155,7 @@ process_envvars (enum mode *modep)
case 9:
/* Test whether we want to see the content of the auxiliary
array passed up from the kernel. */
- if (!INTUSE(__libc_enable_secure)
- && memcmp (envline, "SHOW_AUXV", 9) == 0)
+ if (memcmp (envline, "SHOW_AUXV", 9) == 0)
_dl_show_auxv ();
break;
@@ -2168,8 +2168,7 @@ process_envvars (enum mode *modep)
case 11:
/* Path where the binary is found. */
- if (!INTUSE(__libc_enable_secure)
- && memcmp (envline, "ORIGIN_PATH", 11) == 0)
+ if (memcmp (envline, "ORIGIN_PATH", 11) == 0)
GLRO(dl_origin_path) = &envline[12];
break;
@@ -2188,8 +2187,7 @@ process_envvars (enum mode *modep)
break;
}
- if (!INTUSE(__libc_enable_secure)
- && memcmp (envline, "DYNAMIC_WEAK", 12) == 0)
+ if (memcmp (envline, "DYNAMIC_WEAK", 12) == 0)
GLRO(dl_dynamic_weak) = 1;
break;
@@ -2199,15 +2197,13 @@ process_envvars (enum mode *modep)
#ifdef EXTRA_LD_ENVVARS_13
EXTRA_LD_ENVVARS_13
#endif
- if (!INTUSE(__libc_enable_secure)
- && memcmp (envline, "USE_LOAD_BIAS", 13) == 0)
+ if (memcmp (envline, "USE_LOAD_BIAS", 13) == 0)
GLRO(dl_use_load_bias) = envline[14] == '1' ? -1 : 0;
break;
case 14:
/* Where to place the profiling data file. */
- if (!INTUSE(__libc_enable_secure)
- && memcmp (envline, "PROFILE_OUTPUT", 14) == 0
+ if (memcmp (envline, "PROFILE_OUTPUT", 14) == 0
&& envline[15] != '\0')
GLRO(dl_profile_output) = &envline[15];
break;
@@ -2251,16 +2247,39 @@ process_envvars (enum mode *modep)
EXTRA_UNSECURE_ENVVARS
#endif
UNSECURE_ENVVARS;
+ static const char restricted_envvars[] =
+ RESTRICTED_ENVVARS;
const char *nextp;
- nextp = unsecure_envvars;
- do
+ for (nextp = unsecure_envvars; *nextp != '\0';
+ nextp = (char *) rawmemchr (nextp, '\0') + 1)
{
unsetenv (nextp);
- /* We could use rawmemchr but this need not be fast. */
- nextp = (char *) (strchr) (nextp, '\0') + 1;
}
- while (*nextp != '\0');
+
+ if (__builtin_expect (INTUSE(__libc_security_mask) & 2, 0))
+ {
+ static const char unsecure_uid_envvars[] =
+ UNSECURE_UID_ENVVARS;
+
+ for (nextp = unsecure_uid_envvars; *nextp != '\0';
+ nextp = (char *) rawmemchr (nextp, '\0') + 1)
+ {
+ unsetenv (nextp);
+ }
+ }
+
+ /* This loop is buggy: it will only check the first occurrence of each
+ variable (but will correctly remove all in case of a match). This
+ may be a problem if the list is later re-ordered or accessed by an
+ application with something other than the glibc getenv(). */
+ for (nextp = restricted_envvars; *nextp != '\0';
+ nextp = (char *) rawmemchr (nextp, '\0') + 1)
+ {
+ const char *value = getenv (nextp);
+ if (value && (value[0] == '.' || strchr(value, '/')))
+ unsetenv (nextp);
+ }
if (__access ("/etc/suid-debug", F_OK) != 0)
{
diff -upk.orig glibc-2.3.5.orig/elf/Versions glibc-2.3.5/elf/Versions
--- glibc-2.3.5.orig/elf/Versions 2004-10-19 22:20:33 +0000
+++ glibc-2.3.5/elf/Versions 2005-05-23 01:53:37 +0000
@@ -56,5 +56,6 @@ ld {
_dl_make_stack_executable;
# Only here for gdb while a better method is developed.
_dl_debug_state;
+ __libc_security_mask;
}
}
diff -upk.orig glibc-2.3.5.orig/gmon/gmon.c glibc-2.3.5/gmon/gmon.c
--- glibc-2.3.5.orig/gmon/gmon.c 2004-09-14 04:24:43 +0000
+++ glibc-2.3.5/gmon/gmon.c 2005-05-17 13:53:18 +0000
@@ -326,8 +326,8 @@ write_gmon (void)
# define O_NOFOLLOW 0
#endif
- env = getenv ("GMON_OUT_PREFIX");
- if (env != NULL && !__libc_enable_secure)
+ env = __secure_getenv ("GMON_OUT_PREFIX");
+ if (env != NULL)
{
size_t len = strlen (env);
char buf[len + 20];
diff -upk.orig glibc-2.3.5.orig/iconv/gconv_cache.c glibc-2.3.5/iconv/gconv_cache.c
--- glibc-2.3.5.orig/iconv/gconv_cache.c 2003-06-11 21:38:47 +0000
+++ glibc-2.3.5/iconv/gconv_cache.c 2005-05-17 13:53:18 +0000
@@ -55,7 +55,7 @@ __gconv_load_cache (void)
/* We cannot use the cache if the GCONV_PATH environment variable is
set. */
- __gconv_path_envvar = getenv ("GCONV_PATH");
+ __gconv_path_envvar = __secure_getenv ("GCONV_PATH");
if (__gconv_path_envvar != NULL)
return -1;
diff -upk.orig glibc-2.3.5.orig/include/unistd.h glibc-2.3.5/include/unistd.h
--- glibc-2.3.5.orig/include/unistd.h 2004-06-30 07:35:39 +0000
+++ glibc-2.3.5/include/unistd.h 2005-05-23 02:16:28 +0000
@@ -141,10 +141,12 @@ libc_hidden_proto (__sbrk)
and some functions contained in the C library ignore various
environment variables that normally affect them. */
extern int __libc_enable_secure attribute_relro;
+extern int __libc_security_mask attribute_relro;
extern int __libc_enable_secure_decided;
#ifdef IS_IN_rtld
/* XXX The #ifdef should go. */
extern int __libc_enable_secure_internal attribute_relro attribute_hidden;
+extern int __libc_security_mask_internal attribute_relro attribute_hidden;
#endif
diff -upk.orig glibc-2.3.5.orig/intl/loadmsgcat.c glibc-2.3.5/intl/loadmsgcat.c
--- glibc-2.3.5.orig/intl/loadmsgcat.c 2004-09-26 05:06:56 +0000
+++ glibc-2.3.5/intl/loadmsgcat.c 2005-05-17 13:53:18 +0000
@@ -816,7 +816,7 @@ _nl_init_domain_conv (domain_file, domai
outcharset = domainbinding->codeset;
else
{
- outcharset = getenv ("OUTPUT_CHARSET");
+ outcharset = __secure_getenv ("OUTPUT_CHARSET");
if (outcharset == NULL || outcharset[0] == '\0')
{
# ifdef _LIBC
diff -upk.orig glibc-2.3.5.orig/io/getdirname.c glibc-2.3.5/io/getdirname.c
--- glibc-2.3.5.orig/io/getdirname.c 2001-07-06 04:54:53 +0000
+++ glibc-2.3.5/io/getdirname.c 2005-05-17 13:53:18 +0000
@@ -31,7 +31,7 @@ get_current_dir_name (void)
char *pwd;
struct stat64 dotstat, pwdstat;
- pwd = getenv ("PWD");
+ pwd = __secure_getenv ("PWD");
if (pwd != NULL
&& stat64 (".", &dotstat) == 0
&& stat64 (pwd, &pwdstat) == 0
diff -upk.orig glibc-2.3.5.orig/libidn/toutf8.c glibc-2.3.5/libidn/toutf8.c
--- glibc-2.3.5.orig/libidn/toutf8.c 2004-03-08 20:52:56 +0000
+++ glibc-2.3.5/libidn/toutf8.c 2005-05-17 13:53:18 +0000
@@ -71,7 +71,7 @@
const char *
stringprep_locale_charset (void)
{
- const char *charset = getenv ("CHARSET"); /* flawfinder: ignore */
+ const char *charset = __secure_getenv ("CHARSET"); /* flawfinder: ignore */
if (charset && *charset)
return charset;
diff -upk.orig glibc-2.3.5.orig/locale/newlocale.c glibc-2.3.5/locale/newlocale.c
--- glibc-2.3.5.orig/locale/newlocale.c 2004-07-16 19:05:49 +0000
+++ glibc-2.3.5/locale/newlocale.c 2005-05-17 13:53:18 +0000
@@ -104,7 +104,7 @@ __newlocale (int category_mask, const ch
locale_path = NULL;
locale_path_len = 0;
- locpath_var = getenv ("LOCPATH");
+ locpath_var = __secure_getenv ("LOCPATH");
if (locpath_var != NULL && locpath_var[0] != '\0')
{
if (__argz_create_sep (locpath_var, ':',
diff -upk.orig glibc-2.3.5.orig/locale/setlocale.c glibc-2.3.5/locale/setlocale.c
--- glibc-2.3.5.orig/locale/setlocale.c 2004-08-04 21:55:05 +0000
+++ glibc-2.3.5/locale/setlocale.c 2005-05-17 13:53:18 +0000
@@ -237,7 +237,7 @@ setlocale (int category, const char *loc
locale_path = NULL;
locale_path_len = 0;
- locpath_var = getenv ("LOCPATH");
+ locpath_var = __secure_getenv ("LOCPATH");
if (locpath_var != NULL && locpath_var[0] != '\0')
{
if (__argz_create_sep (locpath_var, ':',
diff -upk.orig glibc-2.3.5.orig/malloc/arena.c glibc-2.3.5/malloc/arena.c
--- glibc-2.3.5.orig/malloc/arena.c 2005-03-07 22:46:24 +0000
+++ glibc-2.3.5/malloc/arena.c 2005-05-17 13:53:18 +0000
@@ -456,10 +456,10 @@ ptmalloc_init (void)
# undef NO_STARTER
# endif
#endif
+ s = NULL;
#ifdef _LIBC
secure = __libc_enable_secure;
- s = NULL;
- if (__builtin_expect (_environ != NULL, 1))
+ if (! secure && __builtin_expect (_environ != NULL, 1))
{
char **runp = _environ;
char *envline;
@@ -482,15 +482,14 @@ ptmalloc_init (void)
s = &envline[7];
break;
case 8:
- if (! secure && memcmp (envline, "TOP_PAD_", 8) == 0)
+ if (memcmp (envline, "TOP_PAD_", 8) == 0)
mALLOPt(M_TOP_PAD, atoi(&envline[9]));
break;
case 9:
- if (! secure && memcmp (envline, "MMAP_MAX_", 9) == 0)
+ if (memcmp (envline, "MMAP_MAX_", 9) == 0)
mALLOPt(M_MMAP_MAX, atoi(&envline[10]));
break;
case 15:
- if (! secure)
{
if (memcmp (envline, "TRIM_THRESHOLD_", 15) == 0)
mALLOPt(M_TRIM_THRESHOLD, atoi(&envline[16]));
diff -upk.orig glibc-2.3.5.orig/malloc/memusage.c glibc-2.3.5/malloc/memusage.c
--- glibc-2.3.5.orig/malloc/memusage.c 2004-08-10 04:11:50 +0000
+++ glibc-2.3.5/malloc/memusage.c 2005-05-17 13:53:18 +0000
@@ -193,7 +193,7 @@ int_handler (int signo)
static void
me (void)
{
- const char *env = getenv ("MEMUSAGE_PROG_NAME");
+ const char *env = __secure_getenv ("MEMUSAGE_PROG_NAME");
size_t prog_len = strlen (__progname);
initialized = -1;
@@ -229,7 +229,7 @@ me (void)
if (!start_sp)
start_sp = GETSP ();
- outname = getenv ("MEMUSAGE_OUTPUT");
+ outname = __secure_getenv ("MEMUSAGE_OUTPUT");
if (outname != NULL && outname[0] != '\0'
&& (access (outname, R_OK | W_OK) == 0 || errno == ENOENT))
{
@@ -251,7 +251,7 @@ me (void)
/* Determine the buffer size. We use the default if the
environment variable is not present. */
buffer_size = DEFAULT_BUFFER_SIZE;
- if (getenv ("MEMUSAGE_BUFFER_SIZE") != NULL)
+ if (__secure_getenv ("MEMUSAGE_BUFFER_SIZE") != NULL)
{
buffer_size = atoi (getenv ("MEMUSAGE_BUFFER_SIZE"));
if (buffer_size == 0 || buffer_size > DEFAULT_BUFFER_SIZE)
@@ -259,7 +259,7 @@ me (void)
}
/* Possibly enable timer-based stack pointer retrieval. */
- if (getenv ("MEMUSAGE_NO_TIMER") == NULL)
+ if (__secure_getenv ("MEMUSAGE_NO_TIMER") == NULL)
{
struct sigaction act;
@@ -280,7 +280,7 @@ me (void)
}
}
- if (!not_me && getenv ("MEMUSAGE_TRACE_MMAP") != NULL)
+ if (!not_me && __secure_getenv ("MEMUSAGE_TRACE_MMAP") != NULL)
trace_mmap = true;
}
}
diff -upk.orig glibc-2.3.5.orig/nis/nis_defaults.c glibc-2.3.5/nis/nis_defaults.c
--- glibc-2.3.5.orig/nis/nis_defaults.c 2004-10-24 20:28:28 +0000
+++ glibc-2.3.5/nis/nis_defaults.c 2005-05-17 13:53:18 +0000
@@ -379,7 +379,7 @@ __nis_default_owner (char *defaults)
}
else
{
- cptr = getenv ("NIS_DEFAULTS");
+ cptr = __secure_getenv ("NIS_DEFAULTS");
if (cptr != NULL)
{
dptr = strstr (cptr, "owner=");
@@ -419,7 +419,7 @@ __nis_default_group (char *defaults)
}
else
{
- cptr = getenv ("NIS_DEFAULTS");
+ cptr = __secure_getenv ("NIS_DEFAULTS");
if (cptr != NULL)
{
dptr = strstr (cptr, "group=");
@@ -450,7 +450,7 @@ __nis_default_ttl (char *defaults)
return searchttl (defaults);
}
- cptr = getenv ("NIS_DEFAULTS");
+ cptr = __secure_getenv ("NIS_DEFAULTS");
if (cptr == NULL)
return DEFAULT_TTL;
@@ -478,9 +478,9 @@ __nis_default_access (char *param, unsig
result = searchaccess (param, result);
else
{
- cptr = getenv ("NIS_DEFAULTS");
+ cptr = __secure_getenv ("NIS_DEFAULTS");
if (cptr != NULL && strstr (cptr, "access=") != NULL)
- result = searchaccess (getenv ("NIS_DEFAULTS"), result);
+ result = searchaccess (cptr, result);
}
return result;
diff -upk.orig glibc-2.3.5.orig/nis/nis_local_names.c glibc-2.3.5/nis/nis_local_names.c
--- glibc-2.3.5.orig/nis/nis_local_names.c 2004-10-24 20:28:28 +0000
+++ glibc-2.3.5/nis/nis_local_names.c 2005-05-17 13:53:18 +0000
@@ -30,7 +30,7 @@ nis_local_group (void)
char *cptr;
if (__nisgroup[0] == '\0'
- && (cptr = getenv ("NIS_GROUP")) != NULL
+ && (cptr = __secure_getenv ("NIS_GROUP")) != NULL
&& strlen (cptr) < NIS_MAXNAMELEN)
{
char *cp = stpcpy (__nisgroup, cptr);
diff -upk.orig glibc-2.3.5.orig/nis/nis_subr.c glibc-2.3.5/nis/nis_subr.c
--- glibc-2.3.5.orig/nis/nis_subr.c 2004-10-24 20:28:28 +0000
+++ glibc-2.3.5/nis/nis_subr.c 2005-05-17 13:53:18 +0000
@@ -152,7 +152,7 @@ nis_getnames (const_nis_name name)
}
/* Get the search path, where we have to search "name" */
- path = getenv ("NIS_PATH");
+ path = __secure_getenv ("NIS_PATH");
if (path == NULL)
path = strdupa ("$");
else
diff -upk.orig glibc-2.3.5.orig/posix/execvp.c glibc-2.3.5/posix/execvp.c
--- glibc-2.3.5.orig/posix/execvp.c 2005-02-26 01:02:17 +0000
+++ glibc-2.3.5/posix/execvp.c 2005-05-23 01:53:37 +0000
@@ -87,19 +87,18 @@ execvp (file, argv)
}
else
{
- char *path = getenv ("PATH");
+ char *path = __secure_getenv ("PATH");
bool path_malloc = false;
if (path == NULL)
{
/* There is no `PATH' in the environment.
- The default search path is the current directory
- followed by the path `confstr' returns for `_CS_PATH'. */
+ The default search path is what `confstr' returns
+ for `_CS_PATH'. */
size_t len = confstr (_CS_PATH, (char *) NULL, 0);
- path = (char *) malloc (1 + len);
+ path = (char *) malloc (len);
if (path == NULL)
return -1;
- path[0] = ':';
- (void) confstr (_CS_PATH, path + 1, len);
+ (void) confstr (_CS_PATH, path, len);
path_malloc = true;
}
diff -upk.orig glibc-2.3.5.orig/resolv/res_hconf.c glibc-2.3.5/resolv/res_hconf.c
--- glibc-2.3.5.orig/resolv/res_hconf.c 2004-06-01 22:17:39 +0000
+++ glibc-2.3.5/resolv/res_hconf.c 2005-05-17 13:53:18 +0000
@@ -431,7 +431,7 @@ do_init (void)
memset (&_res_hconf, '\0', sizeof (_res_hconf));
- hconf_name = getenv (ENV_HOSTCONF);
+ hconf_name = __secure_getenv (ENV_HOSTCONF);
if (hconf_name == NULL)
hconf_name = _PATH_HOSTCONF;
@@ -453,30 +453,30 @@ do_init (void)
fclose (fp);
}
- envval = getenv (ENV_SERVORDER);
+ envval = __secure_getenv (ENV_SERVORDER);
if (envval)
{
_res_hconf.num_services = 0;
arg_service_list (ENV_SERVORDER, 1, envval, 0);
}
- envval = getenv (ENV_SPOOF);
+ envval = __secure_getenv (ENV_SPOOF);
if (envval)
arg_spoof (ENV_SPOOF, 1, envval, 0);
- envval = getenv (ENV_MULTI);
+ envval = __secure_getenv (ENV_MULTI);
if (envval)
arg_bool (ENV_MULTI, 1, envval, HCONF_FLAG_MULTI);
- envval = getenv (ENV_REORDER);
+ envval = __secure_getenv (ENV_REORDER);
if (envval)
arg_bool (ENV_REORDER, 1, envval, HCONF_FLAG_REORDER);
- envval = getenv (ENV_TRIM_ADD);
+ envval = __secure_getenv (ENV_TRIM_ADD);
if (envval)
arg_trimdomain_list (ENV_TRIM_ADD, 1, envval, 0);
- envval = getenv (ENV_TRIM_OVERR);
+ envval = __secure_getenv (ENV_TRIM_OVERR);
if (envval)
{
_res_hconf.num_trimdomains = 0;
diff -upk.orig glibc-2.3.5.orig/resolv/res_init.c glibc-2.3.5/resolv/res_init.c
--- glibc-2.3.5.orig/resolv/res_init.c 2004-10-11 20:49:25 +0000
+++ glibc-2.3.5/resolv/res_init.c 2005-05-23 01:53:37 +0000
@@ -201,7 +201,7 @@ __res_vinit(res_state statp, int preinit
#endif
/* Allow user to override the local domain definition */
- if ((cp = getenv("LOCALDOMAIN")) != NULL) {
+ if ((cp = __secure_getenv("LOCALDOMAIN")) != NULL) {
(void)strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1);
statp->defdname[sizeof(statp->defdname) - 1] = '\0';
haveenv++;
@@ -441,7 +441,7 @@ __res_vinit(res_state statp, int preinit
#endif /* !RFC1535 */
}
- if ((cp = getenv("RES_OPTIONS")) != NULL)
+ if ((cp = __secure_getenv("RES_OPTIONS")) != NULL)
res_setoptions(statp, cp, "env");
statp->options |= RES_INIT;
return (0);
diff -upk.orig glibc-2.3.5.orig/resolv/res_query.c glibc-2.3.5/resolv/res_query.c
--- glibc-2.3.5.orig/resolv/res_query.c 2004-10-18 05:09:59 +0000
+++ glibc-2.3.5/resolv/res_query.c 2005-05-17 13:53:18 +0000
@@ -453,7 +453,7 @@ res_hostalias(const res_state statp, con
if (statp->options & RES_NOALIASES)
return (NULL);
- file = getenv("HOSTALIASES");
+ file = __secure_getenv("HOSTALIASES");
if (file == NULL || (fp = fopen(file, "r")) == NULL)
return (NULL);
setbuf(fp, NULL);
diff -upk.orig glibc-2.3.5.orig/stdlib/fmtmsg.c glibc-2.3.5/stdlib/fmtmsg.c
--- glibc-2.3.5.orig/stdlib/fmtmsg.c 2005-02-16 10:37:10 +0000
+++ glibc-2.3.5/stdlib/fmtmsg.c 2005-05-17 13:53:18 +0000
@@ -226,8 +226,8 @@ fmtmsg (long int classification, const c
static void
init (void)
{
- const char *msgverb_var = getenv ("MSGVERB");
- const char *sevlevel_var = getenv ("SEV_LEVEL");
+ const char *msgverb_var = __secure_getenv ("MSGVERB");
+ const char *sevlevel_var = __secure_getenv ("SEV_LEVEL");
if (msgverb_var != NULL && msgverb_var[0] != '\0')
{
diff -upk.orig glibc-2.3.5.orig/sunrpc/rpc_svcout.c glibc-2.3.5/sunrpc/rpc_svcout.c
--- glibc-2.3.5.orig/sunrpc/rpc_svcout.c 2004-10-17 14:59:39 +0000
+++ glibc-2.3.5/sunrpc/rpc_svcout.c 2005-05-17 13:53:18 +0000
@@ -901,7 +901,7 @@ write_pm_most (const char *infile, int n
f_print (fout, "\t\t_rpcpmstart = 1;\n");
if (logflag)
open_log_file (infile, "\t\t");
- f_print (fout, "\t\tif ((netid = getenv(\"NLSPROVIDER\")) == NULL) {\n");
+ f_print (fout, "\t\tif ((netid = __secure_getenv(\"NLSPROVIDER\")) == NULL) {\n");
sprintf (_errbuf, "cannot get transport name");
print_err_message ("\t\t\t");
f_print (fout, "\t\t} else if ((nconf = getnetconfigent(netid)) == NULL) {\n");
diff -upk.orig glibc-2.3.5.orig/sysdeps/generic/dl-sysdep.c glibc-2.3.5/sysdeps/generic/dl-sysdep.c
--- glibc-2.3.5.orig/sysdeps/generic/dl-sysdep.c 2004-11-06 00:24:47 +0000
+++ glibc-2.3.5/sysdeps/generic/dl-sysdep.c 2005-05-23 02:19:02 +0000
@@ -48,8 +48,10 @@ extern void __libc_check_standard_fds (v
#ifdef NEED_DL_BASE_ADDR
ElfW(Addr) _dl_base_addr;
#endif
-int __libc_enable_secure attribute_relro = 0;
+int __libc_enable_secure attribute_relro = 1;
INTVARDEF(__libc_enable_secure)
+int __libc_security_mask attribute_relro = 0x7fffffff;
+INTVARDEF(__libc_security_mask)
int __libc_multiple_libcs = 0; /* Defining this here avoids the inclusion
of init-first. */
/* This variable contains the lowest stack address ever used. */
@@ -74,6 +76,10 @@ static ElfW(auxv_t) *_dl_auxv attribute_
# define DL_STACK_END(cookie) ((void *) (cookie))
#endif
+#ifdef HAVE_AUX_XID
+#undef HAVE_AUX_XID
+#endif
+
ElfW(Addr)
_dl_sysdep_start (void **start_argptr,
void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phnum,
@@ -83,19 +89,19 @@ _dl_sysdep_start (void **start_argptr,
ElfW(Word) phnum = 0;
ElfW(Addr) user_entry;
ElfW(auxv_t) *av;
-#ifdef HAVE_AUX_SECURE
+ int security_mask = 0;
+#if 0
# define set_seen(tag) (tag) /* Evaluate for the side effects. */
-# define set_seen_secure() ((void) 0)
#else
uid_t uid = 0;
gid_t gid = 0;
unsigned int seen = 0;
-# define set_seen_secure() (seen = -1)
# ifdef HAVE_AUX_XID
# define set_seen(tag) (tag) /* Evaluate for the side effects. */
# else
# define M(type) (1 << (type))
# define set_seen(tag) seen |= M ((tag)->a_type)
+# define is_seen(tag) seen & M ((tag)->a_type)
# endif
#endif
#ifdef NEED_DL_SYSINFO
@@ -129,21 +135,18 @@ _dl_sysdep_start (void **start_argptr,
_dl_base_addr = av->a_un.a_val;
break;
#endif
-#ifndef HAVE_AUX_SECURE
case AT_UID:
case AT_EUID:
+ if (is_seen (av)) break;
uid ^= av->a_un.a_val;
break;
case AT_GID:
case AT_EGID:
+ if (is_seen (av)) break;
gid ^= av->a_un.a_val;
break;
-#endif
case AT_SECURE:
-#ifndef HAVE_AUX_SECURE
- seen = -1;
-#endif
- INTUSE(__libc_enable_secure) = av->a_un.a_val;
+ security_mask |= av->a_un.a_val != 0;
break;
case AT_PLATFORM:
GLRO(dl_platform) = av->a_un.a_ptr;
@@ -176,8 +179,6 @@ _dl_sysdep_start (void **start_argptr,
DL_SYSDEP_OSCHECK (dl_fatal);
#endif
-#ifndef HAVE_AUX_SECURE
- if (seen != -1)
{
/* Fill in the values we have not gotten from the kernel through the
auxiliary vector. */
@@ -189,12 +190,12 @@ _dl_sysdep_start (void **start_argptr,
SEE (GID, gid, gid);
SEE (EGID, gid, egid);
# endif
-
- /* If one of the two pairs of IDs does not match this is a setuid
- or setgid run. */
- INTUSE(__libc_enable_secure) = uid | gid;
}
-#endif
+ /* If one of the two pairs of IDs does not match
+ this is a setuid or setgid run. */
+ security_mask |= ((uid != 0) << 1) | ((gid != 0) << 2);
+ INTUSE(__libc_security_mask) = security_mask;
+ INTUSE(__libc_enable_secure) = security_mask != 0;
#ifndef HAVE_AUX_PAGESIZE
if (GLRO(dl_pagesize) == 0)
diff -upk.orig glibc-2.3.5.orig/sysdeps/generic/enbl-secure.c glibc-2.3.5/sysdeps/generic/enbl-secure.c
--- glibc-2.3.5.orig/sysdeps/generic/enbl-secure.c 2003-05-06 06:33:13 +0000
+++ glibc-2.3.5/sysdeps/generic/enbl-secure.c 2005-05-23 02:21:09 +0000
@@ -27,11 +27,17 @@
int __libc_enable_secure_decided;
/* Safest assumption, if somehow the initializer isn't run. */
int __libc_enable_secure = 1;
+int __libc_security_mask = 0x7fffffff;
void
__libc_init_secure (void)
{
if (__libc_enable_secure_decided == 0)
- __libc_enable_secure = (__geteuid () != __getuid ()
- || __getegid () != __getgid ());
+ {
+ __libc_security_mask =
+ ((__geteuid () != __getuid ()) << 1) |
+ ((__getegid () != __getgid ()) << 2);
+ __libc_enable_secure = __libc_security_mask != 0;
+ __libc_security_mask |= __libc_enable_secure;
+ }
}
diff -upk.orig glibc-2.3.5.orig/sysdeps/generic/glob.c glibc-2.3.5/sysdeps/generic/glob.c
--- glibc-2.3.5.orig/sysdeps/generic/glob.c 2004-10-27 18:21:02 +0000
+++ glibc-2.3.5/sysdeps/generic/glob.c 2005-05-23 01:53:37 +0000
@@ -171,7 +171,7 @@ extern int errno;
# define ANSI_STRING
#else /* No standard headers. */
-extern char *getenv ();
+extern char *__secure_getenv ();
# ifdef HAVE_STRING_H
# include <string.h>
@@ -693,7 +693,7 @@ glob (pattern, flags, errfunc, pglob)
if (dirname[1] == '\0' || dirname[1] == '/')
{
/* Look up home directory. */
- const char *home_dir = getenv ("HOME");
+ const char *home_dir = __secure_getenv ("HOME");
# ifdef _AMIGA
if (home_dir == NULL || home_dir[0] == '\0')
home_dir = "SYS:";
diff -upk.orig glibc-2.3.5.orig/sysdeps/generic/segfault.c glibc-2.3.5/sysdeps/generic/segfault.c
--- glibc-2.3.5.orig/sysdeps/generic/segfault.c 2004-10-14 02:22:13 +0000
+++ glibc-2.3.5/sysdeps/generic/segfault.c 2005-05-17 13:53:18 +0000
@@ -149,7 +149,7 @@ __attribute__ ((constructor))
install_handler (void)
{
struct sigaction sa;
- const char *sigs = getenv ("SEGFAULT_SIGNALS");
+ const char *sigs = __secure_getenv ("SEGFAULT_SIGNALS");
const char *name;
sa.sa_handler = (void *) catch_segfault;
@@ -157,7 +157,7 @@ install_handler (void)
sa.sa_flags = SA_RESTART;
/* Maybe we are expected to use an alternative stack. */
- if (getenv ("SEGFAULT_USE_ALTSTACK") != 0)
+ if (__secure_getenv ("SEGFAULT_USE_ALTSTACK") != 0)
{
void *stack_mem = malloc (2 * SIGSTKSZ);
struct sigaltstack ss;
@@ -203,7 +203,7 @@ install_handler (void)
}
/* Preserve the output file name if there is any given. */
- name = getenv ("SEGFAULT_OUTPUT_NAME");
+ name = __secure_getenv ("SEGFAULT_OUTPUT_NAME");
if (name != NULL && name[0] != '\0')
{
int ret = access (name, R_OK | W_OK);
diff -upk.orig glibc-2.3.5.orig/sysdeps/generic/unsecvars.h glibc-2.3.5/sysdeps/generic/unsecvars.h
--- glibc-2.3.5.orig/sysdeps/generic/unsecvars.h 2004-12-07 06:54:31 +0000
+++ glibc-2.3.5/sysdeps/generic/unsecvars.h 2005-05-17 13:53:18 +0000
@@ -2,23 +2,82 @@
all stuffed in a single string which means they have to be terminated
with a '\0' explicitly. */
#define UNSECURE_ENVVARS \
- "LD_PRELOAD\0" \
- "LD_LIBRARY_PATH\0" \
- "LD_ORIGIN_PATH\0" \
- "LD_DEBUG\0" \
- "LD_DEBUG_OUTPUT\0" \
- "LD_PROFILE\0" \
- "LD_USE_LOAD_BIAS\0" \
- "LD_DYNAMIC_WEAK\0" \
- "LD_SHOW_AUXV\0" \
- "GCONV_PATH\0" \
- "GETCONF_DIR\0" \
- "HOSTALIASES\0" \
- "LOCALDOMAIN\0" \
- "LOCPATH\0" \
- "MALLOC_TRACE\0" \
- "NLSPATH\0" \
- "RESOLV_HOST_CONF\0" \
- "RES_OPTIONS\0" \
- "TMPDIR\0" \
+ "ARGP_HELP_FMT\0" \
+ "DATEMSK\0" \
+ "GCONV_PATH\0" \
+ "GETCONF_DIR\0" \
+ "GMON_OUT_PREFIX\0" \
+ "HESIOD_CONFIG\0" \
+ "HES_DOMAIN\0" \
+ "HOSTALIASES\0" \
+ "LD_BIND_NOT\0" \
+ "LD_BIND_NOW\0" \
+ "LD_DEBUG\0" \
+ "LD_DEBUG_OUTPUT\0" \
+ "LD_DYNAMIC_WEAK\0" \
+ "LD_HWCAP_MASK\0" \
+ "LD_LIBRARY_PATH\0" \
+ "LD_ORIGIN_PATH\0" \
+ "LD_PRELOAD\0" \
+ "LD_PROFILE\0" \
+ "LD_PROFILE_OUTPUT\0" \
+ "LD_SHOW_AUXV\0" \
+ "LD_TRACE_LOADED_OBJECTS\0" \
+ "LD_USE_LOAD_BIAS\0" \
+ "LD_WARN\0" \
+ "LOCALDOMAIN\0" \
+ "LOCPATH\0" \
+ "MALLOC_CHECK_\0" \
+ "MALLOC_MMAP_MAX_\0" \
+ "MALLOC_MMAP_THRESHOLD_\0" \
+ "MALLOC_TOP_PAD_\0" \
+ "MALLOC_TRACE\0" \
+ "MALLOC_TRIM_THRESHOLD_\0" \
+ "MEMUSAGE_BUFFER_SIZE\0" \
+ "MEMUSAGE_NO_TIMER\0" \
+ "MEMUSAGE_OUTPUT\0" \
+ "MEMUSAGE_PROG_NAME\0" \
+ "MEMUSAGE_TRACE_MMAP\0" \
+ "MSGVERB\0" \
+ "NIS_DEFAULTS\0" \
+ "NIS_GROUP\0" \
+ "NIS_PATH\0" \
+ "NLSPATH\0" \
+ "PCPROFILE_OUTPUT\0" \
+ "POSIXLY_CORRECT\0" \
+ "PWD\0" \
+ "RESOLV_ADD_TRIM_DOMAINS\0" \
+ "RESOLV_HOST_CONF\0" \
+ "RESOLV_MULTI\0" \
+ "RESOLV_OVERRIDE_TRIM_DOMAINS\0" \
+ "RESOLV_REORDER\0" \
+ "RESOLV_SERV_ORDER\0" \
+ "RESOLV_SPOOF_CHECK\0" \
+ "RES_OPTIONS\0" \
+ "SEGFAULT_OUTPUT_NAME\0" \
+ "SEGFAULT_SIGNALS\0" \
+ "SEGFAULT_USE_ALTSTACK\0" \
+ "SEV_LEVEL\0" \
+ "TZ\0" \
"TZDIR\0"
+
+#define UNSECURE_UID_ENVVARS \
+ "TMPDIR\0"
+
+#define RESTRICTED_ENVVARS \
+ "LANG\0" \
+ "LANGUAGE\0" \
+ "LC_ADDRESS\0" \
+ "LC_ALL\0" \
+ "LC_COLLATE\0" \
+ "LC_CTYPE\0" \
+ "LC_IDENTIFICATION\0" \
+ "LC_MEASUREMENT\0" \
+ "LC_MESSAGES\0" \
+ "LC_MONETARY\0" \
+ "LC_NAME\0" \
+ "LC_NUMERIC\0" \
+ "LC_PAPER\0" \
+ "LC_TELEPHONE\0" \
+ "LC_TIME\0" \
+ "LC_XXX\0"
diff -upk.orig glibc-2.3.5.orig/sysdeps/generic/wordexp.c glibc-2.3.5/sysdeps/generic/wordexp.c
--- glibc-2.3.5.orig/sysdeps/generic/wordexp.c 2005-02-16 10:56:31 +0000
+++ glibc-2.3.5/sysdeps/generic/wordexp.c 2005-05-17 13:53:18 +0000
@@ -315,7 +315,7 @@ parse_tilde (char **word, size_t *word_l
results are unspecified. We do a lookup on the uid if
HOME is unset. */
- home = getenv ("HOME");
+ home = __secure_getenv ("HOME");
if (home != NULL)
{
*word = w_addstr (*word, word_length, max_length, home);
@@ -1491,7 +1491,7 @@ envsubst:
}
}
else
- value = getenv (env);
+ value = __secure_getenv (env);
if (value == NULL && (flags & WRDE_UNDEF))
{
@@ -2268,7 +2268,7 @@ wordexp (const char *words, wordexp_t *p
/* Find out what the field separators are.
* There are two types: whitespace and non-whitespace.
*/
- ifs = getenv ("IFS");
+ ifs = __secure_getenv ("IFS");
if (!ifs)
/* IFS unset - use <space><tab><newline>. */
diff -upk.orig glibc-2.3.5.orig/sysdeps/posix/spawni.c glibc-2.3.5/sysdeps/posix/spawni.c
--- glibc-2.3.5.orig/sysdeps/posix/spawni.c 2004-09-12 18:05:00 +0000
+++ glibc-2.3.5/sysdeps/posix/spawni.c 2005-05-17 13:53:18 +0000
@@ -216,16 +216,15 @@ __spawni (pid_t *pid, const char *file,
}
/* We have to search for FILE on the path. */
- path = getenv ("PATH");
+ path = __secure_getenv ("PATH");
if (path == NULL)
{
/* There is no `PATH' in the environment.
- The default search path is the current directory
- followed by the path `confstr' returns for `_CS_PATH'. */
+ The default search path is ehat `confstr' returns
+ for `_CS_PATH'. */
len = confstr (_CS_PATH, (char *) NULL, 0);
- path = (char *) __alloca (1 + len);
- path[0] = ':';
- (void) confstr (_CS_PATH, path + 1, len);
+ path = (char *) __alloca (len);
+ (void) confstr (_CS_PATH, path, len);
}
len = strlen (file) + 1;
diff -upk.orig glibc-2.3.5.orig/sysdeps/unix/sysv/linux/dl-librecon.h glibc-2.3.5/sysdeps/unix/sysv/linux/dl-librecon.h
--- glibc-2.3.5.orig/sysdeps/unix/sysv/linux/dl-librecon.h 2004-03-05 10:14:48 +0000
+++ glibc-2.3.5/sysdeps/unix/sysv/linux/dl-librecon.h 2005-05-23 01:53:37 +0000
@@ -53,7 +53,7 @@ _dl_osversion_init (char *assume_kernel)
#define DL_OSVERSION_INIT \
do { \
- char *assume_kernel = getenv ("LD_ASSUME_KERNEL"); \
+ char *assume_kernel = __secure_getenv ("LD_ASSUME_KERNEL"); \
if (assume_kernel) \
_dl_osversion_init (assume_kernel); \
} while (0)
diff -upk.orig glibc-2.3.5.orig/sysdeps/unix/sysv/linux/i386/dl-librecon.h glibc-2.3.5/sysdeps/unix/sysv/linux/i386/dl-librecon.h
--- glibc-2.3.5.orig/sysdeps/unix/sysv/linux/i386/dl-librecon.h 2004-10-14 01:53:55 +0000
+++ glibc-2.3.5/sysdeps/unix/sysv/linux/i386/dl-librecon.h 2005-05-17 13:53:18 +0000
@@ -57,6 +57,7 @@
/* Extra unsecure variables. The names are all stuffed in a single
string which means they have to be terminated with a '\0' explicitly. */
#define EXTRA_UNSECURE_ENVVARS \
+ "LD_LIBRARY_VERSION\0" \
"LD_AOUT_LIBRARY_PATH\0" \
"LD_AOUT_PRELOAD\0"
diff -upk.orig glibc-2.3.5.orig/time/getdate.c glibc-2.3.5/time/getdate.c
--- glibc-2.3.5.orig/time/getdate.c 2003-09-04 08:25:11 +0000
+++ glibc-2.3.5/time/getdate.c 2005-05-17 13:53:18 +0000
@@ -115,7 +115,7 @@ __getdate_r (const char *string, struct
struct stat64 st;
int mday_ok = 0;
- datemsk = getenv ("DATEMSK");
+ datemsk = __secure_getenv ("DATEMSK");
if (datemsk == NULL || *datemsk == '\0')
return 1;
diff -upk.orig glibc-2.3.5.orig/time/tzfile.c glibc-2.3.5/time/tzfile.c
--- glibc-2.3.5.orig/time/tzfile.c 2004-11-20 20:23:03 +0000
+++ glibc-2.3.5/time/tzfile.c 2005-05-17 13:53:18 +0000
@@ -133,7 +133,7 @@ __tzfile_read (const char *file, size_t
unsigned int len, tzdir_len;
char *new, *tmp;
- tzdir = getenv ("TZDIR");
+ tzdir = __secure_getenv ("TZDIR");
if (tzdir == NULL || *tzdir == '\0')
{
tzdir = default_tzdir;
diff -upk.orig glibc-2.3.5.orig/time/tzset.c glibc-2.3.5/time/tzset.c
--- glibc-2.3.5.orig/time/tzset.c 2004-12-06 22:50:41 +0000
+++ glibc-2.3.5/time/tzset.c 2005-05-17 13:53:18 +0000
@@ -158,8 +158,11 @@ tzset_internal (always, explicit)
return;
is_initialized = 1;
- /* Examine the TZ environment variable. */
- tz = getenv ("TZ");
+ /* Examine the TZ environment variable. This doesn't really have to be
+ a __secure_getenv() call as __tzfile_read() tries to only read files
+ found under a trusted directory, but this helps reduce the amount of
+ security-critical code. */
+ tz = __secure_getenv ("TZ");
if (tz == NULL && !explicit)
/* Use the site-wide default. This is a file name which means we
would not see changes to the file if we compare only the file