From: Andreas Schwab Date: Wed, 8 Oct 2025 10:26:18 +0000 (+0200) Subject: nss: use C locale for parsing nsswitch.conf (bug 33519) X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9da624a1831998adcd3a9c9769ead0b255aff55d;p=thirdparty%2Fglibc.git 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. --- 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 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 + . */ + +#include +#include + +#include +#include + +/* 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 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]