Merge branch 'freebsd/current/main' into hardened/current/master

This commit is contained in:
HardenedBSD Sync Services 2024-11-19 06:01:23 -07:00
commit e9da7d714e
No known key found for this signature in database
6 changed files with 530 additions and 318 deletions

View File

@ -51,6 +51,9 @@
# xargs -n1 | sort | uniq -d;
# done
# 20241119: rewrite mv tests
OLD_FILES+=usr/tests/bin/mv/legacy_test
# 20241112: Retire MK_PROFILE support
OLD_FILES+=usr/lib/lib80211_p.a
OLD_FILES+=usr/lib/lib9p_p.a

View File

@ -32,13 +32,12 @@
* SUCH DAMAGE.
*/
#include <sys/types.h>
#include <sys/acl.h>
#include <sys/param.h>
#include <sys/acl.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/mount.h>
#include <err.h>
#include <errno.h>
@ -62,18 +61,16 @@ static int copy(const char *, const char *);
static int do_move(const char *, const char *);
static int fastcopy(const char *, const char *, struct stat *);
static void usage(void);
static void preserve_fd_acls(int source_fd, int dest_fd, const char *source_path,
const char *dest_path);
static void preserve_fd_acls(int, int, const char *, const char *);
int
main(int argc, char *argv[])
{
size_t baselen, len;
int rval;
char *p, *endp;
struct stat sb;
int ch;
char path[PATH_MAX];
struct stat sb;
char *p, *endp;
size_t baselen, len;
int ch, rval;
while ((ch = getopt(argc, argv, "fhinv")) != -1)
switch (ch) {
@ -161,9 +158,10 @@ main(int argc, char *argv[])
static int
do_move(const char *from, const char *to)
{
char path[PATH_MAX], modep[15];
struct statfs sfs;
struct stat sb;
int ask, ch, first;
char modep[15];
/*
* Check access. If interactive and file exists, ask user if it
@ -171,9 +169,8 @@ do_move(const char *from, const char *to)
* make sure the user wants to clobber it.
*/
if (!fflg && !access(to, F_OK)) {
/* prompt only if source exists */
if (lstat(from, &sb) == -1) {
if (lstat(from, &sb) == -1) {
warn("%s", from);
return (1);
}
@ -217,9 +214,6 @@ do_move(const char *from, const char *to)
}
if (errno == EXDEV) {
struct statfs sfs;
char path[PATH_MAX];
/*
* If the source is a symbolic link and is on another
* filesystem, it can be recreated at the destination.
@ -305,8 +299,8 @@ err: if (unlink(to))
warn("%s: set owner/group (was: %lu/%lu)", to,
(u_long)sbp->st_uid, (u_long)sbp->st_gid);
if (oldmode & (S_ISUID | S_ISGID)) {
warnx(
"%s: owner/group changed; clearing suid/sgid (mode was 0%03o)",
warnx("%s: owner/group changed; "
"clearing suid/sgid (mode was 0%03o)",
to, oldmode);
sbp->st_mode &= ~(S_ISUID | S_ISGID);
}
@ -494,9 +488,8 @@ preserve_fd_acls(int source_fd, int dest_fd, const char *source_path,
static void
usage(void)
{
(void)fprintf(stderr, "%s\n%s\n",
"usage: mv [-f | -i | -n] [-hv] source target",
" mv [-f | -i | -n] [-v] source ... directory");
"usage: mv [-f | -i | -n] [-hv] source target",
" mv [-f | -i | -n] [-v] source ... directory");
exit(EX_USAGE);
}

View File

@ -1,5 +1,5 @@
.include <bsd.own.mk>
TAP_TESTS_SH= legacy_test
ATF_TESTS_SH= mv_test
.include <bsd.test.mk>

View File

@ -1,295 +0,0 @@
#!/bin/sh
# A directory in a device different from that where the tests are run
TMPDIR=/tmp/regress.$$
COUNT=0
# Begin an individual test
begin()
{
COUNT=`expr $COUNT + 1`
OK=1
if [ -z "$FS" ]
then
NAME="$1"
else
NAME="$1 (cross device)"
fi
rm -rf testdir $TMPDIR/testdir
mkdir -p testdir $TMPDIR/testdir
cd testdir
}
# End an individual test
end()
{
if [ $OK = 1 ]
then
printf 'ok '
else
printf 'not ok '
fi
echo "$COUNT - $NAME"
cd ..
rm -rf testdir $TMPDIR/testdir
}
# Make a file that can later be verified
mkf()
{
CN=`basename $1`
echo "$CN-$CN" >$1
}
# Verify that the file specified is correct
ckf()
{
if [ -f $2 ] && echo "$1-$1" | diff - $2 >/dev/null
then
ok
else
notok
fi
}
# Make a fifo that can later be verified
mkp()
{
mkfifo $1
}
# Verify that the file specified is correct
ckp()
{
if [ -p $2 ]
then
ok
else
notok
fi
}
# Make a directory that can later be verified
mkd()
{
CN=`basename $1`
mkdir -p $1/"$CN-$CN"
}
# Verify that the directory specified is correct
ckd()
{
if [ -d $2/$1-$1 ]
then
ok
else
notok
fi
}
# Verify that the specified file does not exist
# (is not there)
cknt()
{
if [ -r $1 ]
then
notok
else
ok
fi
}
# A part of a test succeeds
ok()
{
:
}
# A part of a test fails
notok()
{
OK=0
}
# Verify that the exit code passed is for unsuccessful termination
ckfail()
{
if [ $1 -gt 0 ]
then
ok
else
notok
fi
}
# Verify that the exit code passed is for successful termination
ckok()
{
if [ $1 -eq 0 ]
then
ok
else
notok
fi
}
# Run all tests locally and across devices
echo 1..32
for FS in '' $TMPDIR/testdir/
do
begin 'Rename file'
mkf fa
mv fa ${FS}fb
ckok $?
ckf fa ${FS}fb
cknt fa
end
begin 'Move files into directory'
mkf fa
mkf fb
mkdir -p ${FS}1/2/3
mv fa fb ${FS}1/2/3
ckok $?
ckf fa ${FS}1/2/3/fa
ckf fb ${FS}1/2/3/fb
cknt fa
cknt fb
end
begin 'Move file from directory to file'
mkdir -p 1/2/3
mkf 1/2/3/fa
mv 1/2/3/fa ${FS}fb
ckok $?
ckf fa ${FS}fb
cknt 1/2/3/fa
end
begin 'Move file from directory to existing file'
mkdir -p 1/2/3
mkf 1/2/3/fa
:> ${FS}fb
mv 1/2/3/fa ${FS}fb
ckok $?
ckf fa ${FS}fb
cknt 1/2/3/fa
end
begin 'Move file from directory to existing directory'
mkdir -p 1/2/3
mkf 1/2/3/fa
mkdir -p ${FS}db/fa
# Should fail per POSIX step 3a:
# Destination path is a file of type directory and
# source_file is not a file of type directory
mv 1/2/3/fa ${FS}db 2>/dev/null
ckfail $?
ckf fa 1/2/3/fa
end
begin 'Move file from directory to directory'
mkdir -p da1/da2/da3
mkdir -p ${FS}db1/db2/db3
mkf da1/da2/da3/fa
mv da1/da2/da3/fa ${FS}db1/db2/db3/fb
ckok $?
ckf fa ${FS}db1/db2/db3/fb
cknt da1/da2/da3/fa
end
begin 'Rename directory'
mkd da
mv da ${FS}db
ckok $?
ckd da ${FS}db
cknt da
end
begin 'Move directory to directory name'
mkd da1/da2/da3/da
mkdir -p ${FS}db1/db2/db3
mv da1/da2/da3/da ${FS}db1/db2/db3/db
ckok $?
ckd da ${FS}db1/db2/db3/db
cknt da1/da2/da3/da
end
begin 'Move directory to directory'
mkd da1/da2/da3/da
mkdir -p ${FS}db1/db2/db3
mv da1/da2/da3/da ${FS}db1/db2/db3
ckok $?
ckd da ${FS}db1/db2/db3/da
cknt da1/da2/da3/da
end
begin 'Move directory to existing empty directory'
mkd da1/da2/da3/da
mkdir -p ${FS}db1/db2/db3/da
mv da1/da2/da3/da ${FS}db1/db2/db3
ckok $?
ckd da ${FS}db1/db2/db3/da
cknt da1/da2/da3/da
end
begin 'Move directory to existing non-empty directory'
mkd da1/da2/da3/da
mkdir -p ${FS}db1/db2/db3/da/full
# Should fail (per the semantics of rename(2))
mv da1/da2/da3/da ${FS}db1/db2/db3 2>/dev/null
ckfail $?
ckd da da1/da2/da3/da
end
begin 'Move directory to existing file'
mkd da1/da2/da3/da
mkdir -p ${FS}db1/db2/db3
:> ${FS}db1/db2/db3/da
# Should fail per POSIX step 3b:
# Destination path is a file not of type directory
# and source_file is a file of type directory
mv da1/da2/da3/da ${FS}db1/db2/db3/da 2>/dev/null
ckfail $?
ckd da da1/da2/da3/da
end
begin 'Rename fifo'
mkp fa
mv fa ${FS}fb
ckok $?
ckp fa ${FS}fb
cknt fa
end
begin 'Move fifos into directory'
mkp fa
mkp fb
mkdir -p ${FS}1/2/3
mv fa fb ${FS}1/2/3
ckok $?
ckp fa ${FS}1/2/3/fa
ckp fb ${FS}1/2/3/fb
cknt fa
cknt fb
end
begin 'Move fifo from directory to fifo'
mkdir -p 1/2/3
mkp 1/2/3/fa
mv 1/2/3/fa ${FS}fb
ckok $?
ckp fa ${FS}fb
cknt 1/2/3/fa
end
begin 'Move fifo from directory to directory'
mkdir -p da1/da2/da3
mkdir -p ${FS}db1/db2/db3
mkp da1/da2/da3/fa
mv da1/da2/da3/fa ${FS}db1/db2/db3/fb
ckok $?
ckp fa ${FS}db1/db2/db3/fb
cknt da1/da2/da3/fa
end
done

508
bin/mv/tests/mv_test.sh Normal file
View File

@ -0,0 +1,508 @@
#
# Copyright (c) 2007 Diomidis Spinellis
# Copyright (c) 2023 Klara, Inc.
#
# SPDX-License-Identifier: BSD-2-Clause
#
mv_setup() {
atf_check mkdir fs
atf_check mount -t tmpfs -o size=1m tmp fs
}
mv_cleanup() {
umount fs || true
}
# Make a file that can later be verified
mv_makefile() {
local cn="${1##*/}"
echo "$cn-$cn" >"$1"
}
# Verify that the file specified is correct
mv_checkfile() {
atf_check -o inline:"$1-$1\n" cat "$2"
}
# Make a fifo that can later be verified
mv_makepipe() {
atf_check mkfifo $1
}
# Verify that the file specified is correct
mv_checkpipe() {
atf_check test -p "$2"
}
# Make a directory that can later be verified
mv_makedir() {
local cn="${1##*/}"
atf_check mkdir -p "$1/$cn-$cn"
}
# Verify that the directory specified is correct
mv_checkdir() {
atf_check test -d "$2/$1-$1"
}
# Verify that the specified file does not exist
# (is not there)
mv_checkabsent() {
atf_check -s exit:1 test -r "$1"
}
atf_test_case rename_file cleanup
rename_file_head() {
atf_set "descr" "Rename file"
atf_set "require.user" "root"
}
rename_file_body() {
mv_setup
for FS in "" "fs/" ; do
mv_makefile fa
atf_check mv fa ${FS}fb
mv_checkfile fa ${FS}fb
mv_checkabsent fa
done
}
rename_file_cleanup() {
mv_cleanup
}
atf_test_case file_into_dir cleanup
file_into_dir_head() {
atf_set "descr" "Move files into directory"
atf_set "require.user" "root"
}
file_into_dir_body() {
mv_setup
for FS in "" "fs/" ; do
mv_makefile fa
mv_makefile fb
atf_check mkdir -p ${FS}1/2/3
atf_check mv fa fb ${FS}1/2/3
mv_checkfile fa ${FS}1/2/3/fa
mv_checkfile fb ${FS}1/2/3/fb
mv_checkabsent fa
mv_checkabsent fb
done
}
file_into_dir_cleanup() {
mv_cleanup
}
atf_test_case file_from_dir cleanup
file_from_dir_head() {
atf_set "descr" "Move file from directory to file"
atf_set "require.user" "root"
}
file_from_dir_body() {
mv_setup
atf_check mkdir -p 1/2/3
for FS in "" "fs/" ; do
mv_makefile 1/2/3/fa
atf_check mv 1/2/3/fa ${FS}fb
mv_checkfile fa ${FS}fb
mv_checkabsent 1/2/3/fa
done
}
file_from_dir_cleanup() {
mv_cleanup
}
atf_test_case file_from_dir_replace cleanup
file_from_dir_replace_head() {
atf_set "descr" "Move file from directory to existing file"
atf_set "require.user" "root"
}
file_from_dir_replace_body() {
mv_setup
atf_check mkdir -p 1/2/3
for FS in "" "fs/" ; do
mv_makefile 1/2/3/fa
:> ${FS}fb
atf_check mv 1/2/3/fa ${FS}fb
mv_checkfile fa ${FS}fb
mv_checkabsent 1/2/3/fa
done
}
file_from_dir_replace_cleanup() {
mv_cleanup
}
atf_test_case file_to_dir cleanup
file_to_dir_head() {
atf_set "descr" "Move file from directory to existing directory"
atf_set "require.user" "root"
}
file_to_dir_body() {
mv_setup
atf_check mkdir -p 1/2/3
for FS in "" "fs/" ; do
mv_makefile 1/2/3/fa
atf_check mkdir -p ${FS}db/fa
# Should fail per POSIX step 3a:
# Destination path is a file of type directory and
# source_file is not a file of type directory
atf_check -s not-exit:0 -e match:"Is a directory" \
mv 1/2/3/fa ${FS}db
mv_checkfile fa 1/2/3/fa
done
}
file_to_dir_cleanup() {
mv_cleanup
}
atf_test_case file_from_rename_dir cleanup
file_from_rename_dir_head() {
atf_set "descr" "Move file from directory to directory"
atf_set "require.user" "root"
}
file_from_rename_dir_body() {
mv_setup
atf_check mkdir -p da1/da2/da3
for FS in "" "fs/" ; do
atf_check mkdir -p ${FS}db1/db2/db3
mv_makefile da1/da2/da3/fa
atf_check mv da1/da2/da3/fa ${FS}db1/db2/db3/fb
mv_checkfile fa ${FS}db1/db2/db3/fb
mv_checkabsent da1/da2/da3/fa
done
}
file_from_rename_dir_cleanup() {
mv_cleanup
}
atf_test_case rename_dir cleanup
rename_dir_head() {
atf_set "descr" "Rename directory"
atf_set "require.user" "root"
}
rename_dir_body() {
mv_setup
for FS in "" "fs/" ; do
mv_makedir da
atf_check mv da ${FS}db
mv_checkdir da ${FS}db
mv_checkabsent da
done
}
rename_dir_cleanup() {
mv_cleanup
}
atf_test_case dir_to_dir cleanup
dir_to_dir_head() {
atf_set "descr" "Move directory to directory name"
atf_set "require.user" "root"
}
dir_to_dir_body() {
mv_setup
for FS in "" "fs/" ; do
mv_makedir da1/da2/da3/da
atf_check mkdir -p ${FS}db1/db2/db3
atf_check mv da1/da2/da3/da ${FS}db1/db2/db3/db
mv_checkdir da ${FS}db1/db2/db3/db
mv_checkabsent da1/da2/da3/da
done
}
dir_to_dir_cleanup() {
mv_cleanup
}
atf_test_case dir_into_dir cleanup
dir_into_dir_head() {
atf_set "descr" "Move directory to directory"
atf_set "require.user" "root"
}
dir_into_dir_body() {
mv_setup
for FS in "" "fs/" ; do
mv_makedir da1/da2/da3/da
atf_check mkdir -p ${FS}db1/db2/db3
atf_check mv da1/da2/da3/da ${FS}db1/db2/db3
mv_checkdir da ${FS}db1/db2/db3/da
mv_checkabsent da1/da2/da3/da
done
}
dir_into_dir_cleanup() {
mv_cleanup
}
atf_test_case dir_to_empty_dir cleanup
dir_to_empty_dir_head() {
atf_set "descr" "Move directory to existing empty directory"
atf_set "require.user" "root"
}
dir_to_empty_dir_body() {
mv_setup
for FS in "" "fs/" ; do
mv_makedir da1/da2/da3/da
atf_check mkdir -p ${FS}db1/db2/db3/da
atf_check mv da1/da2/da3/da ${FS}db1/db2/db3
mv_checkdir da ${FS}db1/db2/db3/da
mv_checkabsent da1/da2/da3/da
done
}
dir_to_empty_dir_cleanup() {
mv_cleanup
}
atf_test_case dir_to_nonempty_dir cleanup
dir_to_nonempty_dir_head() {
atf_set "descr" "Move directory to existing non-empty directory"
atf_set "require.user" "root"
}
dir_to_nonempty_dir_body() {
mv_setup
for FS in "" "fs/" ; do
mv_makedir da1/da2/da3/da
atf_check mkdir -p ${FS}db1/db2/db3/da/full
# Should fail (per the semantics of rename(2))
atf_check -s not-exit:0 -e match:"Directory not empty" \
mv da1/da2/da3/da ${FS}db1/db2/db3
mv_checkdir da da1/da2/da3/da
done
}
dir_to_nonempty_dir_cleanup() {
mv_cleanup
}
atf_test_case dir_to_file cleanup
dir_to_file_head() {
atf_set "descr" "Move directory to existing file"
atf_set "require.user" "root"
}
dir_to_file_body() {
mv_setup
for FS in "" "fs/" ; do
mv_makedir da1/da2/da3/da
atf_check mkdir -p ${FS}db1/db2/db3
:> ${FS}db1/db2/db3/da
# Should fail per POSIX step 3b:
# Destination path is a file not of type directory
# and source_file is a file of type directory
atf_check -s not-exit:0 -e match:"Not a directory" \
mv da1/da2/da3/da ${FS}db1/db2/db3/da
mv_checkdir da da1/da2/da3/da
done
}
dir_to_file_cleanup() {
mv_cleanup
}
atf_test_case rename_fifo cleanup
rename_fifo_head() {
atf_set "descr" "Rename fifo"
atf_set "require.user" "root"
}
rename_fifo_body() {
mv_setup
for FS in "" "fs/" ; do
mv_makepipe fa
atf_check mv fa ${FS}fb
mv_checkpipe fa ${FS}fb
mv_checkabsent fa
done
}
rename_fifo_cleanup() {
mv_cleanup
}
atf_test_case fifo_into_dir cleanup
fifo_into_dir_head() {
atf_set "descr" "Move fifos into directory"
atf_set "require.user" "root"
}
fifo_into_dir_body() {
mv_setup
for FS in "" "fs/" ; do
mv_makepipe fa
mv_makepipe fb
atf_check mkdir -p ${FS}1/2/3
atf_check mv fa fb ${FS}1/2/3
mv_checkpipe fa ${FS}1/2/3/fa
mv_checkpipe fb ${FS}1/2/3/fb
mv_checkabsent fa
mv_checkabsent fb
done
}
fifo_into_dir_cleanup() {
mv_cleanup
}
atf_test_case fifo_from_dir cleanup
fifo_from_dir_head() {
atf_set "descr" "Move fifo from directory to fifo"
atf_set "require.user" "root"
}
fifo_from_dir_body() {
mv_setup
atf_check mkdir -p 1/2/3
for FS in "" "fs/" ; do
mv_makepipe 1/2/3/fa
atf_check mv 1/2/3/fa ${FS}fb
mv_checkpipe fa ${FS}fb
mv_checkabsent 1/2/3/fa
done
}
fifo_from_dir_cleanup() {
mv_cleanup
}
atf_test_case fifo_from_dir_into_dir cleanup
fifo_from_dir_into_dir_head() {
atf_set "descr" "Move fifo from directory to directory"
atf_set "require.user" "root"
}
fifo_from_dir_into_dir_body() {
mv_setup
atf_check mkdir -p da1/da2/da3
for FS in "" "fs/" ; do
atf_check mkdir -p ${FS}db1/db2/db3
mv_makepipe da1/da2/da3/fa
atf_check mv da1/da2/da3/fa ${FS}db1/db2/db3/fb
mv_checkpipe fa ${FS}db1/db2/db3/fb
mv_checkabsent da1/da2/da3/fa
done
}
fifo_from_dir_into_dir_cleanup() {
mv_cleanup
}
atf_test_case mv_f cleanup
mv_f_head() {
atf_set "descr" "Force replacement"
atf_set "require.user" "root"
}
mv_f_body() {
mv_setup
for FS in "" "fs/" ; do
mv_makefile fa
atf_check mv fa ${FS}fb
mv_checkfile fa ${FS}fb
mv_checkabsent fa
mv_makefile fa
:> ${FS}fb
atf_check mv -i -n -f fa ${FS}fb
mv_checkfile fa ${FS}fb
mv_checkabsent fa
done
}
mv_f_cleanup() {
mv_cleanup
}
atf_test_case mv_h cleanup
mv_h_head() {
atf_set "descr" "Replace symbolic link"
atf_set "require.user" "root"
}
mv_h_body() {
mv_setup
for FS in "" "fs/" ; do
atf_check mkdir ${FS}da
atf_check ln -s da ${FS}db
# First test without -h, file goes into symlink target
mv_makefile fa
atf_check mv fa ${FS}db
mv_checkfile fa ${FS}da/fa
# Second test with -h, file replaces symlink
mv_makefile fa
atf_check mv -h fa ${FS}db
mv_checkfile fa ${FS}db
done
}
mv_h_cleanup() {
mv_cleanup
}
atf_test_case mv_i cleanup
mv_i_head() {
atf_set "descr" "Confirm replacement"
atf_set "require.user" "root"
}
mv_i_body() {
mv_setup
echo n >n
echo y >y
for FS in "" "fs/" ; do
mv_makefile fa
mv_makefile ${FS}fb
# First test, answer no, file is not replaced
atf_check -e match:"^overwrite ${FS}fb\\?" \
mv -i fa ${FS}fb <n
mv_checkfile fa fa
mv_checkfile fb ${FS}fb
# Second test, answer yes, file is replaced
atf_check -e match:"^overwrite ${FS}fb\\?" \
mv -i fa ${FS}fb <y
mv_checkabsent fa
mv_checkfile fa ${FS}fb
done
}
mv_i_cleanup() {
mv_cleanup
}
atf_test_case mv_n cleanup
mv_n_head() {
atf_set "descr" "Decline replacement"
atf_set "require.user" "root"
}
mv_n_body() {
mv_setup
for FS in "" "fs/" ; do
mv_makefile fa
mv_makefile ${FS}fb
atf_check mv -n fa ${FS}fb
mv_checkfile fa fa
mv_checkfile fb ${FS}fb
done
}
mv_n_cleanup() {
mv_cleanup
}
atf_test_case mv_v cleanup
mv_v_head() {
atf_set "descr" "Verbose mode"
atf_set "require.user" "root"
}
mv_v_body() {
mv_setup
for FS in "" "fs/" ; do
mv_makefile fa
atf_check mkdir ${FS}da
atf_check -o inline:"fa -> ${FS}da/fa\n" \
mv -v fa ${FS}da
done
}
mv_v_cleanup() {
mv_cleanup
}
atf_init_test_cases() {
atf_add_test_case rename_file
atf_add_test_case file_into_dir
atf_add_test_case file_from_dir
atf_add_test_case file_from_dir_replace
atf_add_test_case file_to_dir
atf_add_test_case file_from_rename_dir
atf_add_test_case rename_dir
atf_add_test_case dir_to_dir
atf_add_test_case dir_into_dir
atf_add_test_case dir_to_empty_dir
atf_add_test_case dir_to_nonempty_dir
atf_add_test_case dir_to_file
atf_add_test_case rename_fifo
atf_add_test_case fifo_into_dir
atf_add_test_case fifo_from_dir
atf_add_test_case fifo_from_dir_into_dir
atf_add_test_case mv_f
atf_add_test_case mv_h
atf_add_test_case mv_i
atf_add_test_case mv_n
atf_add_test_case mv_v
}

View File

@ -12,7 +12,10 @@ oci_image_build() {
FreeBSD-runtime \
FreeBSD-certctl \
FreeBSD-kerberos-lib \
FreeBSD-libarchive \
FreeBSD-libexecinfo \
FreeBSD-libucl \
FreeBSD-fetch \
FreeBSD-rc \
FreeBSD-pkg-bootstrap \
FreeBSD-mtree