summaryrefslogtreecommitdiff
path: root/libcli
diff options
context:
space:
mode:
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>2023-04-12 11:38:24 +1200
committerAndrew Bartlett <abartlet@samba.org>2023-04-28 02:15:36 +0000
commitb3cff5636bcf9fee23207dce5a34569912f4b1cb (patch)
treebd71f62d6462a8124a600a10277f66d22e3cef23 /libcli
parent6f37f8324c39336c111c1d519d25387f4cf1b434 (diff)
downloadsamba-b3cff5636bcf9fee23207dce5a34569912f4b1cb.tar.gz
libcli/security: stricter identauth parsing
We don't want octal numbers or overflows. Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'libcli')
-rw-r--r--libcli/security/dom_sid.c23
1 files changed, 19 insertions, 4 deletions
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;
}