From b3cff5636bcf9fee23207dce5a34569912f4b1cb Mon Sep 17 00:00:00 2001 From: Douglas Bagnall Date: Wed, 12 Apr 2023 11:38:24 +1200 Subject: libcli/security: stricter identauth parsing We don't want octal numbers or overflows. Signed-off-by: Douglas Bagnall Reviewed-by: Andrew Bartlett --- libcli/security/dom_sid.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'libcli') diff --git a/libcli/security/dom_sid.c b/libcli/security/dom_sid.c index bcab0aec407..6cf7cc4d6d8 100644 --- a/libcli/security/dom_sid.c +++ b/libcli/security/dom_sid.c @@ -131,7 +131,8 @@ bool dom_sid_parse_endp(const char *sidstr,struct dom_sid *sidout, const char **endp) { const char *p; - char *q; + char *q = NULL; + char *end = NULL; uint64_t conv; int error = 0; @@ -158,12 +159,27 @@ bool dom_sid_parse_endp(const char *sidstr,struct dom_sid *sidout, if (!isdigit(*q)) { goto format_error; } + while (q[0] == '0' && isdigit((unsigned char)q[1])) { + /* + * strtoull will think this is octal, which is not how SIDs + * work! So let's walk along until there are no leading zeros + * (or a single zero). + */ + q++; + } /* get identauth */ - conv = smb_strtoull(q, &q, 0, &error, SMB_STR_STANDARD); + conv = smb_strtoull(q, &end, 0, &error, SMB_STR_STANDARD); if (conv & AUTHORITY_MASK || error != 0) { goto format_error; } + if (conv >= (1ULL << 48) || end - q > 15) { + /* + * This identauth looks like a big number, but resolves to a + * small number after rounding. + */ + goto format_error; + } /* NOTE - the conv value is in big-endian format. */ sidout->id_auth[0] = (conv & 0xff0000000000ULL) >> 40; @@ -174,6 +190,7 @@ bool dom_sid_parse_endp(const char *sidstr,struct dom_sid *sidout, sidout->id_auth[5] = (conv & 0x0000000000ffULL); sidout->num_auths = 0; + q = end; if (*q != '-') { /* Just id_auth, no subauths */ goto done; @@ -182,8 +199,6 @@ bool dom_sid_parse_endp(const char *sidstr,struct dom_sid *sidout, q++; while (true) { - char *end; - if (!isdigit(*q)) { goto format_error; } -- cgit v1.2.1