diff options
-rw-r--r-- | ChangeLog | 17 | ||||
-rw-r--r-- | elf/dl-deps.c | 8 | ||||
-rw-r--r-- | elf/dl-load.c | 61 | ||||
-rw-r--r-- | elf/dl-open.c | 2 | ||||
-rw-r--r-- | elf/link.h | 8 | ||||
-rw-r--r-- | elf/rtld.c | 12 | ||||
-rw-r--r-- | math/libm-test.c | 4 | ||||
-rw-r--r-- | sysdeps/libm-ieee754/s_modfl.c | 2 |
8 files changed, 91 insertions, 23 deletions
diff --git a/ChangeLog b/ChangeLog index 805219afbb..fb69047b19 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 27de231dff..c069fab0c8 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 96c1eb6bc6..cc94d7b510 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 d095f5e65d..c97321edf0 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 7f2dc674db..67701a13b7 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 9529b9c14e..2ca1692584 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 8fa473eaf5..ea5716ff81 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 5f2b4b5e2c..ad16ef65ec 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 */ |