]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
CVE-2026-2340: test whether vfs_worm allows overwrite
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>
Wed, 18 Feb 2026 23:50:38 +0000 (12:50 +1300)
committerStefan Metzmacher <metze@samba.org>
Tue, 26 May 2026 12:51:32 +0000 (12:51 +0000)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15997

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Volker Lendecke <vl@samba.org>
selftest/knownfail.d/vfs-worm [new file with mode: 0644]
source3/script/tests/test_worm.sh

diff --git a/selftest/knownfail.d/vfs-worm b/selftest/knownfail.d/vfs-worm
new file mode 100644 (file)
index 0000000..f4a330c
--- /dev/null
@@ -0,0 +1,2 @@
+^samba3.blackbox.worm.SMB3
+^samba3.blackbox.worm.NT1
index f96c8ec7e47d8c51b10716bbf596c9483a508cf3..d38488cb79023c4b6573632ae68c2dba26b20f40 100755 (executable)
@@ -40,6 +40,7 @@ do_cleanup()
                #subshell.
                cd "$share_test_dir" || return
                rm -f must-be-deleted must-not-be-deleted must-be-deleted-after-ctime-refresh
+               rm -f must-not-be-overwritten sentinel-value
        )
        rm -f $tmpfile
 }
@@ -51,6 +52,10 @@ do_cleanup
 
 tmpfile=$PREFIX/smbclient_interactive_prompt_commands
 
+tmp_sentinel=$PREFIX/sentinel_value
+SENTINEL_VALUE='1'
+echo $SENTINEL_VALUE > $tmp_sentinel
+
 test_worm()
 {
        # use echo because helo scripts don't support variables
@@ -58,6 +63,7 @@ test_worm()
 put $tmpfile must-be-deleted
 put $tmpfile must-be-deleted-after-ctime-refresh
 put $tmpfile must-not-be-deleted
+put $tmpfile must-not-be-overwritten
 del must-be-deleted
 quit" > $tmpfile
        # make sure the directory is not too old for worm:
@@ -97,6 +103,30 @@ quit" > $tmpfile
                printf "$0: ERROR: must-not-be-deleted WAS deleted\n"
                return 1
        }
+
+       # Check we can't change a protected file by renaming over it.
+       # The source file needs to recently created or access will be
+       # denied before RENAME_AT is reached, which is the thing we
+       # want to test.
+       original_contents=`cat $share_test_dir/must-not-be-overwritten`
+       echo "
+put $tmp_sentinel sentinel-value
+rename sentinel-value must-not-be-overwritten  -f
+quit" > $tmpfile
+       cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT -U$USERNAME%$PASSWORD //$SERVER/worm -I$SERVER_IP $ADDARGS < $tmpfile 2>&1'
+       eval echo "$cmd"
+       out=$(eval "$cmd")
+       new_contents=`cat $share_test_dir/must-not-be-overwritten`
+
+       if [ "$new_contents" = "$SENTINEL_VALUE" ]; then
+           echo "must-not-be-overwritten was overwritten"
+           return 1
+       fi
+       if [ "$new_contents" != "$original_contents" ]; then
+           echo "must-not-be-overwritten was changed (but not precisely overwritten)"
+           return 1
+       fi
+
        # if we're not root, return here:
        test "$UID" = "0" ||  {
                return 0