vfs_worm_renameat() only checked if the source file was WORM-protected,
but not the destination. This allowed overwriting immutable files via
SMB2 rename with ReplaceIfExists=1, bypassing WORM protection.
Add destination check using FSTATAT on the destination dirfsp, as
suggested by the maintainer.
CWE-284 (Improper Access Control)
Reported-by: Pavel Kohout, Aisle Research, www.aisle.com
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15997
Signed-off-by: Pavel Kohout <pavel.kohout@aisle.com>
Reviewed-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
+++ /dev/null
-^samba3.blackbox.worm.SMB3
-^samba3.blackbox.worm.NT1
const struct smb_filename *smb_fname_dst,
const struct vfs_rename_how *how)
{
+ struct stat_ex dst_st;
+ int ret;
+
if (is_readonly(handle, smb_fname_src)) {
errno = EACCES;
return -1;
}
+ /* Check if destination is WORM-protected (fixes CVE-2026-2340) */
+ ret = SMB_VFS_FSTATAT(handle->conn,
+ dst_dirfsp,
+ smb_fname_dst,
+ &dst_st,
+ AT_SYMLINK_NOFOLLOW);
+ if (ret == 0) {
+ struct smb_filename dst_with_stat = *smb_fname_dst;
+ dst_with_stat.st = dst_st;
+ if (is_readonly(handle, &dst_with_stat)) {
+ errno = EACCES;
+ return -1;
+ }
+ }
+
return SMB_VFS_NEXT_RENAMEAT(handle,
src_dirfsp,
smb_fname_src,