From b4c0b4620f12055207adb0519c8d91c3021f354a Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow@samba.org>
Date: Fri, 26 Nov 2021 07:19:32 +0100
Subject: [PATCH 05/99] CVE-2021-44142: libadouble: harden ad_unpack_xattrs()

This ensures ad_unpack_xattrs() is only called for an ad_type of ADOUBLE_RSRC,
which is used for parsing ._ AppleDouble sidecar files, and the buffer
ad->ad_data is AD_XATTR_MAX_HDR_SIZE bytes large which is a prerequisite for all
buffer out-of-bounds access checks in ad_unpack_xattrs().

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14914

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
---
 source3/lib/adouble.c | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/source3/lib/adouble.c b/source3/lib/adouble.c
index f809a445081..6cbe8a5aeda 100644
--- a/source3/lib/adouble.c
+++ b/source3/lib/adouble.c
@@ -707,14 +707,27 @@ static bool ad_pack(struct vfs_handle_struct *handle,
 static bool ad_unpack_xattrs(struct adouble *ad)
 {
 	struct ad_xattr_header *h = &ad->adx_header;
+	size_t bufsize = talloc_get_size(ad->ad_data);
 	const char *p = ad->ad_data;
 	uint32_t hoff;
 	uint32_t i;
 
+	if (ad->ad_type != ADOUBLE_RSRC) {
+		return false;
+	}
+
 	if (ad_getentrylen(ad, ADEID_FINDERI) <= ADEDLEN_FINDERI) {
 		return true;
 	}
 
+	/*
+	 * Ensure the buffer ad->ad_data was allocated by ad_alloc() for an
+	 * ADOUBLE_RSRC type (._ AppleDouble file on-disk).
+	 */
+	if (bufsize != AD_XATTR_MAX_HDR_SIZE) {
+		return false;
+	}
+
 	/* 2 bytes padding */
 	hoff = ad_getentryoff(ad, ADEID_FINDERI) + ADEDLEN_FINDERI + 2;
 
@@ -964,9 +977,11 @@ static bool ad_unpack(struct adouble *ad, const size_t nentries,
 		ad->ad_eid[eid].ade_len = len;
 	}
 
-	ok = ad_unpack_xattrs(ad);
-	if (!ok) {
-		return false;
+	if (ad->ad_type == ADOUBLE_RSRC) {
+		ok = ad_unpack_xattrs(ad);
+		if (!ok) {
+			return false;
+		}
 	}
 
 	return true;
-- 
2.25.1
