Skip to content

Commit

Permalink
libnss_tcb: Disallow potentially-malicious user names in getspnam(3).
Browse files Browse the repository at this point in the history
Signed-off-by: Björn Esser <[email protected]>
  • Loading branch information
besser82 committed Dec 20, 2024
1 parent 0f4837b commit 9dfddfc
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 2 deletions.
8 changes: 7 additions & 1 deletion ChangeLog
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
2021-12-18 Björn Esser <besser82 at fedoraproject.org>
2024-12-20 Björn Esser <besser82 at fedoraproject.org>

libnss_tcb: Disallow potentially-malicious user names in getspnam(3).
* libs/nss.c (_nss_tcb_getspnam_r): Check for potentially-malicious
user names, and bail out in case.

2024-12-18 Björn Esser <besser82 at fedoraproject.org>

libtcb: Add versioning to exported symbols.
This change is implemented for adding some interfaces to libtcb to
Expand Down
32 changes: 31 additions & 1 deletion libs/nss.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,30 @@ int _nss_tcb_endspent(void)
return 1;
}

/* 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 @.
The "$" sign is allowed at the end of usernames to allow typical
Samba machine accounts. */
static int
is_valid_username (const char *un)
{
if (!un || !*un || un[0] == '-' || un[0] == '@' ||
/* curdir || parentdir */
!strcmp(un, ".") || !strcmp(un, ".."))
return 0;

do {
char c = *un++;
if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9') || c == '-' || c == '.' ||
c == '@' || c == '_' || (!*un && c == '$')))
return 0;
} while (*un);

return 1;
}

static FILE *tcb_safe_open(const char *file, const char *name)
{
gid_t grplist[TCB_NGROUPS];
Expand Down Expand Up @@ -64,12 +88,18 @@ int _nss_tcb_getspnam_r(const char *name, struct spwd *__result_buf,
char *file;
int retval, saved_errno;

/* Disallow potentially-malicious user names */
if (!is_valid_username(name)) {
errno = ENOENT;
return NSS_STATUS_NOTFOUND;
}

if (asprintf(&file, TCB_FMT, name) < 0)
return NSS_STATUS_TRYAGAIN;
f = tcb_safe_open(file, name);
free(file);
if (!f)
return NSS_STATUS_UNAVAIL;
return errno == ENOENT ? NSS_STATUS_NOTFOUND : NSS_STATUS_UNAVAIL;

retval = fgetspent_r(f, __result_buf, __buffer, __buflen, __result);
saved_errno = errno;
Expand Down

0 comments on commit 9dfddfc

Please sign in to comment.