From 0ae8d23aac2131d5b7a6f0efe1728260d92360b7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 26 Jun 2023 12:47:17 +0200 Subject: [PATCH 1/4] error_inject: map EROFS Bug: https://bugzilla.samba.org/show_bug.cgi?id=15402 Signed-off-by: Volker Lendecke Reviewed-by: Ralph Boehme (cherry picked from commit 840480789fcbb2e4ffe8b08818869f8490dc29d5) --- source3/modules/vfs_error_inject.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/modules/vfs_error_inject.c b/source3/modules/vfs_error_inject.c index 1a327097b30..4ecff3f7bde 100644 --- a/source3/modules/vfs_error_inject.c +++ b/source3/modules/vfs_error_inject.c @@ -31,6 +31,7 @@ struct unix_error_map { { "EBADF", EBADF }, { "EINTR", EINTR }, { "EACCES", EACCES }, + { "EROFS", EROFS }, }; static int find_unix_error_from_string(const char *err_str) -- 2.30.2 From 917389bc53b2bd8ac62a4ef76cc2bafa14ae3499 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 26 Jun 2023 13:17:19 +0200 Subject: [PATCH 2/4] error_inject: Enable returning EROFS for O_CREAT Bug: https://bugzilla.samba.org/show_bug.cgi?id=15402 Signed-off-by: Volker Lendecke Reviewed-by: Ralph Boehme (cherry picked from commit 37b3667f65d10a39b95dd84c002677d16f8c0776) --- source3/modules/vfs_error_inject.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/source3/modules/vfs_error_inject.c b/source3/modules/vfs_error_inject.c index 4ecff3f7bde..edb7c64a92a 100644 --- a/source3/modules/vfs_error_inject.c +++ b/source3/modules/vfs_error_inject.c @@ -116,6 +116,7 @@ static int vfs_error_inject_openat(struct vfs_handle_struct *handle, const struct vfs_open_how *how) { int error = inject_unix_error("openat", handle); + int create_error = inject_unix_error("openat_create", handle); int dirfsp_flags = (O_NOFOLLOW|O_DIRECTORY); bool return_error; @@ -127,6 +128,24 @@ static int vfs_error_inject_openat(struct vfs_handle_struct *handle, #endif #endif + if ((create_error != 0) && (how->flags & O_CREAT)) { + struct stat_ex st = { + .st_ex_nlink = 0, + }; + int ret; + + ret = SMB_VFS_FSTATAT(handle->conn, + dirfsp, + smb_fname, + &st, + AT_SYMLINK_NOFOLLOW); + + if ((ret == -1) && (errno == ENOENT)) { + errno = create_error; + return -1; + } + } + return_error = (error != 0); return_error &= !fsp->fsp_flags.is_pathref; return_error &= ((how->flags & dirfsp_flags) != dirfsp_flags); -- 2.30.2 From dbe69c8b8a9c933a113e7d55b9bdde29e70aa829 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 26 Jun 2023 14:54:00 +0200 Subject: [PATCH 3/4] tests: Show smbd returns wrong error code when creating on r/o fs Bug: https://bugzilla.samba.org/show_bug.cgi?id=15402 Signed-off-by: Volker Lendecke Reviewed-by: Ralph Boehme (cherry picked from commit 13d199bea0f39fafd2bf39516d83e20893003aa2) --- selftest/knownfail.d/rofs | 1 + source3/script/tests/test_rofs.sh | 34 +++++++++++++++++++++++++++++++ source3/selftest/tests.py | 7 +++++++ 3 files changed, 42 insertions(+) create mode 100644 selftest/knownfail.d/rofs create mode 100755 source3/script/tests/test_rofs.sh diff --git a/selftest/knownfail.d/rofs b/selftest/knownfail.d/rofs new file mode 100644 index 00000000000..dd130773404 --- /dev/null +++ b/selftest/knownfail.d/rofs @@ -0,0 +1 @@ +^samba3.blackbox.rofs_error.* \ No newline at end of file diff --git a/source3/script/tests/test_rofs.sh b/source3/script/tests/test_rofs.sh new file mode 100755 index 00000000000..72901e5845a --- /dev/null +++ b/source3/script/tests/test_rofs.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +# Test smbd handling EROFS when creating a file +# Copyright (C) 2023 Volker Lendecke + +if [ $# -ne 4 ]; then + echo Usage: $0 SERVERCONFFILE SMBCLIENT SERVER SHARE + exit 1 +fi + +CONF=$1 +shift 1 +SMBCLIENT=$1 +shift 1 +SERVER=$1 +shift 1 +SHARE=$1 +shift 1 + +incdir=$(dirname $0)/../../../testprogs/blackbox +. $incdir/subunit.sh + +error_inject_conf=$(dirname ${SERVERCONFFILE})/error_inject.conf +echo "error_inject:openat_create = EROFS" >${error_inject_conf} + +failed=0 + +out=$(${SMBCLIENT} //${SERVER}/${SHARE} ${CONF} -U${USER}%${PASSWORD} \ + -c "put VERSION") +testit_grep "Expect MEDIA_WRITE_PROTECTED" NT_STATUS_MEDIA_WRITE_PROTECTED \ + echo "$out" || failed=$(expr $failed + 1) + +>${error_inject_conf} + +testok $0 $failed diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index 6e4ed6713f6..90806f9ca92 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -1420,6 +1420,13 @@ plantestsuite("samba3.blackbox.chdir-cache", "simpleserver:local", '$PREFIX', 'simpleserver']) +plantestsuite("samba3.blackbox.rofs_error", "simpleserver", + [os.path.join(samba3srcdir, "script/tests/test_rofs.sh"), + configuration, + os.path.join(bindir(), "smbclient"), + '$SERVER_IP', + "error_inject"]) + plantestsuite("samba3.blackbox.zero_readsize", "simpleserver:local", [os.path.join(samba3srcdir, -- 2.30.2 From 36054c7a33d8eed2c5232bdf1737f28156f9b3ba Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 26 Jun 2023 13:17:44 +0200 Subject: [PATCH 4/4] smbd: Don't mask open error if fstatat() fails Bug: https://bugzilla.samba.org/show_bug.cgi?id=15402 Signed-off-by: Volker Lendecke Reviewed-by: Ralph Boehme Autobuild-User(master): Volker Lendecke Autobuild-Date(master): Mon Jun 26 16:53:21 UTC 2023 on atb-devel-224 (cherry picked from commit de2738fb9a7dad84eb50a0cf007d89b6ef53ec9a) --- selftest/knownfail.d/rofs | 1 - source3/smbd/open.c | 9 +++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) delete mode 100644 selftest/knownfail.d/rofs diff --git a/selftest/knownfail.d/rofs b/selftest/knownfail.d/rofs deleted file mode 100644 index dd130773404..00000000000 --- a/selftest/knownfail.d/rofs +++ /dev/null @@ -1 +0,0 @@ -^samba3.blackbox.rofs_error.* \ No newline at end of file diff --git a/source3/smbd/open.c b/source3/smbd/open.c index da0498f9e7d..94f50becb24 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -780,6 +780,15 @@ again: smb_fname_rel, &fsp->fsp_name->st, AT_SYMLINK_NOFOLLOW); + + if (ret == -1) { + /* + * Keep the original error. Otherwise we would + * mask for example EROFS for open(O_CREAT), + * turning it into ENOENT. + */ + goto out; + } } else { ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st); } -- 2.30.2