Skip to content

Commit b6ce07b

Browse files
besser82solardiz
authored andcommitted
libnss_tcb: Disallow potentially-malicious user names in getspnam(3).
IEEE Std 1003.1-2001 allows only the following characters to appear in group- and usernames: letters, digits, underscores, periods, <at>-signs (@), and dashes. The name may not start with a dash or an "@" sign. The "$" sign is allowed at the end of usernames to allow typical Samba machine accounts. Signed-off-by: Björn Esser <[email protected]>
1 parent 1264867 commit b6ce07b

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

ChangeLog

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
2024-12-20 Björn Esser <besser82 at fedoraproject.org>
2+
3+
libnss_tcb: Disallow potentially-malicious user names in getspnam(3).
4+
IEEE Std 1003.1-2001 allows only the following characters to appear
5+
in group- and usernames: letters, digits, underscores, periods,
6+
<at>-signs (@), and dashes. The name may not start with a dash or
7+
an "@" sign. The "$" sign is allowed at the end of usernames to
8+
allow typical Samba machine accounts.
9+
* libs/nss.c (_nss_tcb_getspnam_r): Check for potentially-malicious
10+
user names, and bail out in case.
11+
112
2024-12-18 Björn Esser <besser82 at fedoraproject.org>
213

314
libnss_tcb: Initialize or rewind dirstream from inside setspent(3).

libs/nss.c

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,31 @@ int _nss_tcb_endspent(void)
3636
return 1;
3737
}
3838

39+
/******************************************************************************
40+
IEEE Std 1003.1-2001 allows only the following characters to appear in group-
41+
and usernames: letters, digits, underscores, periods, <at>-signs (@), and
42+
dashes. The name may not start with a dash or an "@" sign. The "$" sign
43+
is allowed at the end of usernames to allow typical Samba machine accounts.
44+
******************************************************************************/
45+
static int
46+
is_valid_username (const char *un)
47+
{
48+
if (!un || !*un || un[0] == '-' || un[0] == '@' ||
49+
/* curdir || parentdir */
50+
!strcmp(un, ".") || !strcmp(un, ".."))
51+
return 0;
52+
53+
do {
54+
char c = *un++;
55+
if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
56+
(c >= '0' && c <= '9') || c == '-' || c == '.' ||
57+
c == '@' || c == '_' || (!*un && c == '$')))
58+
return 0;
59+
} while (*un);
60+
61+
return 1;
62+
}
63+
3964
static FILE *tcb_safe_open(const char *file, const char *name)
4065
{
4166
gid_t grplist[TCB_NGROUPS];
@@ -73,12 +98,18 @@ int _nss_tcb_getspnam_r(const char *name, struct spwd *__result_buf,
7398
char *file;
7499
int retval, saved_errno;
75100

101+
/* Disallow potentially-malicious user names */
102+
if (!is_valid_username(name)) {
103+
errno = ENOENT;
104+
return NSS_STATUS_NOTFOUND;
105+
}
106+
76107
if (asprintf(&file, TCB_FMT, name) < 0)
77108
return NSS_STATUS_TRYAGAIN;
78109
f = tcb_safe_open(file, name);
79110
free(file);
80111
if (!f)
81-
return NSS_STATUS_UNAVAIL;
112+
return errno == ENOENT ? NSS_STATUS_NOTFOUND : NSS_STATUS_UNAVAIL;
82113

83114
retval = fgetspent_r(f, __result_buf, __buffer, __buflen, __result);
84115
saved_errno = errno;

0 commit comments

Comments
 (0)