summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorPali Rohár <pali@kernel.org>2024-12-09 20:44:23 +0100
committerSteve French <stfrench@microsoft.com>2025-04-01 04:58:00 -0500
commite255612b5ed9f179abe8196df7c2ba09dd227900 (patch)
tree9e4b4fe987b446675d23da50e56145ee8fd5f4ba /fs
parent4236ac9fe5b8b42756070d4abfb76fed718e87c2 (diff)
downloadlinux-e255612b5ed9f179abe8196df7c2ba09dd227900.tar.gz
linux-e255612b5ed9f179abe8196df7c2ba09dd227900.tar.bz2
linux-e255612b5ed9f179abe8196df7c2ba09dd227900.zip
cifs: Add fallback for SMB2 CREATE without FILE_READ_ATTRIBUTES
Some operations, like WRITE, does not require FILE_READ_ATTRIBUTES access. So when FILE_READ_ATTRIBUTES is not explicitly requested for smb2_open_file() then first try to do SMB2 CREATE with FILE_READ_ATTRIBUTES access (like it was before) and then fallback to SMB2 CREATE without FILE_READ_ATTRIBUTES access (less common case). This change allows to complete WRITE operation to a file when it does not grant FILE_READ_ATTRIBUTES permission and its parent directory does not grant READ_DATA permission (parent directory READ_DATA is implicit grant of child FILE_READ_ATTRIBUTES permission). Signed-off-by: Pali Rohár <pali@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/smb/client/smb2file.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/fs/smb/client/smb2file.c b/fs/smb/client/smb2file.c
index d609a20fb98a..2d726e9b950c 100644
--- a/fs/smb/client/smb2file.c
+++ b/fs/smb/client/smb2file.c
@@ -152,16 +152,25 @@ int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32
int err_buftype = CIFS_NO_BUFFER;
struct cifs_fid *fid = oparms->fid;
struct network_resiliency_req nr_ioctl_req;
+ bool retry_without_read_attributes = false;
smb2_path = cifs_convert_path_to_utf16(oparms->path, oparms->cifs_sb);
if (smb2_path == NULL)
return -ENOMEM;
- oparms->desired_access |= FILE_READ_ATTRIBUTES;
+ if (!(oparms->desired_access & FILE_READ_ATTRIBUTES)) {
+ oparms->desired_access |= FILE_READ_ATTRIBUTES;
+ retry_without_read_attributes = true;
+ }
smb2_oplock = SMB2_OPLOCK_LEVEL_BATCH;
rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data, NULL, &err_iov,
&err_buftype);
+ if (rc == -EACCES && retry_without_read_attributes) {
+ oparms->desired_access &= ~FILE_READ_ATTRIBUTES;
+ rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data, NULL, &err_iov,
+ &err_buftype);
+ }
if (rc && data) {
struct smb2_hdr *hdr = err_iov.iov_base;