[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]
Re: [linux-security] Beware of dangerous enviroment (Re: Overflows in minicom)
- From: Pavel Kankovsky <peak kerberos troja mff cuni cz>
- To: Torkil Zachariassen <torkil als fo>
- Cc: linux-security redhat com, hjl gnu org
- Subject: Re: [linux-security] Beware of dangerous enviroment (Re: Overflows in minicom)
- Date: Tue, 26 May 1998 14:42:28 +0200 (MET DST)
On Sat, 23 May 1998, Torkil Zachariassen wrote:
> >I have browsed various versions of libc and found a handful of weak points
> >where the value of an enviroment variable is trusted more than necessary.
>
[1]
> Could you explain to programming novices on linux-security - people like
> myself 8) - hwo this could affect security on a firewall (proxy and/or
> IP-router, with/without othert services like a webserver, lpd and alike)
> running Linux (of course)?
[2]
> And what could proper precautions be and how could we monitor this part
> of the security?
[To the moderator: I have no idea whether all this stuff belongs to the
list. It is up to you to decide. :) ]
ad [1]
This means if the attacker could make some privileged (*) program execute
with any of those (**) variables set to certain values, the program would
be coaxed to read (or write) any file on the system if it uses any
affected libc subsystem.
How does it affect your firewall? First of all, it is quite unlikely the
bug is remotely exploitable (but it is certainly possible: for instance,
the telnet protocol allows the client to set arbitrary enviroment
variables, and some old versions of telnetd honored the settings
carelessly). Second, the bugs (save from LD_PROFILE_OUTPUT which is much
more dangerous) can be abused to crash the system (read /dev/flaky_device),
annihilate kernel messages (read /dev/kmsg), or corrupt open data streams
(read /proc/1234/fd/0), one can hardly steal data or modify them in any
predictible way.
ad [2]:
The proper precaution is to fix libc, of course. Ulrich Drepper posted a
fix for glibc2.[01], I myself have made a rather simpleminded (thus overly
paranoid) fix for libc 5.4.44 recently. I am enclosing it. (***)
Hmmm... perhaps the even more proper precaution would be to separate
"vital" (syscalls, string routines) and "user convenience" (NLS, time
conversion) parts of libc, undertake an exhaustive audit of the "vital"
part (the whole libc is too huge), and avoid linking privileged programs
with anything but the audited library. Unfortunately, many programs would
have to be split into an unprivileged "front-end" and a privileged
"back-end".
How to monitor? This a hard question. An attempt to abuse such a hole
could probably be detected if you audited enviroment variable settings of
security sensitive programs, and unusual directory lookups crossing ".."
entries. AFAIK, syscall auditing is a part of Linux-privs project and is
going to be merged into 2.3.
--Pavel Kankovsky aka Peak [ Boycott Microsoft--http://www.vcnet.com/bms ]
(*) for a non-user, any program is privileged
(**) the actual meaning of "those" depends on the version of libc
(***) voila, I patched more getenv()s than I reported in my post:
MALLOC_*, NIS_*; I have to admit I do know whether I did it because
I found they were harmful or because I was too lazy to verify they
were safe...
<<<patch for 5.4.44>>>
--- libc-5.4.44/libc/dl-malloc/malloc.c.secenv Sun Nov 2 03:48:44 1997
+++ libc-5.4.44/libc/dl-malloc/malloc.c Sat May 16 15:28:14 1998
@@ -257,6 +257,8 @@
#include <stdio.h> /* needed for malloc_stats */
+extern char *__libc_secure_getenv(const char *);
+
/*
Compile-time options
@@ -3365,15 +3367,15 @@
if(__libc_malloc_initialized) return;
__libc_malloc_initialized = 1;
- if((s = getenv("MALLOC_TRIM_THRESHOLD_")))
+ if((s = __libc_secure_getenv("MALLOC_TRIM_THRESHOLD_")))
mALLOPt(M_TRIM_THRESHOLD, atoi(s));
- if((s = getenv("MALLOC_TOP_PAD_")))
+ if((s = __libc_secure_getenv("MALLOC_TOP_PAD_")))
mALLOPt(M_TOP_PAD, atoi(s));
- if((s = getenv("MALLOC_MMAP_THRESHOLD_")))
+ if((s = __libc_secure_getenv("MALLOC_MMAP_THRESHOLD_")))
mALLOPt(M_MMAP_THRESHOLD, atoi(s));
- if((s = getenv("MALLOC_MMAP_MAX_")))
+ if((s = __libc_secure_getenv("MALLOC_MMAP_MAX_")))
mALLOPt(M_MMAP_MAX, atoi(s));
- s = getenv("MALLOC_CHECK_");
+ s = __libc_secure_getenv("MALLOC_CHECK_");
if(s) {
if(s[0]) mALLOPt(M_CHECK_ACTION, (int)(s[0] - '0'));
__malloc_check_init();
--- libc-5.4.44/libc/locale/findlocale.c.secenv Sat Oct 5 00:53:01 1996
+++ libc-5.4.44/libc/locale/findlocale.c Sat May 16 15:32:10 1998
@@ -35,6 +35,8 @@
const struct locale_data *_nl_find_locale (const char *, size_t,
int, char **);
+extern char *__libc_secure_getenv(const char *);
+
static inline char *
copy (const char *string)
@@ -73,11 +75,11 @@
{
/* The user decides which locale to use by setting environment
variables. */
- *name = getenv ("LC_ALL");
+ *name = __libc_secure_getenv ("LC_ALL");
if (*name == NULL || (*name)[0] == '\0')
- *name = getenv (_nl_category_names[category]);
+ *name = __libc_secure_getenv (_nl_category_names[category]);
if (*name == NULL || (*name)[0] == '\0')
- *name = getenv ("LANG");
+ *name = __libc_secure_getenv ("LANG");
if (*name == NULL || (*name)[0] == '\0')
*name = (char *) _nl_C_name;
}
--- libc-5.4.44/libc/nls/msgcat.c.secenv Thu Aug 28 04:59:19 1997
+++ libc-5.4.44/libc/nls/msgcat.c Sat May 16 16:45:42 1998
@@ -124,6 +124,8 @@
#include <sys/mman.h>
#endif
+extern char *__libc_secure_getenv(const char *);
+
nl_catd
catopen( const char *name, int type )
{
@@ -141,13 +143,13 @@
if (stat(catpath, &sbuf)) return(NLERR);
} else {
#if BROKEN_SETLOCALE
- if ((lang = (char *) getenv ("LANG")) == NULL) lang = "C";
+ if ((lang = (char *) __libc_secure_getenv ("LANG")) == NULL) lang = "C";
#else
/* Query the locale from the previous setlocale call in msgcat-libc.c*/
if ((lang = (char *) setlocale(LC_MESSAGES,(char *) NULL)) == NULL)
lang="C";
#endif
- if ((nlspath = (char *) getenv ("NLSPATH")) == NULL) {
+ if ((nlspath = (char *) __libc_secure_getenv ("NLSPATH")) == NULL) {
#if OLD_NLS_PATHS
nlspath = "/nlslib/%L/%N.cat:/nlslib/%N/%L";
#else
@@ -187,6 +189,7 @@
++nlspath;
strcpy(pathP, lang);
pathP = tmp;
+ continue;
} else if (*(nlspath + 1) == 'N') {
char * tmp = pathP + strlen(name);
if (tmp > path + sizeof (path))
@@ -197,15 +200,14 @@
++nlspath;
strcpy(pathP, name);
pathP = tmp;
- } else *(pathP++) = *nlspath;
- } else
- {
- if (pathP >= path + sizeof (path))
- {
- goto error;
+ continue;
}
- *(pathP++) = *nlspath;
}
+ if (pathP >= path + sizeof (path))
+ {
+ goto error;
+ }
+ *(pathP++) = *nlspath;
}
*pathP = '\0';
if (stat(path, &sbuf) == 0 && S_ISREG (sbuf.st_mode)) {
--- libc-5.4.44/libc/nys/nis/src/nis_names.c.secenv Mon Oct 21 06:40:17 1996
+++ libc-5.4.44/libc/nys/nis/src/nis_names.c Sat May 16 15:46:52 1998
@@ -29,6 +29,8 @@
#include "nis_conf.h"
#include "xalloc.h"
+extern char *__libc_secure_getenv(const char *);
+
nis_name nis_local_directory(void)
{
@@ -152,7 +154,7 @@
static char default_group[NIS_MAXNAMELEN];
char *cptr;
- if ((cptr=getenv("NIS_GROUP"))==NULL)
+ if ((cptr=__libc_secure_getenv("NIS_GROUP"))==NULL)
return "";
if (strlen(cptr) >= sizeof(default_group))
@@ -317,7 +319,7 @@
return rnames;
}
- path = getenv("NIS_PATH");
+ path = __libc_secure_getenv("NIS_PATH");
if (path == NULL)
path = "$";
--- libc-5.4.44/libc/time/bsdtime.c.secenv Mon Oct 21 06:40:22 1996
+++ libc-5.4.44/libc/time/bsdtime.c Sat May 16 17:02:38 1998
@@ -1015,6 +1015,8 @@
(void) tzparse(GMT, sp, TRUE);
}
+extern char *__libc_secure_getenv(const char *);
+
#ifdef __STDC__
void
tzset(void)
@@ -1026,7 +1028,7 @@
register const char * name;
void tzsetwall(void);
- name = getenv("TZ");
+ name = __libc_secure_getenv("TZ");
if (name == NULL) {
tzsetwall();
return;
<<<end of the patch>>>
[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]