diff options
author | Ralph Boehme <slow@samba.org> | 2021-11-26 07:19:32 +0100 |
---|---|---|
committer | Jule Anger <janger@samba.org> | 2022-01-30 14:08:00 +0100 |
commit | b3b76222cfba5d162843b14b55570a02573c8ce8 (patch) | |
tree | 16605394f99b4f69ee13d998273517d316f23af7 | |
parent | 9eba87ce4b47488f1422248b8d4ad9b37ae26899 (diff) | |
download | samba-b3b76222cfba5d162843b14b55570a02573c8ce8.tar.gz |
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>
-rw-r--r-- | source3/lib/adouble.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/source3/lib/adouble.c b/source3/lib/adouble.c index 42b2e808d66..48621feb530 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; |