From bb04d87aeffdfef86074a58fe348019856c8caec Mon Sep 17 00:00:00 2001 From: Daniel Markstedt Date: Wed, 6 May 2026 21:28:45 +0200 Subject: [PATCH] CVE-2026-44057,CVE-2026-44066: afpd: fix spotlight unmarshalling depth and dead check Reported-by: @00redbeer Signed-off-by: Daniel Markstedt --- etc/afpd/spotlight_marshalling.c | 46 +++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/etc/afpd/spotlight_marshalling.c b/etc/afpd/spotlight_marshalling.c index 362e95fba..92390ea52 100644 --- a/etc/afpd/spotlight_marshalling.c +++ b/etc/afpd/spotlight_marshalling.c @@ -71,7 +71,12 @@ static int sl_pack_loop(DALLOC_CTX *query, char *buf, int offset, char *toc_buf, int *toc_idx); static int sl_unpack_loop(DALLOC_CTX *query, const char *buf, int offset, - uint count, const uint toc_offset, const uint encoding); + uint count, const uint toc_offset, const uint encoding, + int depth); +static int sl_unpack_cpx(DALLOC_CTX *query, const char *buf, const int offset, + uint cpx_query_type, uint cpx_query_count, + const uint toc_offset, const uint encoding, int depth); +static int sl_unpack_r(DALLOC_CTX *query, const char *buf, int depth); /************************************************************************************************** * Wrapper functions for the *VAL macros with bound checking @@ -675,9 +680,15 @@ static int sl_unpack_cpx(DALLOC_CTX *query, uint cpx_query_type, uint cpx_query_count, const uint toc_offset, - const uint encoding) + const uint encoding, + int depth) { EC_INIT; + + if (depth >= SUBQ_SAFETY_LIM) { + EC_FAIL; + } + int roffset = offset; uint64_t query_data64; uint unicode_encoding; @@ -692,14 +703,14 @@ static int sl_unpack_cpx(DALLOC_CTX *query, case SQ_CPX_TYPE_ARRAY: sl_array = talloc_zero(query, sl_array_t); EC_NEG1_LOG(roffset = sl_unpack_loop(sl_array, buf, offset, cpx_query_count, - toc_offset, encoding)); + toc_offset, encoding, depth + 1)); dalloc_add(query, sl_array, sl_array_t); break; case SQ_CPX_TYPE_DICT: sl_dict = talloc_zero(query, sl_dict_t); EC_NEG1_LOG(roffset = sl_unpack_loop(sl_dict, buf, offset, cpx_query_count, - toc_offset, encoding)); + toc_offset, encoding, depth + 1)); dalloc_add(query, sl_dict, sl_dict_t); break; @@ -749,7 +760,7 @@ static int sl_unpack_cpx(DALLOC_CTX *query, EC_FAIL_LOG("SQ_CPX_TYPE_FILEMETA: query_length <= 8: %d", qlen); } else { sl_fm = talloc_zero(query, sl_filemeta_t); - EC_NEG1_LOG(sl_unpack(sl_fm, buf + offset + 8)); + EC_NEG1_LOG(sl_unpack_r(sl_fm, buf + offset + 8, depth + 1)); dalloc_add(query, sl_fm, sl_filemeta_t); } @@ -781,9 +792,15 @@ static int sl_unpack_loop(DALLOC_CTX *query, int offset, uint count, const uint toc_offset, - const uint encoding) + const uint encoding, + int depth) { EC_INIT; + + if (depth >= SUBQ_SAFETY_LIM) { + EC_FAIL; + } + int i, toc_index, query_length; uint subcount; uint64_t query_data64, query_type; @@ -807,7 +824,8 @@ static int sl_unpack_loop(DALLOC_CTX *query, cpx_query_type = (query_data64 & 0xffff0000) >> 16; cpx_query_count = query_data64 >> 32; EC_NEG1_LOG(offset = sl_unpack_cpx(query, buf, offset + 8, cpx_query_type, - cpx_query_count, toc_offset, encoding)); + cpx_query_count, toc_offset, encoding, + depth + 1)); count--; break; @@ -905,10 +923,10 @@ int sl_pack(DALLOC_CTX *query, char *buf) return len; } -int sl_unpack(DALLOC_CTX *query, const char *buf) +static int sl_unpack_r(DALLOC_CTX *query, const char *buf, int depth) { EC_INIT; - int encoding, toc_entries; + int encoding; uint64_t toc_offset; if (strncmp(buf, "md031234", 8) == 0) { @@ -920,13 +938,17 @@ int sl_unpack(DALLOC_CTX *query, const char *buf) buf += 8; toc_offset = ((sl_unpack_uint64(buf, 0, encoding) >> 32) - 1) * 8; - if (toc_offset < 0 || (toc_offset > 65000)) { + if (toc_offset > 65000) { EC_FAIL; } buf += 8; - toc_entries = (int)(sl_unpack_uint64(buf, toc_offset, encoding) & 0xffff); - EC_NEG1(sl_unpack_loop(query, buf, 0, 1, toc_offset + 8, encoding)); + EC_NEG1(sl_unpack_loop(query, buf, 0, 1, toc_offset + 8, encoding, depth)); EC_CLEANUP: EC_EXIT; } + +int sl_unpack(DALLOC_CTX *query, const char *buf) +{ + return sl_unpack_r(query, buf, 0); +}