aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog17
-rw-r--r--elf/dl-deps.c8
-rw-r--r--elf/dl-load.c61
-rw-r--r--elf/dl-open.c2
-rw-r--r--elf/link.h8
-rw-r--r--elf/rtld.c12
-rw-r--r--math/libm-test.c4
-rw-r--r--sysdeps/libm-ieee754/s_modfl.c2
8 files changed, 91 insertions, 23 deletions
diff --git a/ChangeLog b/ChangeLog
index 805219a..fb69047 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,22 @@
+1998-02-17 17:41 Ulrich Drepper <drepper@cygnus.com>
+
+ * elf/dl-load.c (open_path): Take extra argument PRELOADED.
+ If PRELOADED is nonzero check in case of an SUID application
+ whether the shared object has the SUID bit set.
+ Fix some other problems with handling shared objects in system
+ specific directories.
+ (_dl_map_object): Also take extra parameter and pass it to open_path.
+ * elf/link.h (_dl_map_object): Correct prototype and comment.
+ * elf/rtld.c (dl_main): Call _dl_map_object correctly.
+ * elf/dl-open.c (_dl_open): Likewise.
+ * elf/dl-deps.c (openaux, _dl_map_object_deps): Likewise.
+
+ * sysdeps/libm-ieee754/s_modfl.c: Handle numbers > 1.0 correctly.
+
1998-02-17 Ulrich Drepper <drepper@cygnus.com>
+ * math/libm-test.c (modf_test): Add test for 1.5.
+
* sysdeps/generic/bits/select.h (__FD_ISSET): Compare result with
0 to get always an int.
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
index 27de231..c069fab 100644
--- a/elf/dl-deps.c
+++ b/elf/dl-deps.c
@@ -1,5 +1,5 @@
/* Load the dependencies of a mapped object.
- Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -53,7 +53,7 @@ openaux (void *a)
{
struct openaux_args *args = (struct openaux_args *) a;
- args->aux = _dl_map_object (args->map, args->strtab + args->d->d_un.d_val,
+ args->aux = _dl_map_object (args->map, args->strtab + args->d->d_un.d_val, 0,
(args->map->l_type == lt_executable
? lt_library : args->map->l_type),
args->trace_mode);
@@ -160,7 +160,7 @@ _dl_map_object_deps (struct link_map *map,
{
/* Map in the needed object. */
struct link_map *dep
- = _dl_map_object (l, strtab + d->d_un.d_val,
+ = _dl_map_object (l, strtab + d->d_un.d_val, 0,
l->l_type == lt_executable ? lt_library :
l->l_type, trace_mode);
/* Allocate new entry. */
@@ -216,7 +216,7 @@ _dl_map_object_deps (struct link_map *map,
}
else
/* For filter objects the dependency must be available. */
- args.aux = _dl_map_object (l, strtab + d->d_un.d_val,
+ args.aux = _dl_map_object (l, strtab + d->d_un.d_val, 0,
(l->l_type == lt_executable
? lt_library : l->l_type),
trace_mode);
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 96c1eb6..cc94d7b 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -793,7 +793,7 @@ _dl_map_object_from_fd (char *name, int fd, char *realname,
with the malloc'd full directory name. */
static int
-open_path (const char *name, size_t namelen,
+open_path (const char *name, size_t namelen, int preloaded,
struct r_search_path_elem **dirs,
char **realname)
{
@@ -839,9 +839,31 @@ open_path (const char *name, size_t namelen,
else
this_dir->machdirstatus = existing;
}
+ if (fd != -1 && preloaded && __libc_enable_secure)
+ {
+ /* This is an extra security effort to make sure nobody can
+ preload broken shared objects which are in the trusted
+ directories and so exploit the bugs. */
+ struct stat st;
+
+ if (__fxstat (_STAT_VER, fd, &st) != 0
+ || (st.st_mode & S_ISUID) == 0)
+ {
+ /* The shared object cannot be tested for being SUID
+ or this bit is not set. In this case we must not
+ use this object. */
+ __close (fd);
+ fd = -1;
+ /* We simply ignore the file, signal this by setting
+ the error value which would have been set by `open'. */
+ errno = ENOENT;
+ }
+ }
}
+ else
+ errno = ENOENT;
- if (fd == -1 && this_dir->dirstatus != nonexisting)
+ if (fd == -1 && errno == ENOENT && this_dir->dirstatus != nonexisting)
{
/* Construct the pathname to try. */
buflen = ((char *) __mempcpy (__mempcpy (buf, this_dir->dirname,
@@ -871,12 +893,32 @@ open_path (const char *name, size_t namelen,
else
this_dir->dirstatus = existing;
}
+ if (fd != -1 && preloaded && __libc_enable_secure)
+ {
+ /* This is an extra security effort to make sure nobody can
+ preload broken shared objects which are in the trusted
+ directories and so exploit the bugs. */
+ struct stat st;
+
+ if (__fxstat (_STAT_VER, fd, &st) != 0
+ || (st.st_mode & S_ISUID) == 0)
+ {
+ /* The shared object cannot be tested for being SUID
+ or this bit is not set. In this case we must not
+ use this object. */
+ __close (fd);
+ fd = -1;
+ /* We simply ignore the file, signal this by setting
+ the error value which would have been set by `open'. */
+ errno = ENOENT;
+ }
+ }
}
if (fd != -1)
{
*realname = malloc (buflen);
- if (*realname)
+ if (*realname != NULL)
{
memcpy (*realname, buf, buflen);
return fd;
@@ -901,8 +943,8 @@ open_path (const char *name, size_t namelen,
/* Map in the shared object file NAME. */
struct link_map *
-_dl_map_object (struct link_map *loader, const char *name, int type,
- int trace_mode)
+_dl_map_object (struct link_map *loader, const char *name, int preloaded,
+ int type, int trace_mode)
{
int fd;
char *realname;
@@ -963,7 +1005,8 @@ _dl_map_object (struct link_map *loader, const char *name, int type,
}
if (l->l_rpath_dirs != (struct r_search_path_elem **) -1l)
- fd = open_path (name, namelen, l->l_rpath_dirs, &realname);
+ fd = open_path (name, namelen, preloaded, l->l_rpath_dirs,
+ &realname);
}
/* If dynamically linked, try the DT_RPATH of the executable itself
@@ -971,12 +1014,12 @@ _dl_map_object (struct link_map *loader, const char *name, int type,
l = _dl_loaded;
if (fd == -1 && l && l->l_type != lt_loaded
&& l->l_rpath_dirs != (struct r_search_path_elem **) -1l)
- fd = open_path (name, namelen, l->l_rpath_dirs, &realname);
+ fd = open_path (name, namelen, preloaded, l->l_rpath_dirs, &realname);
/* This is used if a static binary uses dynamic loading and there
is a LD_LIBRARY_PATH given. */
if (fd == -1 && fake_path_list != NULL)
- fd = open_path (name, namelen, fake_path_list, &realname);
+ fd = open_path (name, namelen, preloaded, fake_path_list, &realname);
if (fd == -1)
{
@@ -1001,7 +1044,7 @@ _dl_map_object (struct link_map *loader, const char *name, int type,
/* Finally, try the default path. */
if (fd == -1)
- fd = open_path (name, namelen, rtld_search_dirs, &realname);
+ fd = open_path (name, namelen, preloaded, rtld_search_dirs, &realname);
}
else
{
diff --git a/elf/dl-open.c b/elf/dl-open.c
index d095f5e..c97321e 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -61,7 +61,7 @@ _dl_open (const char *file, int mode)
__libc_lock_lock (_dl_load_lock);
/* Load the named object. */
- new = _dl_map_object (NULL, file, lt_loaded, 0);
+ new = _dl_map_object (NULL, file, 0, lt_loaded, 0);
if (new->l_searchlist)
{
/* It was already open. */
diff --git a/elf/link.h b/elf/link.h
index 7f2dc67..67701a1 100644
--- a/elf/link.h
+++ b/elf/link.h
@@ -296,10 +296,12 @@ extern int _dlerror_run (void (*operate) (void *), void *args);
/* Open the shared object NAME and map in its segments.
LOADER's DT_RPATH is used in searching for NAME.
- If the object is already opened, returns its existing map. */
+ If the object is already opened, returns its existing map.
+ For preloaded shared objects PRELOADED is set to a non-zero
+ value to allow additional security checks. */
extern struct link_map *_dl_map_object (struct link_map *loader,
- const char *name, int type,
- int trace_mode);
+ const char *name, int preloaded,
+ int type, int trace_mode);
/* Call _dl_map_object on the dependencies of MAP, and set up
MAP->l_searchlist. PRELOADS points to a vector of NPRELOADS previously
diff --git a/elf/rtld.c b/elf/rtld.c
index 9529b9c..2ca1692 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -187,7 +187,7 @@ static void
map_doit (void *a)
{
struct map_args *args = (struct map_args *)a;
- args->main_map = _dl_map_object (NULL, args->str, lt_library, 0);
+ args->main_map = _dl_map_object (NULL, args->str, 0, lt_library, 0);
}
static void
@@ -394,7 +394,7 @@ of this helper program; chances are you did not intend to run this program.\n",
}
}
else
- main_map = _dl_map_object (NULL, _dl_argv[0], lt_library, 0);
+ main_map = _dl_map_object (NULL, _dl_argv[0], 0, lt_library, 0);
phdr = main_map->l_phdr;
phent = main_map->l_phnum;
@@ -509,7 +509,8 @@ of this helper program; chances are you did not intend to run this program.\n",
while ((p = strsep (&list, " :")) != NULL)
if (! __libc_enable_secure || strchr (p, '/') == NULL)
{
- struct link_map *new_map = _dl_map_object (NULL, p, lt_library, 0);
+ struct link_map *new_map = _dl_map_object (NULL, p, 1,
+ lt_library, 0);
if (new_map->l_opencount == 1)
/* It is no duplicate. */
++npreloads;
@@ -569,7 +570,7 @@ of this helper program; chances are you did not intend to run this program.\n",
runp = file + strspn (file, ": \t\n");
while ((p = strsep (&runp, ": \t\n")) != NULL)
{
- struct link_map *new_map = _dl_map_object (NULL, p,
+ struct link_map *new_map = _dl_map_object (NULL, p, 1,
lt_library, 0);
if (new_map->l_opencount == 1)
/* It is no duplicate. */
@@ -583,7 +584,8 @@ of this helper program; chances are you did not intend to run this program.\n",
if (problem != NULL)
{
char *p = strndupa (problem, file_size - (problem - file));
- struct link_map *new_map = _dl_map_object (NULL, p, lt_library, 0);
+ struct link_map *new_map = _dl_map_object (NULL, p, 1,
+ lt_library, 0);
if (new_map->l_opencount == 1)
/* It is no duplicate. */
++npreloads;
diff --git a/math/libm-test.c b/math/libm-test.c
index 8fa473e..ea5716f 100644
--- a/math/libm-test.c
+++ b/math/libm-test.c
@@ -1703,6 +1703,10 @@ modf_test (void)
check ("modf (-0, &x) returns -0", result, minus_zero);
check ("modf (-0, &x) sets x to -0", intpart, minus_zero);
+ result = FUNC(modf) (1.5, &intpart);
+ check ("modf (1.5, &x) returns 0.5", result, 0.5);
+ check ("modf (1.5, &x) sets x to 1", intpart, 1);
+
result = FUNC(modf) (2.5, &intpart);
check ("modf (2.5, &x) returns 0.5", result, 0.5);
check ("modf (2.5, &x) sets x to 2", intpart, 2);
diff --git a/sysdeps/libm-ieee754/s_modfl.c b/sysdeps/libm-ieee754/s_modfl.c
index 5f2b4b5..ad16ef6 100644
--- a/sysdeps/libm-ieee754/s_modfl.c
+++ b/sysdeps/libm-ieee754/s_modfl.c
@@ -71,7 +71,7 @@ static long double one = 1.0;
SET_LDOUBLE_WORDS(x,se&0x8000,0,0); /* return +-0 */
return x;
} else { /* fraction part in low x */
- i = ((u_int32_t)(0x7fffffff))>>(j0-32);
+ i = ((u_int32_t)(0xffffffff))>>(j0-32);
if((i1&i)==0) { /* x is integral */
*iptr = x;
INSERT_WORDS(x,se&0x8000,0); /* return +-0 */