nss: use C locale for parsing nsswitch.conf (bug 33519)

The keywords in nsswitch.conf are ASCII-only, but some locales map ASCII
characters to non-ASCII characters in case conversion.
This commit is contained in:
Andreas Schwab 2025-10-08 12:26:18 +02:00
parent 3ee23564ce
commit 9da624a183
5 changed files with 70 additions and 12 deletions

View File

@ -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

View File

@ -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;

View File

@ -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>

View File

@ -0,0 +1 @@
root:x:0:

View File

@ -0,0 +1 @@
group: files [unavail=return]