From: Ralph Boehme Date: Tue, 6 Nov 2018 12:24:14 +0000 (+0100) Subject: vfs_fruit: validation of writes on AFP_AfpInfo stream X-Git-Tag: samba-4.8.8~32 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=42c3b3325a39446d481a69f1c462e25c551c17e8;p=thirdparty%2Fsamba.git vfs_fruit: validation of writes on AFP_AfpInfo stream Bug: https://bugzilla.samba.org/show_bug.cgi?id=13677 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (backported from commit a7c877847f855be5ee6673e541a181b818013abf) Autobuild-User(v4-8-test): Karolin Seeger Autobuild-Date(v4-8-test): Wed Nov 14 17:12:08 CET 2018 on sn-devel-144 --- diff --git a/selftest/knownfail.d/samba3.vfs.fruit b/selftest/knownfail.d/samba3.vfs.fruit index fe188b33b3d..6307e2b3404 100644 --- a/selftest/knownfail.d/samba3.vfs.fruit +++ b/selftest/knownfail.d/samba3.vfs.fruit @@ -1,5 +1,2 @@ ^samba3.vfs.fruit streams_depot.OS X AppleDouble file conversion\(nt4_dc\) ^samba3.vfs.fruit streams_depot.OS X AppleDouble file conversion without embedded xattr\(nt4_dc\) -^samba3.vfs.fruit metadata_netatalk.writing_afpinfo\(nt4_dc\) -^samba3.vfs.fruit metadata_stream.writing_afpinfo\(nt4_dc\) -^samba3.vfs.fruit streams_depot.writing_afpinfo\(nt4_dc\) diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c index 0bb034d0d8f..7b24256f0e4 100644 --- a/source3/modules/vfs_fruit.c +++ b/source3/modules/vfs_fruit.c @@ -4628,22 +4628,62 @@ static ssize_t fruit_pwrite_meta(vfs_handle_struct *handle, { struct fio *fio = (struct fio *)VFS_FETCH_FSP_EXTENSION(handle, fsp); ssize_t nwritten; + uint8_t buf[AFP_INFO_SIZE]; + size_t to_write; + size_t to_copy; + int cmp; + + if (n < 3) { + errno = EINVAL; + return -1; + } - if (n != AFP_INFO_SIZE || offset != 0) { - DBG_ERR("unexpected offset=%jd or size=%jd\n", - (intmax_t)offset, (intmax_t)n); + if (offset != 0 && n < 60) { + errno = EINVAL; return -1; } + cmp = memcmp(data, "AFP", 3); + if (cmp != 0) { + errno = EINVAL; + return -1; + } + + if (n <= AFP_OFF_FinderInfo) { + /* + * Nothing to do here really, just return + */ + return n; + } + + offset = 0; + + to_copy = n; + if (to_copy > AFP_INFO_SIZE) { + to_copy = AFP_INFO_SIZE; + } + memcpy(buf, data, to_copy); + + to_write = n; + if (to_write != AFP_INFO_SIZE) { + to_write = AFP_INFO_SIZE; + } + switch (fio->config->meta) { case FRUIT_META_STREAM: - nwritten = fruit_pwrite_meta_stream(handle, fsp, data, - n, offset); + nwritten = fruit_pwrite_meta_stream(handle, + fsp, + buf, + to_write, + offset); break; case FRUIT_META_NETATALK: - nwritten = fruit_pwrite_meta_netatalk(handle, fsp, data, - n, offset); + nwritten = fruit_pwrite_meta_netatalk(handle, + fsp, + buf, + to_write, + offset); break; default: @@ -4651,7 +4691,14 @@ static ssize_t fruit_pwrite_meta(vfs_handle_struct *handle, return -1; } - return nwritten; + if (nwritten != to_write) { + return -1; + } + + /* + * Return the requested amount, verified against macOS SMB server + */ + return n; } static ssize_t fruit_pwrite_rsrc_stream(vfs_handle_struct *handle,