summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNamjae Jeon <linkinjeon@kernel.org>2024-01-07 21:24:07 +0900
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-01-20 11:53:01 +0100
commit4f6638562db5f9568dbfbe3a2a6ac80c4832f19e (patch)
tree60f427839f4107c77c38f50670dfb811f6f45f8d
parentf90fb3a482d1d4705603ab6c320de0ccd611055c (diff)
downloadlinux-stable-4f6638562db5f9568dbfbe3a2a6ac80c4832f19e.tar.gz
linux-stable-4f6638562db5f9568dbfbe3a2a6ac80c4832f19e.tar.bz2
linux-stable-4f6638562db5f9568dbfbe3a2a6ac80c4832f19e.zip
ksmbd: don't allow O_TRUNC open on read-only share
commit d592a9158a112d419f341f035d18d02f8d232def upstream. When file is changed using notepad on read-only share(read_only = yes in ksmbd.conf), There is a problem where existing data is truncated. notepad in windows try to O_TRUNC open(FILE_OVERWRITE_IF) and all data in file is truncated. This patch don't allow O_TRUNC open on read-only share and add KSMBD_TREE_CONN_FLAG_WRITABLE check in smb2_set_info(). Cc: stable@vger.kernel.org Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--fs/smb/server/smb2pdu.c23
1 files changed, 9 insertions, 14 deletions
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 652ab429bf2e..ca2c528c9de3 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -2971,7 +2971,7 @@ int smb2_open(struct ksmbd_work *work)
&may_flags);
if (!test_tree_conn_flag(tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
- if (open_flags & O_CREAT) {
+ if (open_flags & (O_CREAT | O_TRUNC)) {
ksmbd_debug(SMB,
"User does not have write permission\n");
rc = -EACCES;
@@ -5943,12 +5943,6 @@ static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp,
}
case FILE_RENAME_INFORMATION:
{
- if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
- ksmbd_debug(SMB,
- "User does not have write permission\n");
- return -EACCES;
- }
-
if (buf_len < sizeof(struct smb2_file_rename_info))
return -EINVAL;
@@ -5968,12 +5962,6 @@ static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp,
}
case FILE_DISPOSITION_INFORMATION:
{
- if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
- ksmbd_debug(SMB,
- "User does not have write permission\n");
- return -EACCES;
- }
-
if (buf_len < sizeof(struct smb2_file_disposition_info))
return -EINVAL;
@@ -6035,7 +6023,7 @@ int smb2_set_info(struct ksmbd_work *work)
{
struct smb2_set_info_req *req;
struct smb2_set_info_rsp *rsp;
- struct ksmbd_file *fp;
+ struct ksmbd_file *fp = NULL;
int rc = 0;
unsigned int id = KSMBD_NO_FID, pid = KSMBD_NO_FID;
@@ -6055,6 +6043,13 @@ int smb2_set_info(struct ksmbd_work *work)
rsp = smb2_get_msg(work->response_buf);
}
+ if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
+ ksmbd_debug(SMB, "User does not have write permission\n");
+ pr_err("User does not have write permission\n");
+ rc = -EACCES;
+ goto err_out;
+ }
+
if (!has_file_id(id)) {
id = req->VolatileFileId;
pid = req->PersistentFileId;