diff --git a/net/netatalk3/Makefile b/net/netatalk3/Makefile index 71d081b6c62c..659a299aa0c1 100644 --- a/net/netatalk3/Makefile +++ b/net/netatalk3/Makefile @@ -1,104 +1,104 @@ PORTNAME= netatalk PORTVERSION= 3.1.13 -PORTREVISION= 3 +PORTREVISION= 4 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-libatalk_adouble_ad__open.c b/net/netatalk3/files/patch-libatalk_adouble_ad__open.c index a5a279834158..bff592c563bd 100644 --- a/net/netatalk3/files/patch-libatalk_adouble_ad__open.c +++ b/net/netatalk3/files/patch-libatalk_adouble_ad__open.c @@ -1,97 +1,159 @@ --- libatalk/adouble/ad_open.c.orig 2022-03-22 04:44:25 UTC +++ libatalk/adouble/ad_open.c @@ -140,17 +140,17 @@ static struct adouble_fops ad_adouble_ea = { 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} }; @@ -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); + /* 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)); } /* 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 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", +@@ -782,20 +791,42 @@ static int ad_header_read_ea(const char *path, struct + EC_FAIL; + } + ++ /* ++ * It is possible for AFP metadata to contain a zero-length ++ * comment. This will cause ad_entry(ad, ADEID_COMMENT) to return NULL ++ * but should not be treated as an error condition. ++ * Since recent CVE fixes have introduced new behavior regarding ++ * ad_entry() output. For now, we will AFP_ASSERT() in EC_CLEANUP to prevent ++ * altering on-disk info. This does introduce an avenue to DOS ++ * the netatalk server by locally writing garbage to the EA. At this ++ * point, the outcome is an acceptable risk to prevent unintended ++ * changes to metadata. ++ */ + if (nentries != ADEID_NUM_EA + || !ad_entry(ad, ADEID_FINDERI) +- || !ad_entry(ad, ADEID_COMMENT) + || !ad_entry(ad, ADEID_FILEDATESI) + || !ad_entry(ad, ADEID_AFPFILEI) + || !ad_entry(ad, ADEID_PRIVDEV) + || !ad_entry(ad, ADEID_PRIVINO) + || !ad_entry(ad, ADEID_PRIVSYN) + || !ad_entry(ad, ADEID_PRIVID)) { +- LOG(log_error, logtype_ad, "ad_header_read_ea(\"%s\"): invalid metadata EA", fullpathname(path)); ++ LOG(log_error, logtype_ad, ++ "ad_header_read_ea(\"%s\"): invalid metadata EA " ++ "this is now being treated as a fatal error. " ++ "if you see this log entry, please file a bug ticket " ++ "with your upstream vendor and attach the generated " ++ "core file.", path ? fullpathname(path) : "UNKNOWN"); ++ + errno = EINVAL; + EC_FAIL; + } + ++ if (!ad_entry(ad, ADEID_COMMENT) && ++ (ad->ad_eid[ADEID_COMMENT].ade_len != 0)) { ++ errno = EINVAL; ++ EC_FAIL; ++ } ++ + /* + * Ensure the resource fork offset is always set + */ +@@ -805,6 +836,8 @@ static int ad_header_read_ea(const char *path, struct + #endif + + EC_CLEANUP: ++ AFP_ASSERT(!(ret != 0 && errno == EINVAL)); ++#if 0 + if (ret != 0 && errno == EINVAL) { + become_root(); + (void)sys_removexattr(path, AD_EA_META); +@@ -812,6 +845,7 @@ EC_CLEANUP: + LOG(log_error, logtype_ad, "ad_header_read_ea(\"%s\"): deleted invalid metadata EA", fullpathname(path), nentries); + errno = ENOENT; + } ++#endif + EC_EXIT; + } +