Accepting request 877767 from home:Andreas_Schwab:Factory

- nss-database-check-reload.patch: nsswitch: return result when nss
  database is locked (BZ #27343)
- nss-load-chroot.patch: nss: Re-enable NSS module loading after chroot
  (bsc#1182323, BZ #27389)
- x86-isa-level.patch: x86: Set minimum x86-64 level marker (bsc#1182522,
  BZ #27318)
- nss-database-lookup.patch: nss: fix nss_database_lookup2's alternate
  handling (bsc#1182247, BZ #27416)
- nss-revert-api.patch: remove
- nscd-netgroupcache.patch: nscd: Fix double free in netgroupcache
  (CVE-2021-27645, bsc#1182733, BZ #27462)

OBS-URL: https://build.opensuse.org/request/show/877767
OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=585
This commit is contained in:
Andreas Schwab 2021-03-08 15:03:02 +00:00 committed by Git OBS Bridge
parent b855cdeb01
commit 47a70fb50a
9 changed files with 1334 additions and 4641 deletions

View File

@ -1,15 +1,13 @@
Index: glibc-2.33/nss/nsswitch.c
Index: glibc-2.33/nss/nss_database.c
===================================================================
--- glibc-2.33.orig/nss/nsswitch.c
+++ glibc-2.33/nss/nsswitch.c
@@ -126,6 +126,10 @@ __nss_database_lookup2 (const char *data
/* Read config file. */
service_table = nss_parse_file (_PATH_NSSWITCH_CONF);
+ /* Retry with the OS vendor provided config file. */
+ if (service_table == NULL)
+ service_table = nss_parse_file ("/usr" _PATH_NSSWITCH_CONF);
+
/* Test whether configuration data is available. */
if (service_table != NULL)
{
--- glibc-2.33.orig/nss/nss_database.c
+++ glibc-2.33/nss/nss_database.c
@@ -303,6 +303,8 @@ nss_database_reload (struct nss_database
{
FILE *fp = fopen (_PATH_NSSWITCH_CONF, "rce");
if (fp == NULL)
+ fp = fopen ("/usr" _PATH_NSSWITCH_CONF, "rce");
+ if (fp == NULL)
switch (errno)
{
case EACCES:

View File

@ -1,3 +1,18 @@
-------------------------------------------------------------------
Mon Mar 8 10:43:30 UTC 2021 - Andreas Schwab <schwab@suse.de>
- nss-database-check-reload.patch: nsswitch: return result when nss
database is locked (BZ #27343)
- nss-load-chroot.patch: nss: Re-enable NSS module loading after chroot
(bsc#1182323, BZ #27389)
- x86-isa-level.patch: x86: Set minimum x86-64 level marker (bsc#1182522,
BZ #27318)
- nss-database-lookup.patch: nss: fix nss_database_lookup2's alternate
handling (bsc#1182247, BZ #27416)
- nss-revert-api.patch: remove
- nscd-netgroupcache.patch: nscd: Fix double free in netgroupcache
(CVE-2021-27645, bsc#1182733, BZ #27462)
-------------------------------------------------------------------
Tue Mar 2 11:57:15 UTC 2021 - Andreas Schwab <schwab@suse.de>

View File

@ -90,9 +90,6 @@ BuildRequires: zlib-devel
ExclusiveArch: i586 i686
BuildArch: i686
%endif
%if %{with usrmerged} && %{build_main}
Provides: /sbin/ldconfig
%endif
%define __filter_GLIBC_PRIVATE 1
%ifarch i686
@ -183,6 +180,9 @@ Provides: ld-linux.so.3(GLIBC_2.4)
Requires(pre): filesystem
Recommends: glibc-extra
Provides: rtld(GNU_HASH)
%if %{with usrmerged}
Provides: /sbin/ldconfig
%endif
%endif
%if %{build_utils}
Requires: glibc = %{version}
@ -200,8 +200,6 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-build
###
# Patches that upstream will not accept
###
# PATCH-FIX-OPENSUSE Work around for nss-compat brokeness
Patch1: nss-revert-api.patch
###
# openSUSE specific patches - won't go upstream
@ -247,6 +245,14 @@ Patch306: glibc-fix-double-loopback.diff
###
# Patches from upstream
###
# PATCH-FIX-UPSTREAM nsswitch: return result when nss database is locked (BZ #27343)
Patch1000: nss-database-check-reload.patch
# PATCH-FIX-UPSTREAM nss: Re-enable NSS module loading after chroot (BZ #27389)
Patch1001: nss-load-chroot.patch
# PATCH-FIX-UPSTREAM x86: Set minimum x86-64 level marker (BZ #27318)
Patch1002: x86-isa-level.patch
# PATCH-FIX-UPSTREAM nscd: Fix double free in netgroupcache (CVE-2021-27645, BZ #27462)
Patch1003: nscd-netgroupcache.patch
###
# Patches awaiting upstream approval
@ -255,6 +261,8 @@ Patch306: glibc-fix-double-loopback.diff
Patch2000: fix-locking-in-_IO_cleanup.patch
# PATCH-FIX-UPSTREAM Avoid concurrency problem in ldconfig (BZ #23973)
Patch2001: ldconfig-concurrency.patch
# PATCH-FIX-UPSTREAM nss: fix nss_database_lookup2's alternate handling (BZ #27416)
Patch2002: nss-database-lookup.patch
# Non-glibc patches
# PATCH-FIX-OPENSUSE Remove debianisms from manpages
@ -445,7 +453,6 @@ Internal usrmerge bootstrap helper
%prep
%setup -n glibc-%{version} -q -a 4
%patch1 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
@ -465,8 +472,14 @@ Internal usrmerge bootstrap helper
%patch304 -p1
%patch306 -p1
%patch1000 -p1
%patch1001 -p1
%patch1002 -p1
%patch1003 -p1
%patch2000 -p1
%patch2001 -p1
%patch2002 -p1
%patch3000
@ -503,16 +516,17 @@ echo "#define GITID \"%{git_id}\"" >> version.h
#
# Default CFLAGS and Compiler
#
BuildFlags="%{optflags} -U_FORTIFY_SOURCE"
enable_stack_protector=
for opt in $BuildFlags; do
BuildFlags=
tmp="%{optflags}"
for opt in $tmp; do
case $opt in
-fstack-protector-strong) enable_stack_protector=strong ;;
-fstack-protector-all) enable_stack_protector=all ;;
-fstack-protector-*) enable_stack_protector=${opt#-fstack-protector-} ;;
-fstack-protector) enable_stack_protector=yes ;;
-ffortify=* | *_FORTIFY_SOURCE*) ;;
*) BuildFlags+=" $opt" ;;
esac
done
BuildFlags=$(echo $BuildFlags | sed -e 's#-fstack-protector[^ ]*##' -e 's#-ffortify=[0-9]*##')
BuildCC="%__cc"
BuildCCplus="%__cxx"
#
@ -547,10 +561,6 @@ BuildCCplus="%__cxx"
%ifarch hppa
BuildFlags="$BuildFlags -mpa-risc-1-1 -fstrict-aliasing"
%endif
# Add flags for all plattforms except AXP
%ifnarch alpha
BuildFlags="$BuildFlags -g"
%endif
%if %{disable_assert}
BuildFlags="$BuildFlags -DNDEBUG=1"
%endif
@ -565,7 +575,7 @@ BuildCCplus="%__cxx"
mkdir cc-base
cd cc-base
%ifarch %arm aarch64
# remove asynchronous-unwind-tables during configure as it causes
# remove [asynchronous-]unwind-tables during configure as it causes
# some checks to fail spuriously on arm
conf_cflags="${BuildFlags/-fasynchronous-unwind-tables/}"
conf_cflags="${conf_cflags/-funwind-tables/}"
@ -578,8 +588,6 @@ profile="--enable-profile"
%else
profile="--disable-profile"
%endif
# Disable x86 ISA level support for now (bsc#1182522)
export libc_cv_include_x86_isa_level=no
../configure \
CFLAGS="$conf_cflags" BUILD_CFLAGS="$conf_cflags" \
CC="$BuildCC" CXX="$BuildCCplus" \

42
nscd-netgroupcache.patch Normal file
View File

@ -0,0 +1,42 @@
From a151f2e05a64727c552a297d129b8ef242ffb3b6 Mon Sep 17 00:00:00 2001
From: DJ Delorie <dj@redhat.com>
Date: Thu, 25 Feb 2021 16:08:21 -0500
Subject: [PATCH] nscd: Fix double free in netgroupcache [BZ #27462]
In commit 745664bd798ec8fd50438605948eea594179fba1 a use-after-free
was fixed, but this led to an occasional double-free. This patch
tracks the "live" allocation better.
Tested manually by a third party.
Related: RHBZ 1927877
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit dca565886b5e8bd7966e15f0ca42ee5cff686673)
---
nscd/netgroupcache.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
Index: glibc-2.33/nscd/netgroupcache.c
===================================================================
--- glibc-2.33.orig/nscd/netgroupcache.c
+++ glibc-2.33/nscd/netgroupcache.c
@@ -248,7 +248,7 @@ addgetnetgrentX (struct database_dyn *db
: NULL);
ndomain = (ndomain ? newbuf + ndomaindiff
: NULL);
- buffer = newbuf;
+ *tofreep = buffer = newbuf;
}
nhost = memcpy (buffer + bufused,
@@ -319,7 +319,7 @@ addgetnetgrentX (struct database_dyn *db
else if (status == NSS_STATUS_TRYAGAIN && e == ERANGE)
{
buflen *= 2;
- buffer = xrealloc (buffer, buflen);
+ *tofreep = buffer = xrealloc (buffer, buflen);
}
else if (status == NSS_STATUS_RETURN
|| status == NSS_STATUS_NOTFOUND

View File

@ -0,0 +1,45 @@
From 17f0ff097887008b2d3dca270c8ffbb4b43a8749 Mon Sep 17 00:00:00 2001
From: Sergei Trofimovich <slyfox@gentoo.org>
Date: Fri, 5 Feb 2021 07:32:18 +0000
Subject: [PATCH] nsswitch: return result when nss database is locked [BZ
#27343]
Before the change nss_database_check_reload_and_get() did not populate
the '*result' value when it returned success in a case of chroot
detection. This caused initgroups() to use garage pointer in the
following test (extracted from unbound):
```
int main() {
// load some NSS modules
struct passwd * pw = getpwnam("root");
chdir("/tmp");
chroot("/tmp");
chdir("/");
// access nsswitch.conf in a chroot
initgroups("root", 0);
}
```
Reviewed-by: DJ Delorie <dj@redhat.com>
---
nss/nss_database.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
Index: glibc-2.33/nss/nss_database.c
===================================================================
--- glibc-2.33.orig/nss/nss_database.c
+++ glibc-2.33/nss/nss_database.c
@@ -400,8 +400,9 @@ nss_database_check_reload_and_get (struc
&& (str.st_ino != local->root_ino
|| str.st_dev != local->root_dev)))
{
- /* Change detected; disable reloading. */
+ /* Change detected; disable reloading and return current state. */
atomic_store_release (&local->data.reload_disabled, 1);
+ *result = local->data.services[database_index];
__libc_lock_unlock (local->lock);
__nss_module_disable_loading ();
return true;

839
nss-database-lookup.patch Normal file
View File

@ -0,0 +1,839 @@
From: DJ Delorie via Libc-alpha <libc-alpha@sourceware.org>
Subject: [PATCH v4] nss: fix nss_database_lookup2's alternate handling [BZ
#27416]
Date: Fri, 05 Mar 2021 20:29:31 -0500
__nss_database_lookup2's extra arguments were left unused in the
nsswitch reloading patch set; this broke compat (default config
ignored) and shadow files (secondary name ignored) which relies on
these fallbacks.
This patch adds in the previous behavior by correcting the
initialization of the database list to reflect the fallbacks. This
means that the nss_database_lookup2 interface no longer needs to be
passed the fallback info, so API and callers were adjusted.
Since all callers needed to be edited anyway, the calls were changed
from __nss_database_lookup2 to the faster __nss_database_get. This
was an intended optimization which was deferred during the initial
lookup changes to avoid touching so many files.
The test case verifies that compat targets work (passwd) and that the
default configuration works (group). Tested on x86-64.
---
nscd/aicache.c | 4 +-
nscd/initgrcache.c | 3 +-
nscd/netgroupcache.c | 2 +-
nss/Makefile | 1 +
nss/Versions | 2 +-
nss/XXX-lookup.c | 17 +---
nss/databases.def | 3 +
nss/grp-lookup.c | 1 -
nss/hosts-lookup.c | 1 -
nss/key-lookup.c | 1 -
nss/network-lookup.c | 1 -
nss/nss_compat/compat-grp.c | 2 +-
nss/nss_compat/compat-initgroups.c | 2 +-
nss/nss_compat/compat-pwd.c | 2 +-
nss/nss_compat/compat-spwd.c | 3 +-
nss/nss_database.c | 35 ++++++-
nss/nss_database.h | 5 +-
nss/nss_module.c | 20 ++--
nss/nss_test.h | 7 ++
nss/nss_test1.c | 93 +++++++++++++++++++
nss/nsswitch.c | 25 +----
nss/nsswitch.h | 7 +-
nss/pwd-lookup.c | 1 -
nss/sgrp-lookup.c | 2 -
nss/spwd-lookup.c | 2 -
nss/tst-nss-compat1.c | 81 ++++++++++++++++
nss/tst-nss-compat1.root/etc/group | 1 +
nss/tst-nss-compat1.root/etc/nsswitch.conf | 3 +
nss/tst-nss-compat1.root/etc/passwd | 3 +
nss/tst-nss-compat1.root/etc/shadow | 2 +
.../tst-nss-compat1.script | 1 +
sysdeps/posix/getaddrinfo.c | 4 +-
32 files changed, 256 insertions(+), 81 deletions(-)
create mode 100644 nss/tst-nss-compat1.c
create mode 100644 nss/tst-nss-compat1.root/etc/group
create mode 100644 nss/tst-nss-compat1.root/etc/nsswitch.conf
create mode 100644 nss/tst-nss-compat1.root/etc/passwd
create mode 100644 nss/tst-nss-compat1.root/etc/shadow
create mode 100644 nss/tst-nss-compat1.root/tst-nss-compat1.script
Index: glibc-2.33/nscd/aicache.c
===================================================================
--- glibc-2.33.orig/nscd/aicache.c
+++ glibc-2.33/nscd/aicache.c
@@ -77,9 +77,7 @@ addhstaiX (struct database_dyn *db, int
int rc4 = 0;
int herrno = 0;
- no_more = __nss_database_lookup2 ("hosts", NULL,
- "dns [!UNAVAIL=return] files",
- &nip);
+ no_more = (__nss_database_get (nss_database_hosts, &nip) == false);
/* Initialize configurations. */
struct resolv_context *ctx = __resolv_context_get ();
Index: glibc-2.33/nscd/initgrcache.c
===================================================================
--- glibc-2.33.orig/nscd/initgrcache.c
+++ glibc-2.33/nscd/initgrcache.c
@@ -82,8 +82,7 @@ addinitgroupsX (struct database_dyn *db,
int no_more;
if (group_database == NULL)
- no_more = __nss_database_lookup2 ("group", NULL, "files",
- &group_database);
+ no_more = (__nss_database_get (nss_database_group, &group_database) == false);
else
no_more = 0;
nip = group_database;
Index: glibc-2.33/nscd/netgroupcache.c
===================================================================
--- glibc-2.33.orig/nscd/netgroupcache.c
+++ glibc-2.33/nscd/netgroupcache.c
@@ -143,7 +143,7 @@ addgetnetgrentX (struct database_dyn *db
*tofreep = NULL;
if (netgroup_database == NULL
- && __nss_database_lookup2 ("netgroup", NULL, NULL, &netgroup_database))
+ && !__nss_database_get (nss_database_netgroup, &netgroup_database))
{
/* No such service. */
cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout,
Index: glibc-2.33/nss/Makefile
===================================================================
--- glibc-2.33.orig/nss/Makefile
+++ glibc-2.33/nss/Makefile
@@ -63,6 +63,7 @@ tests = test-netdb test-digits-dots ts
xtests = bug-erange
tests-container = \
+ tst-nss-compat1 \
tst-nss-test3 \
tst-nss-files-hosts-long \
tst-nss-db-endpwent \
Index: glibc-2.33/nss/Versions
===================================================================
--- glibc-2.33.orig/nss/Versions
+++ glibc-2.33/nss/Versions
@@ -17,7 +17,7 @@ libc {
__nss_passwd_lookup2; __nss_group_lookup2; __nss_hosts_lookup2;
__nss_services_lookup2; __nss_next2; __nss_lookup;
- __nss_hash; __nss_database_lookup2;
+ __nss_hash; __nss_database_lookup2; __nss_database_get;
__nss_files_fopen; __nss_readline; __nss_parse_line_result;
}
}
Index: glibc-2.33/nss/XXX-lookup.c
===================================================================
--- glibc-2.33.orig/nss/XXX-lookup.c
+++ glibc-2.33/nss/XXX-lookup.c
@@ -37,27 +37,20 @@
#define CONCAT3_1(Pre, Name, Post) CONCAT3_2 (Pre, Name, Post)
#define CONCAT3_2(Pre, Name, Post) Pre##Name##Post
+#define DATABASE_NAME_ID CONCAT2_1 (nss_database_, DATABASE_NAME)
+#define CONCAT2_1(Pre, Name) CONCAT2_2 (Pre, Name)
+#define CONCAT2_2(Pre, Name) Pre##Name
+
#define DATABASE_NAME_SYMBOL CONCAT3_1 (__nss_, DATABASE_NAME, _database)
#define DATABASE_NAME_STRING STRINGIFY1 (DATABASE_NAME)
#define STRINGIFY1(Name) STRINGIFY2 (Name)
#define STRINGIFY2(Name) #Name
-#ifdef ALTERNATE_NAME
-#define ALTERNATE_NAME_STRING STRINGIFY1 (ALTERNATE_NAME)
-#else
-#define ALTERNATE_NAME_STRING NULL
-#endif
-
-#ifndef DEFAULT_CONFIG
-#define DEFAULT_CONFIG NULL
-#endif
-
int
DB_LOOKUP_FCT (nss_action_list *ni, const char *fct_name, const char *fct2_name,
void **fctp)
{
- if (__nss_database_lookup2 (DATABASE_NAME_STRING, ALTERNATE_NAME_STRING,
- DEFAULT_CONFIG, &DATABASE_NAME_SYMBOL) < 0)
+ if (! __nss_database_get (DATABASE_NAME_ID, &DATABASE_NAME_SYMBOL))
return -1;
*ni = DATABASE_NAME_SYMBOL;
Index: glibc-2.33/nss/databases.def
===================================================================
--- glibc-2.33.orig/nss/databases.def
+++ glibc-2.33/nss/databases.def
@@ -23,17 +23,20 @@
DEFINE_DATABASE (aliases)
DEFINE_DATABASE (ethers)
DEFINE_DATABASE (group)
+DEFINE_DATABASE (group_compat)
DEFINE_DATABASE (gshadow)
DEFINE_DATABASE (hosts)
DEFINE_DATABASE (initgroups)
DEFINE_DATABASE (netgroup)
DEFINE_DATABASE (networks)
DEFINE_DATABASE (passwd)
+DEFINE_DATABASE (passwd_compat)
DEFINE_DATABASE (protocols)
DEFINE_DATABASE (publickey)
DEFINE_DATABASE (rpc)
DEFINE_DATABASE (services)
DEFINE_DATABASE (shadow)
+DEFINE_DATABASE (shadow_compat)
/*
Local Variables:
Index: glibc-2.33/nss/grp-lookup.c
===================================================================
--- glibc-2.33.orig/nss/grp-lookup.c
+++ glibc-2.33/nss/grp-lookup.c
@@ -19,6 +19,5 @@
#include <config.h>
#define DATABASE_NAME group
-#define DEFAULT_CONFIG "files"
#include "XXX-lookup.c"
Index: glibc-2.33/nss/hosts-lookup.c
===================================================================
--- glibc-2.33.orig/nss/hosts-lookup.c
+++ glibc-2.33/nss/hosts-lookup.c
@@ -17,6 +17,5 @@
<https://www.gnu.org/licenses/>. */
#define DATABASE_NAME hosts
-#define DEFAULT_CONFIG "dns [!UNAVAIL=return] files"
#include "XXX-lookup.c"
Index: glibc-2.33/nss/key-lookup.c
===================================================================
--- glibc-2.33.orig/nss/key-lookup.c
+++ glibc-2.33/nss/key-lookup.c
@@ -17,6 +17,5 @@
<https://www.gnu.org/licenses/>. */
#define DATABASE_NAME publickey
-#define DEFAULT_CONFIG "nis nisplus"
#include "XXX-lookup.c"
Index: glibc-2.33/nss/network-lookup.c
===================================================================
--- glibc-2.33.orig/nss/network-lookup.c
+++ glibc-2.33/nss/network-lookup.c
@@ -17,6 +17,5 @@
<https://www.gnu.org/licenses/>. */
#define DATABASE_NAME networks
-#define DEFAULT_CONFIG "dns [!UNAVAIL=return] files"
#include "XXX-lookup.c"
Index: glibc-2.33/nss/nss_compat/compat-grp.c
===================================================================
--- glibc-2.33.orig/nss/nss_compat/compat-grp.c
+++ glibc-2.33/nss/nss_compat/compat-grp.c
@@ -81,7 +81,7 @@ static bool in_blacklist (const char *,
static void
init_nss_interface (void)
{
- if (__nss_database_lookup2 ("group_compat", NULL, "nis", &ni) >= 0)
+ if (__nss_database_get (nss_database_group_compat, &ni))
{
setgrent_impl = __nss_lookup_function (ni, "setgrent");
getgrnam_r_impl = __nss_lookup_function (ni, "getgrnam_r");
Index: glibc-2.33/nss/nss_compat/compat-initgroups.c
===================================================================
--- glibc-2.33.orig/nss/nss_compat/compat-initgroups.c
+++ glibc-2.33/nss/nss_compat/compat-initgroups.c
@@ -91,7 +91,7 @@ init_nss_interface (void)
/* Retest. */
if (ni == NULL
- && __nss_database_lookup2 ("group_compat", NULL, "nis", &ni) >= 0)
+ && __nss_database_get (nss_database_group_compat, &ni))
{
initgroups_dyn_impl = __nss_lookup_function (ni, "initgroups_dyn");
getgrnam_r_impl = __nss_lookup_function (ni, "getgrnam_r");
Index: glibc-2.33/nss/nss_compat/compat-pwd.c
===================================================================
--- glibc-2.33.orig/nss/nss_compat/compat-pwd.c
+++ glibc-2.33/nss/nss_compat/compat-pwd.c
@@ -91,7 +91,7 @@ static bool in_blacklist (const char *,
static void
init_nss_interface (void)
{
- if (__nss_database_lookup2 ("passwd_compat", NULL, "nis", &ni) >= 0)
+ if (__nss_database_get (nss_database_passwd_compat, &ni))
{
setpwent_impl = __nss_lookup_function (ni, "setpwent");
getpwnam_r_impl = __nss_lookup_function (ni, "getpwnam_r");
Index: glibc-2.33/nss/nss_compat/compat-spwd.c
===================================================================
--- glibc-2.33.orig/nss/nss_compat/compat-spwd.c
+++ glibc-2.33/nss/nss_compat/compat-spwd.c
@@ -88,8 +88,7 @@ static bool in_blacklist (const char *,
static void
init_nss_interface (void)
{
- if (__nss_database_lookup2 ("shadow_compat", "passwd_compat",
- "nis", &ni) >= 0)
+ if (__nss_database_get (nss_database_shadow_compat, &ni))
{
setspent_impl = __nss_lookup_function (ni, "setspent");
getspnam_r_impl = __nss_lookup_function (ni, "getspnam_r");
Index: glibc-2.33/nss/nss_database.c
===================================================================
--- glibc-2.33.orig/nss/nss_database.c
+++ glibc-2.33/nss/nss_database.c
@@ -93,13 +93,16 @@ enum nss_database_default
static const char per_database_defaults[NSS_DATABASE_COUNT] =
{
[nss_database_group] = nss_database_default_compat,
+ [nss_database_group_compat] = nss_database_default_nis,
[nss_database_gshadow] = nss_database_default_files,
[nss_database_hosts] = nss_database_default_dns,
[nss_database_initgroups] = nss_database_default_none,
[nss_database_networks] = nss_database_default_dns,
[nss_database_passwd] = nss_database_default_compat,
+ [nss_database_passwd_compat] = nss_database_default_nis,
[nss_database_publickey] = nss_database_default_nis_nisplus,
[nss_database_shadow] = nss_database_default_compat,
+ [nss_database_shadow_compat] = nss_database_default_nis,
};
struct nss_database_default_cache
@@ -166,13 +169,12 @@ nss_database_select_default (struct nss_
assert (errno == ENOMEM);
return false;
}
- else
- return true;
+ return true;
}
/* database_name must be large enough for each individual name plus a
null terminator. */
-typedef char database_name[11];
+typedef char database_name[14];
#define DEFINE_DATABASE(name) \
_Static_assert (sizeof (#name) <= sizeof (database_name), #name);
#include "databases.def"
@@ -325,14 +327,40 @@ nss_database_reload (struct nss_database
/* No other threads have access to fp. */
__fsetlocking (fp, FSETLOCKING_BYCALLER);
+ /* We start with all of *staging pointing to NULL. */
+
bool ok = true;
if (fp != NULL)
ok = nss_database_reload_1 (staging, fp);
+ /* Now we have non-NULL entries where the user explictly listed the
+ service in nsswitch.conf. */
+
/* Apply defaults. */
if (ok)
{
struct nss_database_default_cache cache = { };
+
+ /* These three default to other services if the user listed the
+ other service. */
+
+ /* was lookup2() in nss/nss_compat/compat-spwd.c */
+ if (staging->services[nss_database_shadow_compat] == NULL)
+ staging->services[nss_database_shadow_compat] =
+ staging->services[nss_database_passwd_compat];
+
+ /* was ALTERNATE_NAME in nss/spwd_lookup.c */
+ if (staging->services[nss_database_shadow] == NULL)
+ staging->services[nss_database_shadow] =
+ staging->services[nss_database_passwd];
+
+ /* was ALTERNATE_NAME in nss/sgrp_lookup.c */
+ if (staging->services[nss_database_gshadow] == NULL)
+ staging->services[nss_database_gshadow] =
+ staging->services[nss_database_group];
+
+ /* For anything still unspecified, load the default configs. */
+
for (int i = 0; i < NSS_DATABASE_COUNT; ++i)
if (staging->services[i] == NULL)
{
@@ -442,6 +470,7 @@ __nss_database_get (enum nss_database db
struct nss_database_state *local = nss_database_state_get ();
return nss_database_check_reload_and_get (local, actions, db);
}
+libc_hidden_def (__nss_database_get)
nss_action_list
__nss_database_get_noreload (enum nss_database db)
Index: glibc-2.33/nss/nss_database.h
===================================================================
--- glibc-2.33.orig/nss/nss_database.h
+++ glibc-2.33/nss/nss_database.h
@@ -52,12 +52,11 @@ enum nss_database
NSS_DATABASE_COUNT
};
-
/* Looks up the action list for DB and stores it in *ACTIONS. Returns
true on success or false on failure. Success can mean that
*ACTIONS is NULL. */
-bool __nss_database_get (enum nss_database db, nss_action_list *actions)
- attribute_hidden;
+bool __nss_database_get (enum nss_database db, nss_action_list *actions);
+libc_hidden_proto (__nss_database_get)
/* Like __nss_database_get, but does not reload /etc/nsswitch.conf
from disk. This assumes that there has been a previous successful
Index: glibc-2.33/nss/nss_module.c
===================================================================
--- glibc-2.33.orig/nss/nss_module.c
+++ glibc-2.33/nss/nss_module.c
@@ -31,14 +31,6 @@
#include <stdlib.h>
#include <string.h>
-#ifdef LINK_OBSOLETE_NSL
-# define DEFAULT_CONFIG "compat [NOTFOUND=return] files"
-# define DEFAULT_DEFCONFIG "nis [NOTFOUND=return] files"
-#else
-# define DEFAULT_CONFIG "files"
-# define DEFAULT_DEFCONFIG "files"
-#endif
-
/* Suffix after .so of NSS service modules. This is a bit of magic,
but we assume LIBNSS_FILES_SO looks like "libnss_files.so.2" and we
want a pointer to the ".2" part. We have no API to extract this
@@ -292,11 +284,11 @@ __nss_module_get_function (struct nss_mo
#if defined SHARED && defined USE_NSCD
/* Load all libraries for the service. */
static void
-nss_load_all_libraries (const char *service, const char *def)
+nss_load_all_libraries (enum nss_database service)
{
nss_action_list ni = NULL;
- if (__nss_database_lookup2 (service, NULL, def, &ni) == 0)
+ if (__nss_database_get (service, &ni))
while (ni->module != NULL)
{
__nss_module_load (ni->module);
@@ -323,10 +315,10 @@ __nss_disable_nscd (void (*cb) (size_t,
is_nscd = true;
/* Find all the relevant modules so that the init functions are called. */
- nss_load_all_libraries ("passwd", DEFAULT_CONFIG);
- nss_load_all_libraries ("group", DEFAULT_CONFIG);
- nss_load_all_libraries ("hosts", "dns [!UNAVAIL=return] files");
- nss_load_all_libraries ("services", NULL);
+ nss_load_all_libraries (nss_database_passwd);
+ nss_load_all_libraries (nss_database_group);
+ nss_load_all_libraries (nss_database_hosts);
+ nss_load_all_libraries (nss_database_services);
/* Make sure NSCD purges its cache if nsswitch.conf changes. */
init_traced_file (&pwd_traced_file.file, _PATH_NSSWITCH_CONF, 0);
Index: glibc-2.33/nss/nss_test.h
===================================================================
--- glibc-2.33.orig/nss/nss_test.h
+++ glibc-2.33/nss/nss_test.h
@@ -33,11 +33,13 @@
#include <pwd.h>
#include <grp.h>
+#include <shadow.h>
#include <netdb.h>
typedef struct test_tables {
struct passwd *pwd_table;
struct group *grp_table;
+ struct spwd *spwd_table;
struct hostent *host_table;
} test_tables;
@@ -46,10 +48,12 @@ extern void _nss_test2_init_hook (test_t
#define PWD_LAST() { .pw_name = NULL, .pw_uid = 0 }
#define GRP_LAST() { .gr_name = NULL, .gr_gid = 0 }
+#define SPWD_LAST() { .sp_namp = NULL, .sp_pwdp = NULL }
#define HOST_LAST() { .h_name = NULL, .h_aliases = NULL, .h_length = 0, .h_addr_list = NULL }
#define PWD_ISLAST(p) ((p)->pw_name == NULL && (p)->pw_uid == 0)
#define GRP_ISLAST(g) ((g)->gr_name == NULL && (g)->gr_gid == 0)
+#define SPWD_ISLAST(s) ((s)->sp_namp == NULL && (s)->sp_pwdp == 0)
#define HOST_ISLAST(h) ((h)->h_name == NULL && (h)->h_length == 0)
/* Macros to fill in the tables easily. */
@@ -76,6 +80,9 @@ extern void _nss_test2_init_hook (test_t
{ .gr_name = (char *) n, .gr_passwd = (char *) "*", .gr_gid = u, \
.gr_mem = (char **) m }
+#define SPWD(u) \
+ { .sp_namp = (char *) "name" #u, .sp_pwdp = (char *) "passwd" #u }
+
#define HOST(u) \
{ .h_name = (char *) "name" #u, .h_aliases = NULL, .h_addrtype = u, \
.h_length = 4, \
Index: glibc-2.33/nss/nss_test1.c
===================================================================
--- glibc-2.33.orig/nss/nss_test1.c
+++ glibc-2.33/nss/nss_test1.c
@@ -66,6 +66,9 @@ static int npwd_data = default_npwd_data
static struct group *grp_data = NULL;
static int ngrp_data = 0;
+static struct spwd *spwd_data = NULL;
+static int nspwd_data = 0;
+
static struct hostent *host_data = NULL;
static int nhost_data = 0;
@@ -102,6 +105,13 @@ init(void)
;
ngrp_data = i;
}
+ if (t.spwd_table)
+ {
+ spwd_data = t.spwd_table;
+ for (i=0; ! SPWD_ISLAST(& spwd_data[i]); i++)
+ ;
+ nspwd_data = i;
+ }
if (t.host_table)
{
host_data = t.host_table;
@@ -322,6 +332,89 @@ NAME(getgrnam_r) (const char *name, stru
return NSS_STATUS_NOTFOUND;
}
+
+/* -------------------------------------------------- */
+/* Shadow password handling. */
+
+static size_t spwd_iter;
+#define CURSPWD spwd_data[spwd_iter]
+
+static pthread_mutex_t spwd_lock = PTHREAD_MUTEX_INITIALIZER;
+
+enum nss_status
+NAME(setspent) (int stayopen)
+{
+ init();
+ spwd_iter = 0;
+ return NSS_STATUS_SUCCESS;
+}
+
+
+enum nss_status
+NAME(endspwent) (void)
+{
+ init();
+ return NSS_STATUS_SUCCESS;
+}
+
+static enum nss_status
+copy_shadow (struct spwd *result, struct spwd *local,
+ char *buffer, size_t buflen, int *errnop)
+{
+ struct alloc_buffer buf = alloc_buffer_create (buffer, buflen);
+
+ result->sp_namp = alloc_buffer_maybe_copy_string (&buf, local->sp_namp);
+ result->sp_pwdp = alloc_buffer_maybe_copy_string (&buf, local->sp_pwdp);
+ result->sp_lstchg = local->sp_lstchg;
+ result->sp_min = local->sp_min;
+ result->sp_max = local->sp_max;
+ result->sp_warn = local->sp_warn;
+ result->sp_inact = local->sp_inact;
+ result->sp_expire = local->sp_expire;
+ result->sp_flag = local->sp_flag;
+
+ if (alloc_buffer_has_failed (&buf))
+ {
+ *errnop = ERANGE;
+ return NSS_STATUS_TRYAGAIN;
+ }
+
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status
+NAME(getspent_r) (struct spwd *result, char *buffer, size_t buflen,
+ int *errnop)
+{
+ int res = NSS_STATUS_SUCCESS;
+
+ init();
+ pthread_mutex_lock (&spwd_lock);
+
+ if (spwd_iter >= nspwd_data)
+ res = NSS_STATUS_NOTFOUND;
+ else
+ {
+ res = copy_shadow (result, &CURSPWD, buffer, buflen, errnop);
+ ++spwd_iter;
+ }
+
+ pthread_mutex_unlock (&spwd_lock);
+
+ return res;
+}
+
+enum nss_status
+NAME(getspnam_r) (const char *name, struct spwd *result, char *buffer,
+ size_t buflen, int *errnop)
+{
+ init();
+ for (size_t idx = 0; idx < nspwd_data; ++idx)
+ if (strcmp (spwd_data[idx].sp_namp, name) == 0)
+ return copy_shadow (result, &spwd_data[idx], buffer, buflen, errnop);
+
+ return NSS_STATUS_NOTFOUND;
+}
/* -------------------------------------------------- */
/* Host handling. */
Index: glibc-2.33/nss/nsswitch.c
===================================================================
--- glibc-2.33.orig/nss/nsswitch.c
+++ glibc-2.33/nss/nsswitch.c
@@ -63,37 +63,22 @@ static const char * database_names[] = {
bool __nss_database_custom[NSS_DBSIDX_max];
#endif
-
/*__libc_lock_define_initialized (static, lock)*/
/* -1 == database not found
0 == database entry pointer stored */
int
-__nss_database_lookup2 (const char *database, const char *alternate_name,
- const char *defconfig, nss_action_list *ni)
+__nss_database_lookup2 (const char *database, nss_action_list *ni)
{
int database_id;
for (database_id = 0; database_names[database_id]; database_id++)
if (strcmp (database_names[database_id], database) == 0)
- break;
-
- if (database_names[database_id] == NULL)
- return -1;
+ if (__nss_database_get (database_id, ni))
+ return 0;
- /* If *NI is NULL, the database was not mentioned in nsswitch.conf.
- If *NI is not NULL, but *NI->module is NULL, the database was in
- nsswitch.conf but listed no actions. We test for the former. */
- if (__nss_database_get (database_id, ni) && *ni != NULL)
- {
- /* Success. */
- return 0;
- }
- else
- {
- /* Failure. */
- return -1;
- }
+ /* Failure. */
+ return -1;
}
libc_hidden_def (__nss_database_lookup2)
Index: glibc-2.33/nss/nsswitch.h
===================================================================
--- glibc-2.33.orig/nss/nsswitch.h
+++ glibc-2.33/nss/nsswitch.h
@@ -88,13 +88,10 @@ extern bool __nss_database_custom[NSS_DB
/* Interface functions for NSS. */
-/* Get the data structure representing the specified database.
- If there is no configuration for this database in the file,
- parse a service list from DEFCONFIG and use that. More
+/* Get the data structure representing the specified database. More
than one function can use the database. */
extern int __nss_database_lookup2 (const char *database,
- const char *alternative_name,
- const char *defconfig, struct nss_action **ni);
+ struct nss_action **ni);
libc_hidden_proto (__nss_database_lookup2)
/* Put first function with name FCT_NAME for SERVICE in FCTP. The
Index: glibc-2.33/nss/pwd-lookup.c
===================================================================
--- glibc-2.33.orig/nss/pwd-lookup.c
+++ glibc-2.33/nss/pwd-lookup.c
@@ -19,6 +19,5 @@
#include <config.h>
#define DATABASE_NAME passwd
-#define DEFAULT_CONFIG "files"
#include "XXX-lookup.c"
Index: glibc-2.33/nss/sgrp-lookup.c
===================================================================
--- glibc-2.33.orig/nss/sgrp-lookup.c
+++ glibc-2.33/nss/sgrp-lookup.c
@@ -17,7 +17,5 @@
<https://www.gnu.org/licenses/>. */
#define DATABASE_NAME gshadow
-#define ALTERNATE_NAME group
-#define DEFAULT_CONFIG "files"
#include "XXX-lookup.c"
Index: glibc-2.33/nss/spwd-lookup.c
===================================================================
--- glibc-2.33.orig/nss/spwd-lookup.c
+++ glibc-2.33/nss/spwd-lookup.c
@@ -19,7 +19,5 @@
#include <config.h>
#define DATABASE_NAME shadow
-#define ALTERNATE_NAME passwd
-#define DEFAULT_CONFIG "files"
#include "XXX-lookup.c"
Index: glibc-2.33/nss/tst-nss-compat1.c
===================================================================
--- /dev/null
+++ glibc-2.33/nss/tst-nss-compat1.c
@@ -0,0 +1,81 @@
+/* Test error checking for group entries.
+ Copyright (C) 2021 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
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <nss.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <shadow.h>
+
+#include <support/support.h>
+#include <support/check.h>
+
+#include "nss_test.h"
+
+static struct passwd pwd_table[] = {
+ PWD (100),
+ PWD (30),
+ PWD_LAST ()
+ };
+
+static struct spwd spwd_table[] = {
+ SPWD (100),
+ SPWD (30),
+ SPWD_LAST ()
+ };
+
+void
+_nss_test1_init_hook(test_tables *t)
+{
+ t->pwd_table = pwd_table;
+ t->spwd_table = spwd_table;
+}
+
+static int
+do_test (void)
+{
+ struct passwd *p = NULL;
+ struct spwd *s = NULL;
+ struct group *g = NULL;
+
+ /* Test that compat-to-test works. */
+ p = getpwuid (100);
+ if (p == NULL)
+ FAIL_EXIT1("getpwuid-compat-test1 p");
+ else if (strcmp (p->pw_name, "name100") != 0)
+ FAIL_EXIT1("getpwuid-compat-test1 name100");
+
+ /* Shadow compat should use passwd via the alternate name. */
+ s = getspnam ("name30");
+ if (s == NULL)
+ FAIL_EXIT1("getspnam-compat-test1 s");
+ else if (strcmp (s->sp_namp, "name30") != 0)
+ FAIL_EXIT1("getpwuid-compat-test1 name30");
+
+ /* Test that internal defconfig works. */
+ g = getgrgid (100);
+ if (g == NULL)
+ FAIL_EXIT1("getgrgid-compat-null");
+ if (strcmp (g->gr_name, "wilma") != 0)
+ FAIL_EXIT1("getgrgid-compat-name");
+
+ return 0;
+}
+
+#include <support/test-driver.c>
Index: glibc-2.33/nss/tst-nss-compat1.root/etc/group
===================================================================
--- /dev/null
+++ glibc-2.33/nss/tst-nss-compat1.root/etc/group
@@ -0,0 +1 @@
+wilma:x:100:
Index: glibc-2.33/nss/tst-nss-compat1.root/etc/nsswitch.conf
===================================================================
--- /dev/null
+++ glibc-2.33/nss/tst-nss-compat1.root/etc/nsswitch.conf
@@ -0,0 +1,3 @@
+passwd : compat
+passwd_compat : test1
+
Index: glibc-2.33/nss/tst-nss-compat1.root/etc/passwd
===================================================================
--- /dev/null
+++ glibc-2.33/nss/tst-nss-compat1.root/etc/passwd
@@ -0,0 +1,3 @@
+name5:x:5:555:name5 for testing:/home/name5:/bin/nologin
++name100
++name30
Index: glibc-2.33/nss/tst-nss-compat1.root/etc/shadow
===================================================================
--- /dev/null
+++ glibc-2.33/nss/tst-nss-compat1.root/etc/shadow
@@ -0,0 +1,2 @@
++name100
++name30
Index: glibc-2.33/nss/tst-nss-compat1.root/tst-nss-compat1.script
===================================================================
--- /dev/null
+++ glibc-2.33/nss/tst-nss-compat1.root/tst-nss-compat1.script
@@ -0,0 +1 @@
+cp $B/nss/libnss_test1.so $L/libnss_test1.so.2
Index: glibc-2.33/sysdeps/posix/getaddrinfo.c
===================================================================
--- glibc-2.33.orig/sysdeps/posix/getaddrinfo.c
+++ glibc-2.33/sysdeps/posix/getaddrinfo.c
@@ -720,9 +720,7 @@ gaih_inet (const char *name, const struc
}
#endif
- no_more = __nss_database_lookup2 ("hosts", NULL,
- "dns [!UNAVAIL=return] files",
- &nip);
+ no_more = (__nss_database_get (nss_database_hosts, &nip) == false);
/* If we are looking for both IPv4 and IPv6 address we don't
want the lookup functions to automatically promote IPv4

172
nss-load-chroot.patch Normal file
View File

@ -0,0 +1,172 @@
From 3e880d733753183696d1a81c34caef3a9add2b0c Mon Sep 17 00:00:00 2001
From: DJ Delorie <dj@redhat.com>
Date: Thu, 18 Feb 2021 15:26:30 -0500
Subject: [PATCH] nss: Re-enable NSS module loading after chroot [BZ #27389]
The glibc 2.33 release enabled /etc/nsswitch.conf reloading,
and to prevent potential security issues like CVE-2019-14271
the re-loading of nsswitch.conf and all mdoules was disabled
when the root filesystem changes (see bug 27077).
Unfortunately php-lpfm and openldap both require the ability
to continue to load NSS modules after chroot. The packages
do not exec after the chroot, and so do not cause the
protections to be reset. The only solution is to re-enable
only NSS module loading (not nsswitch.conf reloading) and so
get back the previous glibc behaviour.
In the future we may introduce a way to harden applications
so they do not reload NSS modules once the root filesystem
changes, or that only files/dns are available pre-loaded
(or builtin).
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit 58673149f37389495c098421085ffdb468b3f7ad)
---
nss/nss_database.c | 1 -
nss/tst-reload2.c | 35 +++++++++++++++----
nss/tst-reload2.root/etc/hosts | 1 +
nss/tst-reload2.root/etc/nsswitch.conf | 1 +
nss/tst-reload2.root/subdir/etc/hosts | 1 +
nss/tst-reload2.root/subdir/etc/nsswitch.conf | 1 +
6 files changed, 32 insertions(+), 8 deletions(-)
create mode 100644 nss/tst-reload2.root/etc/hosts
create mode 100644 nss/tst-reload2.root/subdir/etc/hosts
Index: glibc-2.33/nss/nss_database.c
===================================================================
--- glibc-2.33.orig/nss/nss_database.c
+++ glibc-2.33/nss/nss_database.c
@@ -404,7 +404,6 @@ nss_database_check_reload_and_get (struc
atomic_store_release (&local->data.reload_disabled, 1);
*result = local->data.services[database_index];
__libc_lock_unlock (local->lock);
- __nss_module_disable_loading ();
return true;
}
local->root_ino = str.st_ino;
Index: glibc-2.33/nss/tst-reload2.c
===================================================================
--- glibc-2.33.orig/nss/tst-reload2.c
+++ glibc-2.33/nss/tst-reload2.c
@@ -26,6 +26,7 @@
#include <pwd.h>
#include <grp.h>
#include <unistd.h>
+#include <netdb.h>
#include <support/support.h>
#include <support/check.h>
@@ -48,7 +49,7 @@ static const char *group_4[] = {
"alpha", "beta", "gamma", "fred", NULL
};
-static struct group group_table_data[] =
+static struct group group_table_data1[] =
{
GRP (4),
GRP_LAST ()
@@ -58,7 +59,7 @@ void
_nss_test1_init_hook (test_tables *t)
{
t->pwd_table = pwd_table1;
- t->grp_table = group_table_data;
+ t->grp_table = group_table_data1;
}
static struct passwd pwd_table2[] =
@@ -68,10 +69,21 @@ static struct passwd pwd_table2[] =
PWD_LAST ()
};
+static const char *group_5[] = {
+ "fred", NULL
+};
+
+static struct group group_table_data2[] =
+ {
+ GRP (5),
+ GRP_LAST ()
+ };
+
void
_nss_test2_init_hook (test_tables *t)
{
t->pwd_table = pwd_table2;
+ t->grp_table = group_table_data2;
}
static int
@@ -79,6 +91,7 @@ do_test (void)
{
struct passwd *pw;
struct group *gr;
+ struct hostent *he;
char buf1[PATH_MAX];
char buf2[PATH_MAX];
@@ -99,7 +112,9 @@ do_test (void)
TEST_COMPARE (pw->pw_uid, 1234);
/* This just loads the test2 DSO. */
- gr = getgrnam ("name4");
+ gr = getgrgid (5);
+ TEST_VERIFY (gr != NULL);
+
/* Change the root dir. */
@@ -114,15 +129,21 @@ do_test (void)
if (pw)
TEST_VERIFY (pw->pw_uid != 2468);
- /* The "files" DSO should not be loaded. */
- gr = getgrnam ("test3");
- TEST_VERIFY (gr == NULL);
-
/* We should still be using the old configuration. */
pw = getpwnam ("test1");
TEST_VERIFY (pw != NULL);
if (pw)
TEST_COMPARE (pw->pw_uid, 1234);
+ gr = getgrgid (5);
+ TEST_VERIFY (gr != NULL);
+ gr = getgrnam ("name4");
+ TEST_VERIFY (gr == NULL);
+
+ /* hosts in the outer nsswitch is files; the inner one is test1.
+ Verify that we're still using the outer nsswitch *and* that we
+ can load the files DSO. */
+ he = gethostbyname ("test2");
+ TEST_VERIFY (he != NULL);
return 0;
}
Index: glibc-2.33/nss/tst-reload2.root/etc/hosts
===================================================================
--- /dev/null
+++ glibc-2.33/nss/tst-reload2.root/etc/hosts
@@ -0,0 +1 @@
+1.2.3.4 test1
Index: glibc-2.33/nss/tst-reload2.root/etc/nsswitch.conf
===================================================================
--- glibc-2.33.orig/nss/tst-reload2.root/etc/nsswitch.conf
+++ glibc-2.33/nss/tst-reload2.root/etc/nsswitch.conf
@@ -1,2 +1,3 @@
passwd: test1
group: test2
+hosts: files
Index: glibc-2.33/nss/tst-reload2.root/subdir/etc/hosts
===================================================================
--- /dev/null
+++ glibc-2.33/nss/tst-reload2.root/subdir/etc/hosts
@@ -0,0 +1 @@
+1.2.3.4 test2
Index: glibc-2.33/nss/tst-reload2.root/subdir/etc/nsswitch.conf
===================================================================
--- glibc-2.33.orig/nss/tst-reload2.root/subdir/etc/nsswitch.conf
+++ glibc-2.33/nss/tst-reload2.root/subdir/etc/nsswitch.conf
@@ -1,2 +1,3 @@
passwd: test2
group: files
+hosts: test1

File diff suppressed because it is too large Load Diff

183
x86-isa-level.patch Normal file
View File

@ -0,0 +1,183 @@
From ee9f98d9cac12e843ca59c6e4d4b225f58a66727 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Tue, 2 Feb 2021 13:45:58 -0800
Subject: [PATCH] x86: Set minimum x86-64 level marker [BZ #27318]
Since the full ISA set used in an ELF binary is unknown to compiler,
an x86-64 ISA level marker indicates the minimum, not maximum, ISA set
required to run such an ELF binary. We never guarantee a library with
an x86-64 ISA level v3 marker doesn't contain other ISAs beyond x86-64
ISA level v3, like AVX VNNI. We check the x86-64 ISA level marker for
the minimum ISA set. Since -march=sandybridge enables only some ISAs
in x86-64 ISA level v3, we should set the needed ISA marker to v2.
Otherwise, libc is compiled with -march=sandybridge will fail to run on
Sandy Bridge:
$ ./elf/ld.so ./libc.so
./libc.so: (p) CPU ISA level is lower than required: needed: 7; got: 3
Set the minimum, instead of maximum, x86-64 ISA level marker should have
no impact on the glibc-hwcaps directory assignment logic in ldconfig nor
ld.so.
(cherry picked from commit 339bf918ea4830fb35614632e96f3aab3237adce)
---
config.h.in | 6 ++++++
sysdeps/x86/configure | 28 ++++++++++++++++++++++++++++
sysdeps/x86/configure.ac | 16 ++++++++++++++++
sysdeps/x86/isa-level.c | 25 ++++++++++++++-----------
4 files changed, 64 insertions(+), 11 deletions(-)
Index: glibc-2.33/config.h.in
===================================================================
--- glibc-2.33.orig/config.h.in
+++ glibc-2.33/config.h.in
@@ -275,4 +275,10 @@
/* Define if x86 ISA level should be included in shared libraries. */
#undef INCLUDE_X86_ISA_LEVEL
+/* Define if -msahf is enabled by default on x86. */
+#undef HAVE_X86_LAHF_SAHF
+
+/* Define if -mmovbe is enabled by default on x86. */
+#undef HAVE_X86_MOVBE
+
#endif
Index: glibc-2.33/sysdeps/x86/configure
===================================================================
--- glibc-2.33.orig/sysdeps/x86/configure
+++ glibc-2.33/sysdeps/x86/configure
@@ -126,6 +126,8 @@ cat > conftest2.S <<EOF
4:
EOF
libc_cv_include_x86_isa_level=no
+libc_cv_have_x86_lahf_sahf=no
+libc_cv_have_x86_movbe=no
if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -nostartfiles -nostdlib -r -o conftest conftest1.S conftest2.S'
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
(eval $ac_try) 2>&5
@@ -135,6 +137,24 @@ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS
count=`LC_ALL=C $READELF -n conftest | grep NT_GNU_PROPERTY_TYPE_0 | wc -l`
if test "$count" = 1; then
libc_cv_include_x86_isa_level=yes
+ cat > conftest.c <<EOF
+EOF
+ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - conftest.c'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; } | grep -q "\-msahf"; then
+ libc_cv_have_x86_lahf_sahf=yes
+ fi
+ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - conftest.c'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; } | grep -q "\-mmovbe"; then
+ libc_cv_have_x86_movbe=yes
+ fi
fi
fi
rm -f conftest*
@@ -145,5 +165,13 @@ if test $libc_cv_include_x86_isa_level =
$as_echo "#define INCLUDE_X86_ISA_LEVEL 1" >>confdefs.h
fi
+if test $libc_cv_have_x86_lahf_sahf = yes; then
+ $as_echo "#define HAVE_X86_LAHF_SAHF 1" >>confdefs.h
+
+fi
+if test $libc_cv_have_x86_movbe = yes; then
+ $as_echo "#define HAVE_X86_MOVBE 1" >>confdefs.h
+
+fi
config_vars="$config_vars
enable-x86-isa-level = $libc_cv_include_x86_isa_level"
Index: glibc-2.33/sysdeps/x86/configure.ac
===================================================================
--- glibc-2.33.orig/sysdeps/x86/configure.ac
+++ glibc-2.33/sysdeps/x86/configure.ac
@@ -98,14 +98,30 @@ cat > conftest2.S <<EOF
4:
EOF
libc_cv_include_x86_isa_level=no
+libc_cv_have_x86_lahf_sahf=no
+libc_cv_have_x86_movbe=no
if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -nostartfiles -nostdlib -r -o conftest conftest1.S conftest2.S); then
count=`LC_ALL=C $READELF -n conftest | grep NT_GNU_PROPERTY_TYPE_0 | wc -l`
if test "$count" = 1; then
libc_cv_include_x86_isa_level=yes
+ cat > conftest.c <<EOF
+EOF
+ if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - conftest.c) | grep -q "\-msahf"; then
+ libc_cv_have_x86_lahf_sahf=yes
+ fi
+ if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - conftest.c) | grep -q "\-mmovbe"; then
+ libc_cv_have_x86_movbe=yes
+ fi
fi
fi
rm -f conftest*])
if test $libc_cv_include_x86_isa_level = yes; then
AC_DEFINE(INCLUDE_X86_ISA_LEVEL)
fi
+if test $libc_cv_have_x86_lahf_sahf = yes; then
+ AC_DEFINE(HAVE_X86_LAHF_SAHF)
+fi
+if test $libc_cv_have_x86_movbe = yes; then
+ AC_DEFINE(HAVE_X86_MOVBE)
+fi
LIBC_CONFIG_VAR([enable-x86-isa-level], [$libc_cv_include_x86_isa_level])
Index: glibc-2.33/sysdeps/x86/isa-level.c
===================================================================
--- glibc-2.33.orig/sysdeps/x86/isa-level.c
+++ glibc-2.33/sysdeps/x86/isa-level.c
@@ -29,32 +29,35 @@
/* ELF program property for x86 ISA level. */
#ifdef INCLUDE_X86_ISA_LEVEL
-# if defined __x86_64__ || defined __FXSR__ || !defined _SOFT_FLOAT \
- || defined __MMX__ || defined __SSE__ || defined __SSE2__
+# if defined __SSE__ && defined __SSE2__
+/* NB: ISAs, excluding MMX, in x86-64 ISA level baseline are used. */
# define ISA_BASELINE GNU_PROPERTY_X86_ISA_1_BASELINE
# else
# define ISA_BASELINE 0
# endif
-# if defined __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 \
- || (defined __x86_64__ && defined __LAHF_SAHF__) \
- || defined __POPCNT__ || defined __SSE3__ \
- || defined __SSSE3__ || defined __SSE4_1__ || defined __SSE4_2__
+# if ISA_BASELINE && defined __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 \
+ && defined HAVE_X86_LAHF_SAHF && defined __POPCNT__ \
+ && defined __SSE3__ && defined __SSSE3__ && defined __SSE4_1__ \
+ && defined __SSE4_2__
+/* NB: ISAs in x86-64 ISA level v2 are used. */
# define ISA_V2 GNU_PROPERTY_X86_ISA_1_V2
# else
# define ISA_V2 0
# endif
-# if defined __AVX__ || defined __AVX2__ || defined __F16C__ \
- || defined __FMA__ || defined __LZCNT__ || defined __MOVBE__ \
- || defined __XSAVE__
+# if ISA_V2 && defined __AVX__ && defined __AVX2__ && defined __F16C__ \
+ && defined __FMA__ && defined __LZCNT__ && defined HAVE_X86_MOVBE
+/* NB: ISAs in x86-64 ISA level v3 are used. */
# define ISA_V3 GNU_PROPERTY_X86_ISA_1_V3
# else
# define ISA_V3 0
# endif
-# if defined __AVX512F__ || defined __AVX512BW__ || defined __AVX512CD__ \
- || defined __AVX512DQ__ || defined __AVX512VL__
+# if ISA_V3 && defined __AVX512F__ && defined __AVX512BW__ \
+ && defined __AVX512CD__ && defined __AVX512DQ__ \
+ && defined __AVX512VL__
+/* NB: ISAs in x86-64 ISA level v4 are used. */
# define ISA_V4 GNU_PROPERTY_X86_ISA_1_V4
# else
# define ISA_V4 0