diff --git a/net/netatalk3/Makefile b/net/netatalk3/Makefile index 87e0f5fd840f..71d081b6c62c 100644 --- a/net/netatalk3/Makefile +++ b/net/netatalk3/Makefile @@ -1,104 +1,104 @@ PORTNAME= netatalk PORTVERSION= 3.1.13 -PORTREVISION= 2 +PORTREVISION= 3 PORTEPOCH= 1 CATEGORIES= net MASTER_SITES= SF PKGNAMESUFFIX= 3 MAINTAINER= marcus@FreeBSD.org COMMENT= File server for Mac OS X WWW= http://netatalk.sourceforge.net/ LICENSE= GPLv2 LIB_DEPENDS= libgcrypt.so:security/libgcrypt \ libevent.so:devel/libevent USES= bdb:5+ cpe gettext gmake iconv libtool perl5 pkgconfig shebangfix ssl tar:bzip2 GNU_CONFIGURE= yes USE_LDCONFIG= yes USE_RC_SUBR= netatalk INSTALL_TARGET=install-strip CPE_VENDOR= netatalk_project CONFIGURE_ARGS+= --with-pkgconfdir=${PREFIX}/etc \ --with-libgcrypt-dir=${LOCALBASE} \ --with-uams-path=${PREFIX}/libexec/netatalk-uams \ --with-bdb=${LOCALBASE} \ ${ICONV_CONFIGURE_BASE} \ --localstatedir=/var \ --disable-bundled-libevent \ --with-libevent-header=${LOCALBASE}/include \ --with-libevent-lib=${LOCALBASE}/lib \ --with-ssl-dir=${OPENSSLBASE} \ --without-dtrace OPTIONS_DEFINE=PAM KERBEROS5 LDAP SENDFILE KERBEROS DBUS MYSQL ACL LIBWRAP OPTIONS_DEFAULT=AVAHI DBUS KERBEROS LIBWRAP OPTIONS_RADIO=ZEROCONF OPTIONS_RADIO_ZEROCONF=AVAHI MDNSRESPONDER ZEROCONF_DESC= Zeroconf(Bonjour) support MYSQL_DESC= Enable MySQL CNID backend support SENDFILE_DESC= Enable Sendfile support ACL_DESC= Enable ACL support OPTIONS_SUB= yes KERBEROS5_CONFIGURE_ON= --enable-krbV-uam KERBEROS_CONFIGURE_WITH=kerberos KERBEROS_LIB_DEPENDS=libgpg-error.so:security/libgpg-error PAM_CONFIGURE_WITH=pam AVAHI_CONFIGURE_ON= --enable-zeroconf=${LOCALBASE} AVAHI_CFLAGS= -I${LOCALBASE}/include -L${LOCALBASE}/lib AVAHI_LIB_DEPENDS= libavahi-client.so:net/avahi-app AVAHI_SUB_LIST= ZEROCONF="avahi_daemon" MDNSRESPONDER_CONFIGURE_ON= --enable-zeroconf=${LOCALBASE} MDNSRESPONDER_CONFIGURE_ENV= ac_cv_lib_avahi_client_avahi_client_new=no MDNSRESPONDER_CFLAGS= -I${LOCALBASE}/include -L${LOCALBASE}/lib MDNSRESPONDER_LIB_DEPENDS= libdns_sd.so:net/mDNSResponder MDNSRESPONDER_SUB_LIST= ZEROCONF="mdnsd" LDAP_CONFIGURE_ON= --with-ldap=${LOCALBASE} LDAP_CFLAGS= -I${LOCALBASE}/include -L${LOCALBASE}/lib LDAP_USE= OPENLDAP=yes LDAP_CONFIGURE_OFF= --without-ldap SENDFILE_CONFIGURE_ENABLE=sendfile DBUS_USES= gnome python DBUS_USE= GNOME=glib20 DBUS_LIB_DEPENDS= libdbus-glib-1.so:devel/dbus-glib \ libdbus-1.so:devel/dbus DBUS_RUN_DEPENDS= ${PYTHON_SITELIBDIR}/dbus/_dbus.py:devel/py-dbus@${PY_FLAVOR} MYSQL_USES= mysql MYSQL_CONFIGURE_OFF=--with-mysql-config=/nonexistent ACL_LIB_DEPENDS= libsunacl.so:sysutils/libsunacl ACL_CONFIGURE_WITH=acls LIBWRAP_CONFIGURE_ENABLE=tcp-wrappers SHEBANG_GLOB= afpstats CONFLICTS= jday yudit # bin/dbd man/man1/uniconv.1.gz .include .if ${PORT_OPTIONS:MAVAHI}=="" && ${PORT_OPTIONS:MMDNSRESPONDER}=="" SUB_LIST+= ZEROCONF="" CONFIGURE_ARGS+=--disable-zeroconf .endif post-patch: @${REINPLACE_CMD} -e 's|%%DB_NAME%%|${BDB_INCLUDE_DIR:T}| ; \ s|%%DB_LIB%%|-l${BDB_LIB_NAME}|g ; \ s|%%LOCALBASE%%|${LOCALBASE}|g' \ ${WRKSRC}/configure @${REINPLACE_CMD} -e 's|\.dist|\.sample|g' \ ${WRKSRC}/config/Makefile.in # @${REINPLACE_CMD} -e 's|%%PYTHONCMD%%|${PYTHONCMD}|' \ # ${WRKSRC}/contrib/shell_utils/afpstats post-install: ${INSTALL_SCRIPT} ${WRKSRC}/contrib/macusers/macusers \ ${STAGEDIR}${PREFIX}/bin/macusers .if ${PORT_OPTIONS:MPAM} ${INSTALL_DATA} ${FILESDIR}/pam.conf ${STAGEDIR}${PREFIX}/etc/pam.d/netatalk.sample .endif .include diff --git a/net/netatalk3/files/patch-configure b/net/netatalk3/files/patch-configure index 5b24b6253404..907721778bc7 100644 --- a/net/netatalk3/files/patch-configure +++ b/net/netatalk3/files/patch-configure @@ -1,11 +1,11 @@ ---- configure.orig 2016-09-12 09:54:34 UTC +--- configure.orig 2022-03-22 04:51:09 UTC +++ configure -@@ -17360,7 +17360,7 @@ if test "x$bdb_required" = "xyes"; then +@@ -17368,7 +17368,7 @@ if test "x$bdb_required" = "xyes"; then trybdbdir="" dobdbsearch=yes bdb_search_dirs="/usr/local /usr" - search_subdirs="/ /db6.1 /db6 /db5 /db5.3 /db5.2 /db5.1 /db51 /db5.0 /db50 /db4.8 /db48 /db4.7 /db47 /db4.6 /db46 /db4" -+ search_subdirs="/%%DB_NAME%% / /db6.1 /db6 /db5 /db5.3 /db5.2 /db5.1 /db51 /db5.0 /db50 /db4.8 /db48 /db4.7 /db47 /db4.6 /db46 /db4" ++ search_subdirs="/db5 / /db6.1 /db6 /db5 /db5.3 /db5.2 /db5.1 /db51 /db5.0 /db50 /db4.8 /db48 /db4.7 /db47 /db4.6 /db46 /db4" bdbfound=no savedcflags="$CFLAGS" diff --git a/net/netatalk3/files/patch-etc_afpd_directory.c b/net/netatalk3/files/patch-etc_afpd_directory.c new file mode 100644 index 000000000000..5383bc1d271b --- /dev/null +++ b/net/netatalk3/files/patch-etc_afpd_directory.c @@ -0,0 +1,53 @@ +--- etc/afpd/directory.c.orig 2022-02-28 13:32:06 UTC ++++ etc/afpd/directory.c +@@ -1426,6 +1426,7 @@ int getdirparams(const AFPObj *obj, + struct maccess ma; + struct adouble ad; + char *data, *l_nameoff = NULL, *utf_nameoff = NULL; ++ char *ade = NULL; + int bit = 0, isad = 0; + uint32_t aint; + uint16_t ashort; +@@ -1520,7 +1521,10 @@ int getdirparams(const AFPObj *obj, + + case DIRPBIT_FINFO : + if ( isad ) { +- memcpy( data, ad_entry( &ad, ADEID_FINDERI ), 32 ); ++ ade = ad_entry(&ad, ADEID_FINDERI); ++ AFP_ASSERT(ade != NULL); ++ ++ memcpy( data, ade, 32 ); + } else { /* no appledouble */ + memset( data, 0, 32 ); + /* dot files are by default visible */ +@@ -1744,6 +1748,7 @@ int setdirparams(struct vol *vol, struct path *path, u + struct timeval tv; + + char *upath; ++ char *ade = NULL; + struct dir *dir; + int bit, isad = 0; + int cdate, bdate; +@@ -1905,6 +1910,8 @@ int setdirparams(struct vol *vol, struct path *path, u + fflags &= htons(~FINDERINFO_ISHARED); + memcpy(finder_buf + FINDERINFO_FRFLAGOFF, &fflags, sizeof(uint16_t)); + /* #2802236 end */ ++ ade = ad_entry(&ad, ADEID_FINDERI); ++ AFP_ASSERT(ade != NULL); + + if ( dir->d_did == DIRDID_ROOT ) { + /* +@@ -1915,10 +1922,10 @@ int setdirparams(struct vol *vol, struct path *path, u + * behavior one sees when mounting above another mount + * point. + */ +- memcpy( ad_entry( &ad, ADEID_FINDERI ), finder_buf, 10 ); +- memcpy( ad_entry( &ad, ADEID_FINDERI ) + 14, finder_buf + 14, 18 ); ++ memcpy( ade, finder_buf, 10 ); ++ memcpy( ade + 14, finder_buf + 14, 18 ); + } else { +- memcpy( ad_entry( &ad, ADEID_FINDERI ), finder_buf, 32 ); ++ memcpy( ade, finder_buf, 32 ); + } + } + break; diff --git a/net/netatalk3/files/patch-etc_afpd_file.c b/net/netatalk3/files/patch-etc_afpd_file.c new file mode 100644 index 000000000000..db49f4c60a27 --- /dev/null +++ b/net/netatalk3/files/patch-etc_afpd_file.c @@ -0,0 +1,127 @@ +--- etc/afpd/file.c.orig 2022-02-28 13:32:06 UTC ++++ etc/afpd/file.c +@@ -296,6 +296,7 @@ int getmetadata(const AFPObj *obj, + { + char *data, *l_nameoff = NULL, *upath; + char *utf_nameoff = NULL; ++ char *ade = NULL; + int bit = 0; + uint32_t aint; + cnid_t id = 0; +@@ -497,8 +498,11 @@ int getmetadata(const AFPObj *obj, + } + else { + if ( adp ) { +- memcpy(fdType, ad_entry( adp, ADEID_FINDERI ), 4 ); ++ ade = ad_entry(adp, ADEID_FINDERI); ++ AFP_ASSERT(ade != NULL); + ++ memcpy(fdType, ade, 4); ++ + if ( memcmp( fdType, "TEXT", 4 ) == 0 ) { + achar = '\x04'; + ashort = 0x0000; +@@ -576,8 +580,19 @@ int getmetadata(const AFPObj *obj, + 10.3 clients freak out. */ + + aint = st->st_mode; +- if (adp) { +- memcpy(fdType, ad_entry( adp, ADEID_FINDERI ), 4 ); ++ /* ++ * ad_open() does not initialize adouble header ++ * for symlinks. Hence this should be skipped to ++ * avoid AFP_ASSERT here. Decision was made to ++ * not alter ad_open() behavior so that ++ * improper ops on symlink adoubles will be ++ * more visible (assert). ++ */ ++ if (adp && (ad_meta_fileno(adp) != AD_SYMLINK)) { ++ ade = ad_entry(adp, ADEID_FINDERI); ++ AFP_ASSERT(ade != NULL); ++ ++ memcpy(fdType, ade, 4); + if ( memcmp( fdType, "slnk", 4 ) == 0 ) { + aint |= S_IFLNK; + } +@@ -839,6 +854,7 @@ int setfilparams(const AFPObj *obj, struct vol *vol, + struct extmap *em; + int bit, isad = 1, err = AFP_OK; + char *upath; ++ char *ade = NULL; + u_char achar, *fdType, xyy[4]; /* uninitialized, OK 310105 */ + uint16_t ashort, bshort, oshort; + uint32_t aint; +@@ -989,7 +1005,7 @@ int setfilparams(const AFPObj *obj, struct vol *vol, + /* second try with adouble open + */ + if (ad_open(adp, upath, ADFLAGS_HF | ADFLAGS_RDWR | ADFLAGS_CREATE, 0666) < 0) { +- LOG(log_debug, logtype_afpd, "setfilparams: ad_open_metadata error"); ++ LOG(log_debug, logtype_afpd, "setfilparams: ad_open_metadata error: %s", strerror(errno)); + /* + * For some things, we don't need an adouble header: + * - change of modification date +@@ -1021,6 +1037,9 @@ int setfilparams(const AFPObj *obj, struct vol *vol, + + switch( bit ) { + case FILPBIT_ATTR : ++ if (isad == 0) { ++ break; ++ } + ad_getattr(adp, &bshort); + oshort = bshort; + if ( ntohs( ashort ) & ATTRBIT_SETCLR ) { +@@ -1034,15 +1053,26 @@ int setfilparams(const AFPObj *obj, struct vol *vol, + ad_setattr(adp, bshort); + break; + case FILPBIT_CDATE : ++ if (isad == 0) { ++ break; ++ } + ad_setdate(adp, AD_DATE_CREATE, cdate); + break; + case FILPBIT_MDATE : + break; + case FILPBIT_BDATE : ++ if (isad == 0) { ++ break; ++ } + ad_setdate(adp, AD_DATE_BACKUP, bdate); + break; + case FILPBIT_FINFO : +- if (default_type( ad_entry( adp, ADEID_FINDERI )) ++ if (isad == 0) { ++ break; ++ } ++ ade = ad_entry(adp, ADEID_FINDERI); ++ AFP_ASSERT(ade != NULL); ++ if (default_type(ade) + && ( + ((em = getextmap( path->m_name )) && + !memcmp(finder_buf, em->em_type, sizeof( em->em_type )) && +@@ -1053,7 +1083,7 @@ int setfilparams(const AFPObj *obj, struct vol *vol, + )) { + memcpy(finder_buf, ufinderi, 8 ); + } +- memcpy(ad_entry( adp, ADEID_FINDERI ), finder_buf, 32 ); ++ memcpy(ade, finder_buf, 32 ); + break; + case FILPBIT_UNIXPR : + if (upriv_bit) { +@@ -1061,9 +1091,15 @@ int setfilparams(const AFPObj *obj, struct vol *vol, + } + break; + case FILPBIT_PDINFO : ++ if (isad == 0) { ++ break; ++ } ++ ade = ad_entry(adp, ADEID_FINDERI); ++ AFP_ASSERT(ade != NULL); ++ + if (obj->afp_version < 30) { /* else it's UTF8 name */ +- memcpy(ad_entry( adp, ADEID_FINDERI ), fdType, 4 ); +- memcpy(ad_entry( adp, ADEID_FINDERI ) + 4, "pdos", 4 ); ++ memcpy(ade, fdType, 4 ); ++ memcpy(ade + 4, "pdos", 4 ); + break; + } + /* fallthrough */ diff --git a/net/netatalk3/files/patch-etc_afpd_volume.c b/net/netatalk3/files/patch-etc_afpd_volume.c index cc13c172a9bd..f7edbf34488c 100644 --- a/net/netatalk3/files/patch-etc_afpd_volume.c +++ b/net/netatalk3/files/patch-etc_afpd_volume.c @@ -1,20 +1,23 @@ ---- etc/afpd/volume.c.orig 2020-11-17 04:41:20 UTC +--- etc/afpd/volume.c.orig 2022-03-22 04:50:23 UTC +++ etc/afpd/volume.c -@@ -183,6 +183,7 @@ static int get_tm_used(struct vol * restrict vol) - - if ((bandsize = get_tm_bandsize(cfrombstr(infoplist))) == -1) { - bdestroy(infoplist); -+ infoplist = NULL; - continue; - } +@@ -305,6 +305,7 @@ static int getvolparams(const AFPObj *obj, uint16_t bi + VolSpace xbfree, xbtotal; /* extended bytes */ + char *data, *nameoff = NULL; + char *slash; ++ char *ade = NULL; -@@ -190,7 +191,9 @@ static int get_tm_used(struct vol * restrict vol) - - if ((links = get_tm_bands(cfrombstr(bandsdir))) == -1) { - bdestroy(infoplist); -+ infoplist = NULL; - bdestroy(bandsdir); -+ bandsdir = NULL; - continue; - } + LOG(log_debug, logtype_afpd, "getvolparams: Volume '%s'", vol->v_localname); +@@ -328,8 +329,10 @@ static int getvolparams(const AFPObj *obj, uint16_t bi + slash = vol->v_path; + if (ad_getentryoff(&ad, ADEID_NAME)) { + ad_setentrylen( &ad, ADEID_NAME, strlen( slash )); +- memcpy(ad_entry( &ad, ADEID_NAME ), slash, +- ad_getentrylen( &ad, ADEID_NAME )); ++ ade = ad_entry(&ad, ADEID_NAME); ++ AFP_ASSERT(ade != NULL); ++ ++ memcpy(ade, slash, ad_getentrylen( &ad, ADEID_NAME )); + } + vol_setdate(vol->v_vid, &ad, st->st_mtime); + ad_flush(&ad); diff --git a/net/netatalk3/files/patch-etc_cnid__dbd_cmd__dbd__scanvol.c b/net/netatalk3/files/patch-etc_cnid__dbd_cmd__dbd__scanvol.c new file mode 100644 index 000000000000..c1fba532eaac --- /dev/null +++ b/net/netatalk3/files/patch-etc_cnid__dbd_cmd__dbd__scanvol.c @@ -0,0 +1,25 @@ +--- etc/cnid_dbd/cmd_dbd_scanvol.c.orig 2022-02-28 13:32:06 UTC ++++ etc/cnid_dbd/cmd_dbd_scanvol.c +@@ -560,6 +560,7 @@ static int read_addir(void) + static cnid_t check_cnid(const char *name, cnid_t did, struct stat *st, int adfile_ok) + { + int adflags = ADFLAGS_HF; ++ int err; + cnid_t db_cnid, ad_cnid; + struct adouble ad; + +@@ -602,7 +603,13 @@ static cnid_t check_cnid(const char *name, cnid_t did, + cwdbuf, name, strerror(errno)); + return CNID_INVALID; + } +- ad_setid( &ad, st->st_dev, st->st_ino, db_cnid, did, stamp); ++ err = ad_setid( &ad, st->st_dev, st->st_ino, db_cnid, did, stamp); ++ if (err == -1) { ++ dbd_log(LOGSTD, "Error setting new CNID, malformed adouble: '%s/%s'", ++ cwdbuf, name); ++ ad_close(&ad, ADFLAGS_HF); ++ return CNID_INVALID; ++ } + ad_flush(&ad); + ad_close(&ad, ADFLAGS_HF); + } diff --git a/net/netatalk3/files/patch-libatalk_adouble_ad__attr.c b/net/netatalk3/files/patch-libatalk_adouble_ad__attr.c new file mode 100644 index 000000000000..cafffaed5987 --- /dev/null +++ b/net/netatalk3/files/patch-libatalk_adouble_ad__attr.c @@ -0,0 +1,234 @@ +--- libatalk/adouble/ad_attr.c.orig 2022-02-28 13:32:06 UTC ++++ libatalk/adouble/ad_attr.c +@@ -2,8 +2,10 @@ + #include "config.h" + #endif /* HAVE_CONFIG_H */ + ++#include + #include + #include ++#include + #include + #include + +@@ -22,10 +24,17 @@ int ad_getattr(const struct adouble *ad, uint16_t *att + *attr = 0; + + if (ad_getentryoff(ad, ADEID_AFPFILEI)) { +- memcpy(attr, ad_entry(ad, ADEID_AFPFILEI) + AFPFILEIOFF_ATTR, 2); ++ char *adp = NULL; + ++ adp = ad_entry(ad, ADEID_AFPFILEI); ++ AFP_ASSERT(adp != NULL); ++ memcpy(attr, adp + AFPFILEIOFF_ATTR, 2); ++ + /* Now get opaque flags from FinderInfo */ +- memcpy(&fflags, ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF, 2); ++ adp = ad_entry(ad, ADEID_FINDERI); ++ AFP_ASSERT(adp != NULL); ++ memcpy(&fflags, adp + FINDERINFO_FRFLAGOFF, 2); ++ + if (fflags & htons(FINDERINFO_INVISIBLE)) + *attr |= htons(ATTRBIT_INVISIBLE); + else +@@ -61,10 +70,15 @@ int ad_setattr(const struct adouble *ad, const uint16_ + attr &= ~(ATTRBIT_MULTIUSER | ATTRBIT_NOWRITE | ATTRBIT_NOCOPY); + + if (ad_getentryoff(ad, ADEID_AFPFILEI) && ad_getentryoff(ad, ADEID_FINDERI)) { +- memcpy(ad_entry(ad, ADEID_AFPFILEI) + AFPFILEIOFF_ATTR, &attr, sizeof(attr)); ++ char *adp = NULL; ++ ++ adp = ad_entry(ad, ADEID_FINDERI); ++ AFP_ASSERT(adp != NULL); ++ ++ memcpy(adp + AFPFILEIOFF_ATTR, &attr, sizeof(attr)); + + /* Now set opaque flags in FinderInfo too */ +- memcpy(&fflags, ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF, 2); ++ memcpy(&fflags, adp + FINDERINFO_FRFLAGOFF, 2); + if (attr & htons(ATTRBIT_INVISIBLE)) + fflags |= htons(FINDERINFO_INVISIBLE); + else +@@ -77,7 +91,7 @@ int ad_setattr(const struct adouble *ad, const uint16_ + } else + fflags &= htons(~FINDERINFO_ISHARED); + +- memcpy(ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF, &fflags, 2); ++ memcpy(adp + FINDERINFO_FRFLAGOFF, &fflags, 2); + } + + return 0; +@@ -86,54 +100,114 @@ int ad_setattr(const struct adouble *ad, const uint16_ + /* -------------- + * save file/folder ID in AppleDoubleV2 netatalk private parameters + * return 1 if resource fork has been modified ++ * return -1 on error. + */ + int ad_setid (struct adouble *adp, const dev_t dev, const ino_t ino , const uint32_t id, const cnid_t did, const void *stamp) + { + uint32_t tmp; ++ char *ade = NULL; + + ad_setentrylen( adp, ADEID_PRIVID, sizeof(id)); + tmp = id; + if (adp->ad_vers == AD_VERSION_EA) + tmp = htonl(tmp); +- memcpy(ad_entry( adp, ADEID_PRIVID ), &tmp, sizeof(tmp)); + ++ ade = ad_entry(adp, ADEID_PRIVID); ++ if (ade == NULL) { ++ LOG(log_warning, logtype_ad, "ad_setid: failed to set ADEID_PRIVID\n"); ++ return -1; ++ } ++ memcpy(ade, &tmp, sizeof(tmp)); ++ + ad_setentrylen( adp, ADEID_PRIVDEV, sizeof(dev_t)); ++ ade = ad_entry(adp, ADEID_PRIVDEV); ++ if (ade == NULL) { ++ LOG(log_warning, logtype_ad, "ad_setid: failed to set ADEID_PRIVDEV\n"); ++ return -1; ++ } ++ + if ((adp->ad_options & ADVOL_NODEV)) { +- memset(ad_entry( adp, ADEID_PRIVDEV ), 0, sizeof(dev_t)); ++ memset(ade, 0, sizeof(dev_t)); + } else { +- memcpy(ad_entry( adp, ADEID_PRIVDEV ), &dev, sizeof(dev_t)); ++ memcpy(ade, &dev, sizeof(dev_t)); + } + + ad_setentrylen( adp, ADEID_PRIVINO, sizeof(ino_t)); +- memcpy(ad_entry( adp, ADEID_PRIVINO ), &ino, sizeof(ino_t)); + +- ad_setentrylen( adp, ADEID_DID, sizeof(did)); +- memcpy(ad_entry( adp, ADEID_DID ), &did, sizeof(did)); ++ ade = ad_entry(adp, ADEID_PRIVINO); ++ if (ade == NULL) { ++ LOG(log_warning, logtype_ad, "ad_setid: failed to set ADEID_PRIVINO\n"); ++ return -1; ++ } ++ memcpy(ade, &ino, sizeof(ino_t)); + ++ if (adp->ad_vers != AD_VERSION_EA) { ++ ad_setentrylen( adp, ADEID_DID, sizeof(did)); ++ ++ ade = ad_entry(adp, ADEID_DID); ++ if (ade == NULL) { ++ LOG(log_warning, logtype_ad, "ad_setid: failed to set ADEID_DID\n"); ++ return -1; ++ } ++ memcpy(ade, &did, sizeof(did)); ++ } ++ + ad_setentrylen( adp, ADEID_PRIVSYN, ADEDLEN_PRIVSYN); +- memcpy(ad_entry( adp, ADEID_PRIVSYN ), stamp, ADEDLEN_PRIVSYN); ++ ade = ad_entry(adp, ADEID_PRIVSYN); ++ if (ade == NULL) { ++ LOG(log_warning, logtype_ad, "ad_setid: failed to set ADEID_PRIVSYN\n"); ++ return -1; ++ } ++ memcpy(ade, stamp, ADEDLEN_PRIVSYN); + + return 1; + } + +-/* ----------------------------- */ ++/* ++ * Retrieve stored file / folder. Callers should treat a return of CNID_INVALID (0) as an invalid value. ++ */ + uint32_t ad_getid (struct adouble *adp, const dev_t st_dev, const ino_t st_ino , const cnid_t did, const void *stamp _U_) + { + uint32_t aint = 0; + dev_t dev; + ino_t ino; +- cnid_t a_did; ++ cnid_t a_did = 0; + + if (adp) { + if (sizeof(dev_t) == ad_getentrylen(adp, ADEID_PRIVDEV)) { +- memcpy(&dev, ad_entry(adp, ADEID_PRIVDEV), sizeof(dev_t)); +- memcpy(&ino, ad_entry(adp, ADEID_PRIVINO), sizeof(ino_t)); +- memcpy(&a_did, ad_entry(adp, ADEID_DID), sizeof(cnid_t)); ++ char *ade = NULL; ++ ade = ad_entry(adp, ADEID_PRIVDEV); ++ if (ade == NULL) { ++ LOG(log_warning, logtype_ad, "ad_getid: failed to retrieve ADEID_PRIVDEV\n"); ++ return CNID_INVALID; ++ } ++ memcpy(&dev, ade, sizeof(dev_t)); ++ ade = ad_entry(adp, ADEID_PRIVINO); ++ if (ade == NULL) { ++ LOG(log_warning, logtype_ad, "ad_getid: failed to retrieve ADEID_PRIVINO\n"); ++ return CNID_INVALID; ++ } ++ memcpy(&ino, ade, sizeof(ino_t)); + ++ if (adp->ad_vers != AD_VERSION_EA) { ++ /* ADEID_DID is not stored for AD_VERSION_EA */ ++ ade = ad_entry(adp, ADEID_DID); ++ if (ade == NULL) { ++ LOG(log_warning, logtype_ad, "ad_getid: failed to retrieve ADEID_DID\n"); ++ return CNID_INVALID; ++ } ++ memcpy(&a_did, ade, sizeof(cnid_t)); ++ } ++ + if (((adp->ad_options & ADVOL_NODEV) || (dev == st_dev)) + && ino == st_ino +- && (!did || a_did == did) ) { +- memcpy(&aint, ad_entry(adp, ADEID_PRIVID), sizeof(aint)); ++ && (!did || a_did == 0 || a_did == did) ) { ++ ade = ad_entry(adp, ADEID_PRIVID); ++ if (ade == NULL) { ++ LOG(log_warning, logtype_ad, "ad_getid: failed to retrieve ADEID_PRIVID\n"); ++ return CNID_INVALID; ++ } ++ memcpy(&aint, ade, sizeof(aint)); + if (adp->ad_vers == AD_VERSION2) + return aint; + else +@@ -141,7 +215,7 @@ uint32_t ad_getid (struct adouble *adp, const dev_t st + } + } + } +- return 0; ++ return CNID_INVALID; + } + + /* ----------------------------- */ +@@ -150,13 +224,18 @@ uint32_t ad_forcegetid (struct adouble *adp) + uint32_t aint = 0; + + if (adp) { +- memcpy(&aint, ad_entry(adp, ADEID_PRIVID), sizeof(aint)); ++ char *ade = NULL; ++ ade = ad_entry(adp, ADEID_PRIVID); ++ if (ade == NULL) { ++ return CNID_INVALID; ++ } ++ memcpy(&aint, ade, sizeof(aint)); + if (adp->ad_vers == AD_VERSION2) + return aint; + else + return ntohl(aint); + } +- return 0; ++ return CNID_INVALID; + } + + /* ----------------- +@@ -168,8 +247,13 @@ int ad_setname(struct adouble *ad, const char *path) + if ((len = strlen(path)) > ADEDLEN_NAME) + len = ADEDLEN_NAME; + if (path && ad_getentryoff(ad, ADEID_NAME)) { ++ char *ade = NULL; + ad_setentrylen( ad, ADEID_NAME, len); +- memcpy(ad_entry( ad, ADEID_NAME ), path, len); ++ ade = ad_entry(ad, ADEID_NAME); ++ if (ade == NULL) { ++ return -1; ++ } ++ memcpy(ade, path, len); + return 1; + } + return 0; diff --git a/net/netatalk3/files/patch-libatalk_adouble_ad__conv.c b/net/netatalk3/files/patch-libatalk_adouble_ad__conv.c new file mode 100644 index 000000000000..e2369bc9df20 --- /dev/null +++ b/net/netatalk3/files/patch-libatalk_adouble_ad__conv.c @@ -0,0 +1,27 @@ +--- libatalk/adouble/ad_conv.c.orig 2022-02-28 13:32:06 UTC ++++ libatalk/adouble/ad_conv.c +@@ -93,6 +93,7 @@ static int ad_conv_v22ea_hf(const char *path, const st + goto copy; + if (ad_getentryoff(&adv2, ADEID_FINDERI) + && (ad_getentrylen(&adv2, ADEID_FINDERI) == ADEDLEN_FINDERI) ++ && (ad_entry(&adv2, ADEID_FINDERI) != NULL) + && (memcmp(ad_entry(&adv2, ADEID_FINDERI), emptyad, ADEDLEN_FINDERI) != 0)) + goto copy; + if (ad_getentryoff(&adv2, ADEID_FILEDATESI)) { +@@ -101,7 +102,7 @@ static int ad_conv_v22ea_hf(const char *path, const st + if ((ctime != mtime) || (mtime != sp->st_mtime)) + goto copy; + } +- if (ad_getentryoff(&adv2, ADEID_AFPFILEI)) { ++ if (ad_getentryoff(&adv2, ADEID_AFPFILEI) && (ad_entry(&adv2, ADEID_AFPFILEI) != NULL)) { + if (memcmp(ad_entry(&adv2, ADEID_AFPFILEI), &afpinfo, ADEDLEN_AFPFILEI) != 0) + goto copy; + } +@@ -115,6 +116,7 @@ copy: + EC_ZERO_LOGSTR( ad_open(&adea, path, adflags | ADFLAGS_HF | ADFLAGS_RDWR | ADFLAGS_CREATE), + "ad_conv_v22ea_hf(\"%s\"): error creating metadata EA: %s", + fullpathname(path), strerror(errno)); ++ AFP_ASSERT(ad_refresh(path, &adea) == 0); + EC_ZERO_LOG( ad_copy_header(&adea, &adv2) ); + ad_flush(&adea); + diff --git a/net/netatalk3/files/patch-libatalk_adouble_ad__date.c b/net/netatalk3/files/patch-libatalk_adouble_ad__date.c new file mode 100644 index 000000000000..2b0d129cd7e8 --- /dev/null +++ b/net/netatalk3/files/patch-libatalk_adouble_ad__date.c @@ -0,0 +1,48 @@ +--- libatalk/adouble/ad_date.c.orig 2022-02-28 13:32:06 UTC ++++ libatalk/adouble/ad_date.c +@@ -10,6 +10,7 @@ int ad_setdate(struct adouble *ad, + unsigned int dateoff, uint32_t date) + { + int xlate = (dateoff & AD_DATE_UNIX); ++ char *ade = NULL; + + dateoff &= AD_DATE_MASK; + if (xlate) +@@ -20,8 +21,13 @@ int ad_setdate(struct adouble *ad, + + if (dateoff > AD_DATE_ACCESS) + return -1; +- memcpy(ad_entry(ad, ADEID_FILEDATESI) + dateoff, &date, sizeof(date)); + ++ ade = ad_entry(ad, ADEID_FILEDATESI); ++ if (ade == NULL) { ++ return -1; ++ } ++ memcpy(ade + dateoff, &date, sizeof(date)); ++ + return 0; + } + +@@ -29,6 +35,7 @@ int ad_getdate(const struct adouble *ad, + unsigned int dateoff, uint32_t *date) + { + int xlate = (dateoff & AD_DATE_UNIX); ++ char *ade = NULL; + + dateoff &= AD_DATE_MASK; + if (!ad_getentryoff(ad, ADEID_FILEDATESI)) +@@ -36,7 +43,13 @@ int ad_getdate(const struct adouble *ad, + + if (dateoff > AD_DATE_ACCESS) + return -1; +- memcpy(date, ad_entry(ad, ADEID_FILEDATESI) + dateoff, sizeof(uint32_t)); ++ ++ ++ ade = ad_entry(ad, ADEID_FILEDATESI); ++ if (ade == NULL) { ++ return -1; ++ } ++ memcpy(date, ade + dateoff, sizeof(uint32_t)); + + if (xlate) + *date = AD_DATE_TO_UNIX(*date); diff --git a/net/netatalk3/files/patch-libatalk_adouble_ad__flush.c b/net/netatalk3/files/patch-libatalk_adouble_ad__flush.c new file mode 100644 index 000000000000..032c0b3d6656 --- /dev/null +++ b/net/netatalk3/files/patch-libatalk_adouble_ad__flush.c @@ -0,0 +1,68 @@ +--- libatalk/adouble/ad_flush.c.orig 2022-03-22 04:50:23 UTC ++++ libatalk/adouble/ad_flush.c +@@ -151,6 +151,7 @@ int ad_rebuild_adouble_header_osx(struct adouble *ad, + uint32_t temp; + uint16_t nent; + char *buf; ++ char *ade = NULL; + + LOG(log_debug, logtype_ad, "ad_rebuild_adouble_header_osx"); + +@@ -184,8 +185,11 @@ int ad_rebuild_adouble_header_osx(struct adouble *ad, + 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) ); + memcpy(buf, &temp, sizeof( temp )); +@@ -211,8 +215,12 @@ int ad_copy_header(struct adouble *add, struct adouble + { + uint32_t eid; + uint32_t len; ++ char *src = NULL; ++ char *dst = NULL; + + for ( eid = 0; eid < ADEID_MAX; eid++ ) { ++ src = dst = NULL; ++ + if ( ads->ad_eid[ eid ].ade_off == 0 || add->ad_eid[ eid ].ade_off == 0 ) + continue; + +@@ -226,17 +234,28 @@ int ad_copy_header(struct adouble *add, struct adouble + continue; + default: + ad_setentrylen( add, eid, len ); +- memcpy( ad_entry( add, eid ), ad_entry( ads, eid ), len ); ++ dst = ad_entry(add, eid); ++ AFP_ASSERT(dst != NULL); ++ ++ src = ad_entry(ads, eid); ++ AFP_ASSERT(src != NULL); ++ ++ memcpy( dst, src, len ); + } + } + add->ad_rlen = ads->ad_rlen; + + if (((ads->ad_vers == AD_VERSION2) && (add->ad_vers == AD_VERSION_EA)) + || ((ads->ad_vers == AD_VERSION_EA) && (add->ad_vers == AD_VERSION2))) { ++ src = dst = NULL; + cnid_t id; +- memcpy(&id, ad_entry(add, ADEID_PRIVID), sizeof(cnid_t)); ++ ++ dst = ad_entry(add, ADEID_PRIVID); ++ AFP_ASSERT(dst != NULL); ++ ++ memcpy(&id, dst, sizeof(cnid_t)); + id = htonl(id); +- memcpy(ad_entry(add, ADEID_PRIVID), &id, sizeof(cnid_t)); ++ memcpy(dst, &id, sizeof(cnid_t)); + } + return 0; + } diff --git a/net/netatalk3/files/patch-libatalk_adouble_ad__open.c b/net/netatalk3/files/patch-libatalk_adouble_ad__open.c index 9a704469a6de..a5a279834158 100644 --- a/net/netatalk3/files/patch-libatalk_adouble_ad__open.c +++ b/net/netatalk3/files/patch-libatalk_adouble_ad__open.c @@ -1,84 +1,97 @@ --- libatalk/adouble/ad_open.c.orig 2022-03-22 04:44:25 UTC +++ libatalk/adouble/ad_open.c -@@ -1574,6 +1574,8 @@ static bool ad_entry_check_size(uint32_t eid, - uint32_t required_len; +@@ -140,17 +140,17 @@ static struct adouble_fops ad_adouble_ea = { - if (eid >= ADEID_MAX) { -+ LOG(log_error, logtype_ad, "ad_entry_check_size %d is greater than %d", -+ eid, ADEID_MAX); - return false; - } - if (got_len == 0) { -@@ -1585,6 +1587,7 @@ static bool ad_entry_check_size(uint32_t eid, - * Shouldn't happen: implicitly initialized to zero because - * explicit initializer missing. - */ -+ LOG(log_error, logtype_ad, "ad_entry_check_size explicit initializer missing"); - return false; - } - if (ad_checks[eid].expected_len == -1) { -@@ -1594,6 +1597,8 @@ static bool ad_entry_check_size(uint32_t eid, - if (ad_checks[eid].fixed_size) { - if (ad_checks[eid].expected_len != got_len) { - /* Wrong size fo fixed size entry. */ -+ LOG(log_error, logtype_ad, "ad_entry_check_size wrong size to fixed size entry (%d != %d)", -+ ad_checks[eid].expected_len, got_len); - return false; - } - required_len = got_len; -@@ -1604,12 +1609,16 @@ static bool ad_entry_check_size(uint32_t eid, - * Too small for variable sized entry with - * minimum size. - */ -+ LOG(log_error, logtype_ad, "ad_entry_check_size too small for variable sized entry (%d < %d)", -+ got_len, ad_checks[eid].expected_len); - return false; - } - required_len = got_len; - } else { - if (got_len > ad_checks[eid].expected_len) { - /* Too big for variable sized entry. */ -+ LOG(log_error, logtype_ad, "ad_entry_check_size too big for variable sized entry (%d > %d)", -+ got_len, ad_checks[eid].expected_len); - return false; - } - /* -@@ -1621,10 +1630,14 @@ static bool ad_entry_check_size(uint32_t eid, - } - if (off + required_len < off) { - /* wrap around */ -+ LOG(log_error, logtype_ad, "ad_entry_check_size wrap around (%d + %d < %d)", -+ off, required_len, off); - return false; - } - if (off + required_len > bufsize) { - /* overflow */ -+ LOG(log_error, logtype_ad, "ad_entry_check_size overflow (%d + %d > %d)", -+ off, required_len, bufsize); - return false; - } - return true; -@@ -1637,14 +1650,21 @@ void *ad_entry(const struct adouble *ad, int eid) - size_t len = ad_getentrylen(ad, eid); - bool valid; + static const struct entry entry_order2[ADEID_NUM_V2 + 1] = { + {ADEID_NAME, ADEDOFF_NAME_V2, ADEDLEN_INIT}, +- {ADEID_COMMENT, ADEDOFF_COMMENT_V2, ADEDLEN_INIT}, ++ {ADEID_COMMENT, ADEDOFF_COMMENT_V2, ADEDLEN_COMMENT}, + {ADEID_FILEDATESI, ADEDOFF_FILEDATESI, ADEDLEN_FILEDATESI}, + {ADEID_FINDERI, ADEDOFF_FINDERI_V2, ADEDLEN_FINDERI}, + {ADEID_DID, ADEDOFF_DID, ADEDLEN_DID}, + {ADEID_AFPFILEI, ADEDOFF_AFPFILEI, ADEDLEN_AFPFILEI}, + {ADEID_SHORTNAME, ADEDOFF_SHORTNAME, ADEDLEN_INIT}, + {ADEID_PRODOSFILEI, ADEDOFF_PRODOSFILEI, ADEDLEN_PRODOSFILEI}, +- {ADEID_PRIVDEV, ADEDOFF_PRIVDEV, ADEDLEN_INIT}, +- {ADEID_PRIVINO, ADEDOFF_PRIVINO, ADEDLEN_INIT}, +- {ADEID_PRIVSYN, ADEDOFF_PRIVSYN, ADEDLEN_INIT}, +- {ADEID_PRIVID, ADEDOFF_PRIVID, ADEDLEN_INIT}, ++ {ADEID_PRIVDEV, ADEDOFF_PRIVDEV, ADEDLEN_PRIVDEV}, ++ {ADEID_PRIVINO, ADEDOFF_PRIVINO, ADEDLEN_PRIVINO}, ++ {ADEID_PRIVSYN, ADEDOFF_PRIVSYN, ADEDLEN_PRIVSYN}, ++ {ADEID_PRIVID, ADEDOFF_PRIVID, ADEDLEN_PRIVID}, + {ADEID_RFORK, ADEDOFF_RFORK_V2, ADEDLEN_INIT}, + {0, 0, 0} + }; +@@ -158,13 +158,13 @@ static const struct entry entry_order2[ADEID_NUM_V2 + + /* Using Extended Attributes */ + static const struct entry entry_order_ea[ADEID_NUM_EA + 1] = { + {ADEID_FINDERI, ADEDOFF_FINDERI_EA, ADEDLEN_FINDERI}, +- {ADEID_COMMENT, ADEDOFF_COMMENT_EA, ADEDLEN_INIT}, ++ {ADEID_COMMENT, ADEDOFF_COMMENT_EA, ADEDLEN_COMMENT}, + {ADEID_FILEDATESI, ADEDOFF_FILEDATESI_EA, ADEDLEN_FILEDATESI}, + {ADEID_AFPFILEI, ADEDOFF_AFPFILEI_EA, ADEDLEN_AFPFILEI}, +- {ADEID_PRIVDEV, ADEDOFF_PRIVDEV_EA, ADEDLEN_INIT}, +- {ADEID_PRIVINO, ADEDOFF_PRIVINO_EA, ADEDLEN_INIT}, +- {ADEID_PRIVSYN, ADEDOFF_PRIVSYN_EA, ADEDLEN_INIT}, +- {ADEID_PRIVID, ADEDOFF_PRIVID_EA, ADEDLEN_INIT}, ++ {ADEID_PRIVDEV, ADEDOFF_PRIVDEV_EA, ADEDLEN_PRIVDEV}, ++ {ADEID_PRIVINO, ADEDOFF_PRIVINO_EA, ADEDLEN_PRIVINO}, ++ {ADEID_PRIVSYN, ADEDOFF_PRIVSYN_EA, ADEDLEN_PRIVSYN}, ++ {ADEID_PRIVID, ADEDOFF_PRIVID_EA, ADEDLEN_PRIVID}, + {0, 0, 0} + }; -+ if (bufsize == 0) { -+ bufsize = sizeof(ad->ad_data) - (off + len); -+ } +@@ -360,15 +360,22 @@ static int new_ad_header(struct adouble *ad, const cha + const struct entry *eid; + uint16_t ashort; + struct stat st; ++ char *adp = NULL; + + LOG(log_debug, logtype_ad, "new_ad_header(\"%s\")", path); + + if (ad_init_offsets(ad) != 0) + return -1; + ++ if (ad->valid_data_len == 0) { ++ 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); + - valid = ad_entry_check_size(eid, bufsize, off, len); - if (!valid) { -+ LOG(log_error, logtype_ad, "ad_entry: not valid"); - return NULL; - } + /* set default creator/type fields */ +- memcpy(ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRTYPEOFF,"\0\0\0\0", 4); +- memcpy(ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRCREATOFF,"\0\0\0\0", 4); ++ memcpy(adp + FINDERINFO_FRTYPEOFF,"\0\0\0\0", 4); ++ memcpy(adp + FINDERINFO_FRCREATOFF,"\0\0\0\0", 4); + + /* make things invisible */ + if ((ad->ad_options & ADVOL_INVDOTS) +@@ -378,14 +385,16 @@ static int new_ad_header(struct adouble *ad, const cha + ashort = htons(ATTRBIT_INVISIBLE); + ad_setattr(ad, ashort); + ashort = htons(FINDERINFO_INVISIBLE); +- memcpy(ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF, &ashort, sizeof(ashort)); ++ memcpy(adp + FINDERINFO_FRFLAGOFF, &ashort, sizeof(ashort)); + } -- if (off == 0 || len == 0) { -+ /*if (off == 0 || len == 0) { -+ LOG(log_error, logtype_ad, "ad_entry: off or len is 0 (off: %d, len: %d)", -+ off, len); - return NULL; -- } -+ }*/ + /* put something sane in the date fields */ + if (stp == NULL) { + stp = &st; +- if (lstat(path, &st) != 0) ++ if (lstat(path, &st) != 0) { ++ ad->valid_data_len = 0; + return -1; ++ } + } + ad_setdate(ad, AD_DATE_CREATE | AD_DATE_UNIX, stp->st_mtime); + ad_setdate(ad, AD_DATE_MODIFY | AD_DATE_UNIX, stp->st_mtime); +@@ -417,7 +426,7 @@ static int parse_entries(struct adouble *ad, uint16_t - return ((struct adouble *)ad)->ad_data + off; - } + if (!eid + || eid > ADEID_MAX +- || off >= valid_data_len ++ || ((eid != ADEID_RFORK) && (off >= valid_data_len)) + || ((eid != ADEID_RFORK) && (off + len > valid_data_len))) + { + LOG(log_warning, logtype_ad, "parse_entries: bogus eid: %u, off: %u, len: %u",