From b3fb7b7837a0c057cdf2461ec3d0be9629b10e3b Mon Sep 17 00:00:00 2001 From: Andrew Walker Date: Tue, 12 Apr 2022 15:58:50 -0400 Subject: [PATCH] Fix crash while writing resource forks Variation of previous crashes fixed. In this case we generate a new_ad_header and immediately flush it. Convert intial fix to crashes via ad_entry() by initializing valid_data_len to AD_DATASZ2 or AD_DATASZ_EA, depending on how adouble files are stored. --- etc/afpd/directory.c | 2 -- etc/afpd/file.c | 2 -- libatalk/adouble/ad_flush.c | 6 +++++- libatalk/adouble/ad_open.c | 6 ++---- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/etc/afpd/directory.c b/etc/afpd/directory.c index 063eb6cf46c0..d53ce1e12af6 100644 --- a/etc/afpd/directory.c +++ b/etc/afpd/directory.c @@ -2218,8 +2218,6 @@ int afp_createdir(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_ if (ad_open(&ad, ".", ADFLAGS_HF | ADFLAGS_DIR | ADFLAGS_CREATE | ADFLAGS_RDWR, 0777) < 0) { return( AFPERR_ACCESS ); } - /* ad_refresh() so that valid_data_len is properly initialized */ - AFP_ASSERT(ad_refresh(upath, &ad) == 0); ad_setname(&ad, s_path->m_name); ad_setid( &ad, s_path->st.st_dev, s_path->st.st_ino, dir->d_did, did, vol->v_stamp); diff --git a/etc/afpd/file.c b/etc/afpd/file.c index 076aba93f81d..b2d926a70c5b 100644 --- a/etc/afpd/file.c +++ b/etc/afpd/file.c @@ -752,8 +752,6 @@ int afp_createfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, } path = s_path->m_name; - /* ad_refresh() so that valid_data_len is properly initialized */ - AFP_ASSERT(ad_refresh(path, &ad) == 0); ad_setname(&ad, path); struct stat st; diff --git a/libatalk/adouble/ad_flush.c b/libatalk/adouble/ad_flush.c index 0082110f101f..2f8aa72651c3 100644 --- a/libatalk/adouble/ad_flush.c +++ b/libatalk/adouble/ad_flush.c @@ -152,6 +152,7 @@ int ad_rebuild_adouble_header_osx(struct adouble *ad, char *adbuf) uint32_t temp; uint16_t nent; char *buf; + char *ade = NULL; LOG(log_debug, logtype_ad, "ad_rebuild_adouble_header_osx"); @@ -185,7 +186,10 @@ int ad_rebuild_adouble_header_osx(struct adouble *ad, char *adbuf) memcpy(buf, &temp, sizeof( temp )); buf += sizeof( temp ); - memcpy(adbuf + ADEDOFF_FINDERI_OSX, ad_entry(ad, ADEID_FINDERI), ADEDLEN_FINDERI); + ade = ad_entry(ad, ADEID_FINDERI); + AFP_ASSERT(ade != NULL); + + memcpy(adbuf + ADEDOFF_FINDERI_OSX, ade, ADEDLEN_FINDERI); /* rfork */ temp = htonl( EID_DISK(ADEID_RFORK) ); diff --git a/libatalk/adouble/ad_open.c b/libatalk/adouble/ad_open.c index 2a8b07c9a604..662c57c368da 100644 --- a/libatalk/adouble/ad_open.c +++ b/libatalk/adouble/ad_open.c @@ -361,14 +361,13 @@ static int new_ad_header(struct adouble *ad, const char *path, struct stat *stp, uint16_t ashort; struct stat st; char *adp = NULL; - size_t stored_valid_data_len = ad->valid_data_len; LOG(log_debug, logtype_ad, "new_ad_header(\"%s\")", path); if (ad_init_offsets(ad) != 0) return -1; - ad->valid_data_len = AD_DATASZ_MAX; + ad->valid_data_len = ad->ad_vers == AD_VERSION_EA ? AD_DATASZ_EA : AD_DATASZ2; adp = ad_entry(ad, ADEID_FINDERI); AFP_ASSERT(adp != NULL); @@ -391,7 +390,7 @@ static int new_ad_header(struct adouble *ad, const char *path, struct stat *stp, if (stp == NULL) { stp = &st; if (lstat(path, &st) != 0) { - ad->valid_data_len = stored_valid_data_len; + ad->valid_data_len = 0; return -1; } } @@ -400,7 +399,6 @@ static int new_ad_header(struct adouble *ad, const char *path, struct stat *stp, ad_setdate(ad, AD_DATE_ACCESS | AD_DATE_UNIX, stp->st_mtime); ad_setdate(ad, AD_DATE_BACKUP, AD_DATE_START); - ad->valid_data_len = stored_valid_data_len; return 0; }