1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-27 22:50:26 +03:00

vfs_fruit: unpack AppleDouble xattr header if present

Bug: https://bugzilla.samba.org/show_bug.cgi?id=13076

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
(cherry picked from commit fb137d6070c8cd872a66a4628b0e392cf40c180e)
This commit is contained in:
Ralph Boehme 2017-10-10 16:06:33 +02:00 committed by Karolin Seeger
parent 8d0359810b
commit f42c878313

View File

@ -648,6 +648,141 @@ static bool ad_pack(struct adouble *ad)
return true;
}
static bool ad_unpack_xattrs(struct adouble *ad)
{
struct ad_xattr_header *h = &ad->adx_header;
const char *p = ad->ad_data;
uint32_t hoff;
uint32_t i;
if (ad_getentrylen(ad, ADEID_FINDERI) <= ADEDLEN_FINDERI) {
return true;
}
/* 2 bytes padding */
hoff = ad_getentryoff(ad, ADEID_FINDERI) + ADEDLEN_FINDERI + 2;
h->adx_magic = RIVAL(p, hoff + 0);
h->adx_debug_tag = RIVAL(p, hoff + 4); /* Not used -> not checked */
h->adx_total_size = RIVAL(p, hoff + 8);
h->adx_data_start = RIVAL(p, hoff + 12);
h->adx_data_length = RIVAL(p, hoff + 16);
h->adx_flags = RSVAL(p, hoff + 32); /* Not used -> not checked */
h->adx_num_attrs = RSVAL(p, hoff + 34);
if (h->adx_magic != AD_XATTR_HDR_MAGIC) {
DBG_ERR("Bad magic: 0x%" PRIx32 "\n", h->adx_magic);
return false;
}
if (h->adx_total_size > ad_getentryoff(ad, ADEID_RFORK)) {
DBG_ERR("Bad total size: 0x%" PRIx32 "\n", h->adx_total_size);
return false;
}
if (h->adx_total_size > AD_XATTR_MAX_HDR_SIZE) {
DBG_ERR("Bad total size: 0x%" PRIx32 "\n", h->adx_total_size);
return false;
}
if (h->adx_data_start < (hoff + AD_XATTR_HDR_SIZE)) {
DBG_ERR("Bad start: 0x%" PRIx32 "\n", h->adx_data_start);
return false;
}
if ((h->adx_data_start + h->adx_data_length) < h->adx_data_start) {
DBG_ERR("Bad length: %" PRIu32 "\n", h->adx_data_length);
return false;
}
if ((h->adx_data_start + h->adx_data_length) >
ad->adx_header.adx_total_size)
{
DBG_ERR("Bad length: %" PRIu32 "\n", h->adx_data_length);
return false;
}
if (h->adx_num_attrs > AD_XATTR_MAX_ENTRIES) {
DBG_ERR("Bad num xattrs: %" PRIu16 "\n", h->adx_num_attrs);
return false;
}
if (h->adx_num_attrs == 0) {
return true;
}
ad->adx_entries = talloc_zero_array(
ad, struct ad_xattr_entry, h->adx_num_attrs);
if (ad->adx_entries == NULL) {
return false;
}
hoff += AD_XATTR_HDR_SIZE;
for (i = 0; i < h->adx_num_attrs; i++) {
struct ad_xattr_entry *e = &ad->adx_entries[i];
hoff = (hoff + 3) & ~3;
e->adx_offset = RIVAL(p, hoff + 0);
e->adx_length = RIVAL(p, hoff + 4);
e->adx_flags = RSVAL(p, hoff + 8);
e->adx_namelen = *(p + hoff + 10);
if (e->adx_offset >= ad->adx_header.adx_total_size) {
DBG_ERR("Bad adx_offset: %" PRIx32 "\n",
e->adx_offset);
return false;
}
if ((e->adx_offset + e->adx_length) < e->adx_offset) {
DBG_ERR("Bad adx_length: %" PRIx32 "\n",
e->adx_length);
return false;
}
if ((e->adx_offset + e->adx_length) >
ad->adx_header.adx_total_size)
{
DBG_ERR("Bad adx_length: %" PRIx32 "\n",
e->adx_length);
return false;
}
if (e->adx_namelen == 0) {
DBG_ERR("Bad adx_namelen: %" PRIx32 "\n",
e->adx_namelen);
return false;
}
if ((hoff + 11 + e->adx_namelen) < hoff + 11) {
DBG_ERR("Bad adx_namelen: %" PRIx32 "\n",
e->adx_namelen);
return false;
}
if ((hoff + 11 + e->adx_namelen) >
ad->adx_header.adx_data_start)
{
DBG_ERR("Bad adx_namelen: %" PRIx32 "\n",
e->adx_namelen);
return false;
}
e->adx_name = talloc_strndup(ad->adx_entries,
p + hoff + 11,
e->adx_namelen);
if (e->adx_name == NULL) {
return false;
}
DBG_DEBUG("xattr [%s] offset [0x%x] size [0x%x]\n",
e->adx_name, e->adx_offset, e->adx_length);
dump_data(10, (uint8_t *)(ad->ad_data + e->adx_offset),
e->adx_length);
hoff += 11 + e->adx_namelen;
}
return true;
}
/**
* Unpack an AppleDouble blob into a struct adoble
**/
@ -657,6 +792,7 @@ static bool ad_unpack(struct adouble *ad, const size_t nentries,
size_t bufsize = talloc_get_size(ad->ad_data);
size_t adentries, i;
uint32_t eid, len, off;
bool ok;
/*
* The size of the buffer ad->ad_data is checked when read, so
@ -770,6 +906,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;
}
return true;
}