summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/smb/server/smb2pdu.c42
1 files changed, 34 insertions, 8 deletions
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 6b8809f67b92..3c0d71fcc79b 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -3647,10 +3647,11 @@ static int smb2_create_sd_buffer(struct ksmbd_work *work,
le32_to_cpu(sd_buf->ccontext.DataLength), true, false);
}
-static void ksmbd_acls_fattr(struct smb_fattr *fattr,
- struct mnt_idmap *idmap,
- struct inode *inode)
+static int ksmbd_acls_fattr(struct smb_fattr *fattr,
+ struct mnt_idmap *idmap,
+ struct inode *inode)
{
+ struct posix_acl *acl;
vfsuid_t vfsuid = i_uid_into_vfsuid(idmap, inode);
vfsgid_t vfsgid = i_gid_into_vfsgid(idmap, inode);
@@ -3661,10 +3662,28 @@ static void ksmbd_acls_fattr(struct smb_fattr *fattr,
fattr->cf_dacls = NULL;
if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) {
- fattr->cf_acls = get_inode_acl(inode, ACL_TYPE_ACCESS);
- if (S_ISDIR(inode->i_mode))
- fattr->cf_dacls = get_inode_acl(inode, ACL_TYPE_DEFAULT);
+ acl = get_inode_acl(inode, ACL_TYPE_ACCESS);
+ if (IS_ERR(acl)) {
+ if (acl != ERR_PTR(-EOPNOTSUPP))
+ return PTR_ERR(acl);
+ acl = NULL;
+ }
+ fattr->cf_acls = acl;
+
+ if (S_ISDIR(inode->i_mode)) {
+ acl = get_inode_acl(inode, ACL_TYPE_DEFAULT);
+ if (IS_ERR(acl)) {
+ if (acl != ERR_PTR(-EOPNOTSUPP)) {
+ posix_acl_release(fattr->cf_acls);
+ return PTR_ERR(acl);
+ }
+ acl = NULL;
+ }
+ fattr->cf_dacls = acl;
+ }
}
+
+ return 0;
}
enum {
@@ -4791,7 +4810,10 @@ int smb2_open(struct ksmbd_work *work)
int pntsd_size;
size_t scratch_len;
- ksmbd_acls_fattr(&fattr, idmap, inode);
+ rc = ksmbd_acls_fattr(&fattr, idmap, inode);
+ if (rc)
+ goto err_out;
+
scratch_len = smb_acl_sec_desc_scratch_len(&fattr,
NULL, 0,
OWNER_SECINFO | GROUP_SECINFO |
@@ -7652,7 +7674,11 @@ static int smb2_get_info_sec(struct ksmbd_work *work,
idmap = file_mnt_idmap(fp->filp);
inode = file_inode(fp->filp);
- ksmbd_acls_fattr(&fattr, idmap, inode);
+ rc = ksmbd_acls_fattr(&fattr, idmap, inode);
+ if (rc) {
+ ksmbd_fd_put(work, fp);
+ return rc;
+ }
if (test_share_config_flag(work->tcon->share_conf,
KSMBD_SHARE_FLAG_ACL_XATTR))