[PATCH] nss: use C locale for parsing nsswitch.conf (bug 33519)
Andreas Schwab
schwab@suse.de
Wed Oct 8 11:29:42 GMT 2025
The keywords in nsswitch.conf are ASCII-only, but some locales map ASCII
charactes to non-ASCII characters in case conversion.
---
nss/Makefile | 6 +++
nss/nss_action_parse.c | 32 ++++++++------
nss/tst-nss-action-parse.c | 42 +++++++++++++++++++
nss/tst-nss-action-parse.root/etc/group | 1 +
.../etc/nsswitch.conf | 1 +
5 files changed, 70 insertions(+), 12 deletions(-)
create mode 100644 nss/tst-nss-action-parse.c
create mode 100644 nss/tst-nss-action-parse.root/etc/group
create mode 100644 nss/tst-nss-action-parse.root/etc/nsswitch.conf
diff --git a/nss/Makefile b/nss/Makefile
index 1991b7482a..96d9295778 100644
--- a/nss/Makefile
+++ b/nss/Makefile
@@ -356,6 +356,7 @@ tests-container := \
tst-nss-gai-actions \
tst-nss-gai-hv2-canonname \
tst-nss-test3 \
+ tst-nss-action-parse \
tst-reload1 \
tst-reload2 \
# tests-container
@@ -444,6 +445,9 @@ generated += mtrace-tst-nss-gai-hv2-canonname.out \
include ../Rules
+LOCALES := tr_TR.UTF-8
+include ../gen-locales.mk
+
ifeq (yes,$(have-selinux))
LDLIBS-makedb := -lselinux
endif
@@ -521,6 +525,8 @@ $(objpfx)mtrace-tst-nss-gai-hv2-canonname.out: \
$(objpfx)tst-nss-gai-hv2-canonname.mtrace; } > $@; \
$(evaluate-test)
+$(objpfx)tst-nss-action-parse.out: $(gen-locales)
+
# Disable DT_RUNPATH on NSS tests so that the glibc internal NSS
# functions can load testing NSS modules via DT_RPATH.
LDFLAGS-tst-nss-test1 = -Wl,--disable-new-dtags
diff --git a/nss/nss_action_parse.c b/nss/nss_action_parse.c
index ee3aadf312..cf55b7036b 100644
--- a/nss/nss_action_parse.c
+++ b/nss/nss_action_parse.c
@@ -48,7 +48,8 @@ nss_action_parse (const char *line, struct action_list *result)
/* Read <source> identifier. */
const char *name = line;
- while (line[0] != '\0' && !isspace (line[0]) && line[0] != '[')
+ while (line[0] != '\0' && !__isspace_l (line[0], _nl_C_locobj_ptr)
+ && line[0] != '[')
++line;
if (name == line)
return true;
@@ -88,25 +89,29 @@ nss_action_parse (const char *line, struct action_list *result)
/* Read status name. */
name = line;
- while (line[0] != '\0' && !isspace (line[0]) && line[0] != '='
- && line[0] != ']')
+ while (line[0] != '\0' && !__isspace_l (line[0], _nl_C_locobj_ptr)
+ && line[0] != '=' && line[0] != ']')
++line;
/* Compare with known statuses. */
if (line - name == 7)
{
- if (__strncasecmp (name, "SUCCESS", 7) == 0)
+ if (__strncasecmp_l (name, "SUCCESS", 7,
+ _nl_C_locobj_ptr) == 0)
status = NSS_STATUS_SUCCESS;
- else if (__strncasecmp (name, "UNAVAIL", 7) == 0)
+ else if (__strncasecmp_l (name, "UNAVAIL", 7,
+ _nl_C_locobj_ptr) == 0)
status = NSS_STATUS_UNAVAIL;
else
return false;
}
else if (line - name == 8)
{
- if (__strncasecmp (name, "NOTFOUND", 8) == 0)
+ if (__strncasecmp_l (name, "NOTFOUND", 8,
+ _nl_C_locobj_ptr) == 0)
status = NSS_STATUS_NOTFOUND;
- else if (__strncasecmp (name, "TRYAGAIN", 8) == 0)
+ else if (__strncasecmp_l (name, "TRYAGAIN", 8,
+ _nl_C_locobj_ptr) == 0)
status = NSS_STATUS_TRYAGAIN;
else
return false;
@@ -122,17 +127,20 @@ nss_action_parse (const char *line, struct action_list *result)
++line;
SKIP_WS ();
name = line;
- while (line[0] != '\0' && !isspace (line[0]) && line[0] != '='
- && line[0] != ']')
+ while (line[0] != '\0' && !__isspace_l (line[0], _nl_C_locobj_ptr)
+ && line[0] != '=' && line[0] != ']')
++line;
- if (line - name == 6 && __strncasecmp (name, "RETURN", 6) == 0)
+ if (line - name == 6
+ && __strncasecmp_l (name, "RETURN", 6, _nl_C_locobj_ptr) == 0)
action = NSS_ACTION_RETURN;
else if (line - name == 8
- && __strncasecmp (name, "CONTINUE", 8) == 0)
+ && __strncasecmp_l (name, "CONTINUE", 8,
+ _nl_C_locobj_ptr) == 0)
action = NSS_ACTION_CONTINUE;
else if (line - name == 5
- && __strncasecmp (name, "MERGE", 5) == 0)
+ && __strncasecmp_l (name, "MERGE", 5,
+ _nl_C_locobj_ptr) == 0)
action = NSS_ACTION_MERGE;
else
return false;
diff --git a/nss/tst-nss-action-parse.c b/nss/tst-nss-action-parse.c
new file mode 100644
index 0000000000..8c4a71085e
--- /dev/null
+++ b/nss/tst-nss-action-parse.c
@@ -0,0 +1,42 @@
+/* Test that the nsswitch.conf parser is locale agnostic.
+ Copyright (C) 2025 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 <locale.h>
+#include <grp.h>
+
+#include <support/support.h>
+#include <support/check.h>
+
+/* Test that the nsswitch.conf parser works correctly in a locale that
+ maps ASCII characters to non-ASCII characters in case conversion.
+ Bug #33519 */
+
+static int
+do_test (void)
+{
+ xsetlocale (LC_ALL, "tr_TR.UTF-8");
+
+ /* Trigger parsing of nsswitch.conf. If that fails then the use of any
+ NSS function will return an error. */
+ struct group *grp = getgrgid (0);
+ TEST_VERIFY (grp != NULL);
+
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/nss/tst-nss-action-parse.root/etc/group b/nss/tst-nss-action-parse.root/etc/group
new file mode 100644
index 0000000000..1dbf9013ee
--- /dev/null
+++ b/nss/tst-nss-action-parse.root/etc/group
@@ -0,0 +1 @@
+root:x:0:
diff --git a/nss/tst-nss-action-parse.root/etc/nsswitch.conf b/nss/tst-nss-action-parse.root/etc/nsswitch.conf
new file mode 100644
index 0000000000..4f5151f625
--- /dev/null
+++ b/nss/tst-nss-action-parse.root/etc/nsswitch.conf
@@ -0,0 +1 @@
+group: files [unavail=return]
--
2.51.0
--
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."
More information about the Libc-alpha
mailing list