From c944b8437af4bb683ee28d99a64f48dd850c0a4e8522db7090afc3e5bb646675 Mon Sep 17 00:00:00 2001 From: Petr Baudis Date: Mon, 1 Nov 2010 22:13:24 +0000 Subject: [PATCH] - Fix missing hconf setup in nscd - this meant `multi on` in /etc/host.conf was ignored when nscd was used, breaking e.g. resolving of multi-AF records in /etc/hosts [bnc#572188] - Fix two LD_AUDIT security vulnerabilities: spurious $ORIGIN expansion and missing setuid library check when running as setuid [bnc#646960] OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=42 --- glibc-2.11.3-audit.diff | 274 ++++++++++++++++++++++++++++++++++++++++ glibc-make-3.82.patch | 91 +++++++++++++ glibc-nscd-hconf.diff | 35 +++++ glibc.changes | 20 +++ glibc.spec | 15 ++- ready | 0 6 files changed, 433 insertions(+), 2 deletions(-) create mode 100644 glibc-2.11.3-audit.diff create mode 100644 glibc-make-3.82.patch create mode 100644 glibc-nscd-hconf.diff create mode 100644 ready diff --git a/glibc-2.11.3-audit.diff b/glibc-2.11.3-audit.diff new file mode 100644 index 0000000..ccb3bb9 --- /dev/null +++ b/glibc-2.11.3-audit.diff @@ -0,0 +1,274 @@ +commit 22cd1c9bcf57c5829d65b6da825f7a459d40c9eb +Author: Andreas Schwab +Date: Sun Oct 24 20:40:14 2010 -0400 + + Don't expand DST twice in dl_open + +2010-10-18 Andreas Schwab + + * elf/dl-open.c (dl_open_worker): Don't expand DST here, let + _dl_map_object do it. + +diff --git a/elf/dl-open.c b/elf/dl-open.c +index 754a263..c394b3f 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -221,35 +221,6 @@ dl_open_worker (void *a) + + assert (_dl_debug_initialize (0, args->nsid)->r_state == RT_CONSISTENT); + +- /* Maybe we have to expand a DST. */ +- if (__builtin_expect (dst != NULL, 0)) +- { +- size_t len = strlen (file); +- +- /* Determine how much space we need. We have to allocate the +- memory locally. */ +- size_t required = DL_DST_REQUIRED (call_map, file, len, +- _dl_dst_count (dst, 0)); +- +- /* Get space for the new file name. */ +- char *new_file = (char *) alloca (required + 1); +- +- /* Generate the new file name. */ +- _dl_dst_substitute (call_map, file, new_file, 0); +- +- /* If the substitution failed don't try to load. */ +- if (*new_file == '\0') +- _dl_signal_error (0, "dlopen", NULL, +- N_("empty dynamic string token substitution")); +- +- /* Now we have a new file name. */ +- file = new_file; +- +- /* It does not matter whether call_map is set even if we +- computed it only because of the DST. Since the path contains +- a slash the value is not used. See dl-load.c. */ +- } +- + /* Load the named object. */ + struct link_map *new; + args->map = new = _dl_map_object (call_map, file, 0, lt_loaded, 0, + + +commit 8e9f92e9d5d7737afdacf79b76d98c4c42980508 +Author: Andreas Schwab +Date: Sun Oct 24 21:43:15 2010 -0400 + + Require suid bit on audit objects in privileged programs + +2010-10-22 Andreas Schwab + + * include/dlfcn.h (__RTLD_SECURE): Define. + * elf/dl-load.c (_dl_map_object): Remove preloaded parameter. Use + mode & __RTLD_SECURE instead. + (open_path): Rename preloaded parameter to secure. + * sysdeps/generic/ldsodefs.h (_dl_map_object): Adjust declaration. + * elf/dl-open.c (dl_open_worker): Adjust call to _dl_map_object. + * elf/dl-deps.c (openaux): Likewise. + * elf/rtld.c (struct map_args): Remove is_preloaded. + (map_doit): Don't use it. + (dl_main): Likewise. + (do_preload): Use __RTLD_SECURE instead of is_preloaded. + (dlmopen_doit): Add __RTLD_SECURE to mode bits. + +diff --git a/elf/dl-deps.c b/elf/dl-deps.c +index a58de5c..a51fb6e 100644 +--- a/elf/dl-deps.c ++++ b/elf/dl-deps.c +@@ -62,7 +62,7 @@ openaux (void *a) + { + struct openaux_args *args = (struct openaux_args *) a; + +- args->aux = _dl_map_object (args->map, args->name, 0, ++ args->aux = _dl_map_object (args->map, args->name, + (args->map->l_type == lt_executable + ? lt_library : args->map->l_type), + args->trace_mode, args->open_mode, +diff --git a/elf/dl-load.c b/elf/dl-load.c +index a7162eb..aa8738f 100644 +--- a/elf/dl-load.c ++++ b/elf/dl-load.c +@@ -1812,7 +1812,7 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader, + if MAY_FREE_DIRS is true. */ + + static int +-open_path (const char *name, size_t namelen, int preloaded, ++open_path (const char *name, size_t namelen, int secure, + struct r_search_path_struct *sps, char **realname, + struct filebuf *fbp, struct link_map *loader, int whatcode, + bool *found_other_class) +@@ -1894,7 +1894,7 @@ open_path (const char *name, size_t namelen, int preloaded, + /* Remember whether we found any existing directory. */ + here_any |= this_dir->status[cnt] != nonexisting; + +- if (fd != -1 && __builtin_expect (preloaded, 0) ++ if (fd != -1 && __builtin_expect (secure, 0) + && INTUSE(__libc_enable_secure)) + { + /* This is an extra security effort to make sure nobody can +@@ -1963,7 +1963,7 @@ open_path (const char *name, size_t namelen, int preloaded, + + struct link_map * + internal_function +-_dl_map_object (struct link_map *loader, const char *name, int preloaded, ++_dl_map_object (struct link_map *loader, const char *name, + int type, int trace_mode, int mode, Lmid_t nsid) + { + int fd; +@@ -2067,7 +2067,8 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, + for (l = loader; l; l = l->l_loader) + if (cache_rpath (l, &l->l_rpath_dirs, DT_RPATH, "RPATH")) + { +- fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs, ++ fd = open_path (name, namelen, mode & __RTLD_SECURE, ++ &l->l_rpath_dirs, + &realname, &fb, loader, LA_SER_RUNPATH, + &found_other_class); + if (fd != -1) +@@ -2082,14 +2083,15 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, + && main_map != NULL && main_map->l_type != lt_loaded + && cache_rpath (main_map, &main_map->l_rpath_dirs, DT_RPATH, + "RPATH")) +- fd = open_path (name, namelen, preloaded, &main_map->l_rpath_dirs, ++ fd = open_path (name, namelen, mode & __RTLD_SECURE, ++ &main_map->l_rpath_dirs, + &realname, &fb, loader ?: main_map, LA_SER_RUNPATH, + &found_other_class); + } + + /* Try the LD_LIBRARY_PATH environment variable. */ + if (fd == -1 && env_path_list.dirs != (void *) -1) +- fd = open_path (name, namelen, preloaded, &env_path_list, ++ fd = open_path (name, namelen, mode & __RTLD_SECURE, &env_path_list, + &realname, &fb, + loader ?: GL(dl_ns)[LM_ID_BASE]._ns_loaded, + LA_SER_LIBPATH, &found_other_class); +@@ -2098,12 +2100,12 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, + if (fd == -1 && loader != NULL + && cache_rpath (loader, &loader->l_runpath_dirs, + DT_RUNPATH, "RUNPATH")) +- fd = open_path (name, namelen, preloaded, ++ fd = open_path (name, namelen, mode & __RTLD_SECURE, + &loader->l_runpath_dirs, &realname, &fb, loader, + LA_SER_RUNPATH, &found_other_class); + + if (fd == -1 +- && (__builtin_expect (! preloaded, 1) ++ && (__builtin_expect (! (mode & __RTLD_SECURE), 1) + || ! INTUSE(__libc_enable_secure))) + { + /* Check the list of libraries in the file /etc/ld.so.cache, +@@ -2169,7 +2171,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, + && ((l = loader ?: GL(dl_ns)[nsid]._ns_loaded) == NULL + || __builtin_expect (!(l->l_flags_1 & DF_1_NODEFLIB), 1)) + && rtld_search_dirs.dirs != (void *) -1) +- fd = open_path (name, namelen, preloaded, &rtld_search_dirs, ++ fd = open_path (name, namelen, mode & __RTLD_SECURE, &rtld_search_dirs, + &realname, &fb, l, LA_SER_DEFAULT, &found_other_class); + + /* Add another newline when we are tracing the library loading. */ +diff --git a/elf/dl-open.c b/elf/dl-open.c +index c394b3f..cf8e8cc 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -223,7 +223,7 @@ dl_open_worker (void *a) + + /* Load the named object. */ + struct link_map *new; +- args->map = new = _dl_map_object (call_map, file, 0, lt_loaded, 0, ++ args->map = new = _dl_map_object (call_map, file, lt_loaded, 0, + mode | __RTLD_CALLMAP, args->nsid); + + /* If the pointer returned is NULL this means the RTLD_NOLOAD flag is +diff --git a/elf/rtld.c b/elf/rtld.c +index 5ecc4fe..06b534a 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -589,7 +589,6 @@ struct map_args + /* Argument to map_doit. */ + char *str; + struct link_map *loader; +- int is_preloaded; + int mode; + /* Return value of map_doit. */ + struct link_map *map; +@@ -627,16 +626,17 @@ static void + map_doit (void *a) + { + struct map_args *args = (struct map_args *) a; +- args->map = _dl_map_object (args->loader, args->str, +- args->is_preloaded, lt_library, 0, args->mode, +- LM_ID_BASE); ++ args->map = _dl_map_object (args->loader, args->str, lt_library, 0, ++ args->mode, LM_ID_BASE); + } + + static void + dlmopen_doit (void *a) + { + struct dlmopen_args *args = (struct dlmopen_args *) a; +- args->map = _dl_open (args->fname, RTLD_LAZY | __RTLD_DLOPEN | __RTLD_AUDIT, ++ args->map = _dl_open (args->fname, ++ (RTLD_LAZY | __RTLD_DLOPEN | __RTLD_AUDIT ++ | __RTLD_SECURE), + dl_main, LM_ID_NEWLM, _dl_argc, INTUSE(_dl_argv), + __environ); + } +@@ -806,8 +806,7 @@ do_preload (char *fname, struct link_map *main_map, const char *where) + + args.str = fname; + args.loader = main_map; +- args.is_preloaded = 1; +- args.mode = 0; ++ args.mode = __RTLD_SECURE; + + unsigned int old_nloaded = GL(dl_ns)[LM_ID_BASE]._ns_nloaded; + +@@ -1054,7 +1053,6 @@ of this helper program; chances are you did not intend to run this program.\n\ + + args.str = rtld_progname; + args.loader = NULL; +- args.is_preloaded = 0; + args.mode = __RTLD_OPENEXEC; + (void) _dl_catch_error (&objname, &err_str, &malloced, map_doit, + &args); +@@ -1066,7 +1064,7 @@ of this helper program; chances are you did not intend to run this program.\n\ + else + { + HP_TIMING_NOW (start); +- _dl_map_object (NULL, rtld_progname, 0, lt_library, 0, ++ _dl_map_object (NULL, rtld_progname, lt_library, 0, + __RTLD_OPENEXEC, LM_ID_BASE); + HP_TIMING_NOW (stop); + +diff --git a/include/dlfcn.h b/include/dlfcn.h +index a67426d..af92483 100644 +--- a/include/dlfcn.h ++++ b/include/dlfcn.h +@@ -9,6 +9,7 @@ + #define __RTLD_OPENEXEC 0x20000000 + #define __RTLD_CALLMAP 0x10000000 + #define __RTLD_AUDIT 0x08000000 ++#define __RTLD_SECURE 0x04000000 /* Apply additional security checks. */ + + #define __LM_ID_CALLER -2 + +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index fcc943b..fa4b6b2 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -824,11 +824,9 @@ extern void _dl_receive_error (receiver_fct fct, void (*operate) (void *), + + /* 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. +- For preloaded shared objects PRELOADED is set to a non-zero +- value to allow additional security checks. */ ++ If the object is already opened, returns its existing map. */ + extern struct link_map *_dl_map_object (struct link_map *loader, +- const char *name, int preloaded, ++ const char *name, + int type, int trace_mode, int mode, + Lmid_t nsid) + internal_function attribute_hidden; diff --git a/glibc-make-3.82.patch b/glibc-make-3.82.patch new file mode 100644 index 0000000..702c044 --- /dev/null +++ b/glibc-make-3.82.patch @@ -0,0 +1,91 @@ +From: Andreas Schwab +To: libc-hacker at sourceware dot org +Subject: [PATCH] Work around shortest-stem feature in make 3.82+ + +make 3.82+ no longer selects pattern rules by order, but by shortest +stem, so we need to add more rules to make sure we still get the right +matches. + +Andreas. + +2010-09-09 Andreas Schwab + + * Makeconfig (sysd-rules-patterns): Add rtld-%:rtld-%. + (sysd-rules-targets): Remove duplicates. + * elf/rtld-Rules ($(objpfx)rtld-%.os): Add pattern rules with + rtld-%.$o dependency. + +2010-09-06 Andreas Schwab + + * manual/Makefile: Don't mix pattern rules with normal rules. + +diff --git a/Makeconfig b/Makeconfig +index 9778998..807c1d1 100644 +--- a/Makeconfig ++++ b/Makeconfig +@@ -966,7 +966,7 @@ endif + # emitted into sysd-rules. A sysdeps Makeconfig fragment can + # add its own special object file prefix to this list with e.g. foo-%:% + # to have foo-*.? compiled from *.? using $(foo-CPPFLAGS). +-sysd-rules-patterns := %:% rtld-%:% m_%:s_% ++sysd-rules-patterns := %:% rtld-%:rtld-% rtld-%:% m_%:s_% + + # Let sysdeps/ subdirs contain a Makeconfig fragment for us to include here. + sysdep-makeconfigs := $(wildcard $(+sysdep_dirs:=/Makeconfig)) +@@ -975,8 +975,8 @@ include $(sysdep-makeconfigs) + endif + + # Compute just the target patterns. Makeconfig has set sysd-rules-patterns. +-sysd-rules-targets := $(foreach p,$(sysd-rules-patterns),\ +- $(firstword $(subst :, ,$p))) ++sysd-rules-targets := $(sort $(foreach p,$(sysd-rules-patterns),\ ++ $(firstword $(subst :, ,$p)))) + + endif # Makeconfig not yet included + +diff --git a/elf/rtld-Rules b/elf/rtld-Rules +index 9f31a56..fc225f2 100644 +--- a/elf/rtld-Rules ++++ b/elf/rtld-Rules +@@ -93,6 +93,12 @@ else + # These are the basic compilation rules corresponding to the Makerules ones. + # The sysd-rules generated makefile already defines pattern rules for rtld-% + # targets built from sysdeps source files. ++$(objpfx)rtld-%.os: rtld-%.S $(before-compile) ++ $(compile-command.S) $(rtld-CPPFLAGS) ++$(objpfx)rtld-%.os: rtld-%.s $(before-compile) ++ $(compile-command.s) $(rtld-CPPFLAGS) ++$(objpfx)rtld-%.os: rtld-%.c $(before-compile) ++ $(compile-command.c) $(rtld-CPPFLAGS) + $(objpfx)rtld-%.os: %.S $(before-compile) + $(compile-command.S) $(rtld-CPPFLAGS) + $(objpfx)rtld-%.os: %.s $(before-compile) +@@ -101,6 +107,9 @@ $(objpfx)rtld-%.os: %.c $(before-compile) + $(compile-command.c) $(rtld-CPPFLAGS) + + # The rules for generated source files. ++$(objpfx)rtld-%.os: $(objpfx)rtld-%.S $(before-compile); $(compile-command.S) ++$(objpfx)rtld-%.os: $(objpfx)rtld-%.s $(before-compile); $(compile-command.s) ++$(objpfx)rtld-%.os: $(objpfx)rtld-%.c $(before-compile); $(compile-command.c) + $(objpfx)rtld-%.os: $(objpfx)%.S $(before-compile); $(compile-command.S) + $(objpfx)rtld-%.os: $(objpfx)%.s $(before-compile); $(compile-command.s) + $(objpfx)rtld-%.os: $(objpfx)%.c $(before-compile); $(compile-command.c) +-- +1.7.2.2 + +diff --git a/manual/Makefile b/manual/Makefile +index c5866eb..b1f5fa7 100644 +--- a/manual/Makefile ++++ b/manual/Makefile +@@ -232,7 +232,10 @@ ifdef objpfx + .PHONY: stubs + stubs: $(objpfx)stubs + endif +-$(objpfx)stubs ../po/manual.pot $(objpfx)stamp%: ++$(objpfx)stubs ../po/manual.pot: ++ $(make-target-directory) ++ touch $@ ++$(objpfx)stamp%: + $(make-target-directory) + touch $@ + diff --git a/glibc-nscd-hconf.diff b/glibc-nscd-hconf.diff new file mode 100644 index 0000000..f933559 --- /dev/null +++ b/glibc-nscd-hconf.diff @@ -0,0 +1,35 @@ +diff --git a/nscd/aicache.c b/nscd/aicache.c +index 3cb2208..2e92929 100644 +--- a/nscd/aicache.c ++++ b/nscd/aicache.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + #include "dbg_log.h" + #include "nscd.h" +@@ -103,6 +104,8 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req, + + if (__res_maybe_init (&_res, 0) == -1) + no_more = 1; ++ if (!_res_hconf.initialized) ++ _res_hconf_init (); + + /* If we are looking for both IPv4 and IPv6 address we don't want + the lookup functions to automatically promote IPv4 addresses to +diff --git a/resolv/res_hconf.c b/resolv/res_hconf.c +index ed55bec..c79b85a 100644 +--- a/resolv/res_hconf.c ++++ b/resolv/res_hconf.c +@@ -84,7 +84,9 @@ static const struct cmd + }; + + /* Structure containing the state. */ ++#ifndef NOT_IN_libc + struct hconf _res_hconf; ++#endif + + /* Skip white space. */ + static const char * diff --git a/glibc.changes b/glibc.changes index 89c01c0..4ee76c2 100644 --- a/glibc.changes +++ b/glibc.changes @@ -1,3 +1,23 @@ +------------------------------------------------------------------- +Wed Oct 27 03:14:37 CEST 2010 - pbaudis@suse.cz + +- Fix missing hconf setup in nscd - this meant `multi on` in + /etc/host.conf was ignored when nscd was used, breaking e.g. + resolving of multi-AF records in /etc/hosts [bnc#572188] +- Fix two LD_AUDIT security vulnerabilities: spurious $ORIGIN expansion + and missing setuid library check when running as setuid [bnc#646960] + +------------------------------------------------------------------- +Mon Sep 13 14:36:26 UTC 2010 - aj@suse.de + +- Fix build in manual with make 3.82. + +------------------------------------------------------------------- +Sun Sep 12 08:00:57 UTC 2010 - aj@suse.de + +- Work around shortest-stem feature in make 3.82+ (patch + glibc-make-3.82.patch) + ------------------------------------------------------------------- Wed Jul 7 04:12:05 CEST 2010 - pbaudis@suse.cz diff --git a/glibc.spec b/glibc.spec index a50ed77..8be9a44 100644 --- a/glibc.spec +++ b/glibc.spec @@ -138,6 +138,9 @@ Patch64: glibc-gai-private4.diff Patch65: glibc-resolv-mdnshint.diff Patch66: glibc-ldconfigr-aux.diff Patch67: glibc-nis-initgroups.diff +Patch68: glibc-make-3.82.patch +Patch69: glibc-nscd-hconf.diff +Patch70: glibc-2.11.3-audit.diff Patch500: ARM_glibc-2.10.1-local-eabi-wchar.diff Patch501: ARM_glibc-2.10.1-local-hwcap-updates.diff Patch502: ARM_glibc-2.10.1-local-lowlevellock.diff @@ -361,6 +364,9 @@ rm nscd/s-stamp %patch65 -p1 %patch66 -p1 %patch67 -p1 +%patch68 -p1 +%patch69 -p1 +%patch70 -p1 %ifarch %arm armv5tel armv7l %patch500 %patch501 @@ -388,12 +394,12 @@ rm nscd/s-stamp rm -fv sysdeps/powerpc/powerpc32/power4/hp-timing.c sysdeps/powerpc/powerpc32/power4/hp-timing.h find . -name configure | xargs touch + ####################################################################### ### ### BUILD ### ####################################################################### - %build if [ -x /bin/uname.bin ]; then /bin/uname.bin -a @@ -555,6 +561,7 @@ $BuildCC -static -Os -g $RPM_SOURCE_DIR/glibc_post_upgrade.c -o glibc_post_upgra %endif '-DLIBDIR="/%{_lib}"' '-DGCONV_MODULES_DIR="%{_prefix}/%{_lib}/gconv"' + ####################################################################### ### ### CHECK @@ -577,6 +584,7 @@ $BuildCC -static -Os -g $RPM_SOURCE_DIR/glibc_post_upgrade.c -o glibc_post_upgra %endif make -C cc-base check-abi || echo check-abi failed + ####################################################################### ### ### INSTALL @@ -669,6 +677,7 @@ cp -av bits/stdio-lock.h $RPM_BUILD_ROOT%{_prefix}/include/bits/stdio-lock.h ln -sf ../%{_lib}/ld-%{version}.so $RPM_BUILD_ROOT/lib/ld64.so.1 %endif + # Miscelanna: install -m 0700 glibc_post_upgrade $RPM_BUILD_ROOT%{_sbindir} @@ -689,6 +698,7 @@ cp -p manual/libc/*.html $RPM_BUILD_ROOT/usr/share/doc/glibc cd manpages; make install_root=$RPM_BUILD_ROOT install; cd .. + # nscd tools: cp nscd/nscd.conf $RPM_BUILD_ROOT/etc @@ -762,6 +772,7 @@ for o in $RPM_BUILD_ROOT/%{_libdir}/crt[1in].o $RPM_BUILD_ROOT/%{_libdir}/lib*_n objcopy -R ".comment.SUSE.OPTs" -R ".note.gnu.build-id" $o done + ####################################################################### ### ### ... @@ -799,6 +810,7 @@ done %insserv_cleanup exit 0 + ####################################################################### ### ### FILES @@ -806,7 +818,6 @@ exit 0 ####################################################################### # glibc - %files %defattr(-,root,root) %doc LICENSES diff --git a/ready b/ready new file mode 100644 index 0000000..473a0f4