ksmbd: add user namespace support
authorHyunchul Lee <hyc.lee@gmail.com>
Wed, 30 Jun 2021 09:25:53 +0000 (18:25 +0900)
committerNamjae Jeon <namjae.jeon@samsung.com>
Fri, 2 Jul 2021 07:27:10 +0000 (16:27 +0900)
For user namespace support, call vfs functions
with struct user_namespace got from struct path.

This patch have been tested mannually as below.

Create an id-mapped mount using the mount-idmapped utility
(https://github.com/brauner/mount-idmapped).
$ mount-idmapped --map-mount b:1003:1002:1 /home/foo <EXPORT DIR>/foo
(the user, "foo" is 1003, and the user "bar" is 1002).

And  mount the export directory using cifs with the user, "bar".
succeed to create/delete/stat/read/write files and directory in
the <EXPORT DIR>/foo. But fail with a bind mount for /home/foo.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com>
Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/ksmbd/ndr.c
fs/ksmbd/ndr.h
fs/ksmbd/oplock.c
fs/ksmbd/smb2pdu.c
fs/ksmbd/smb_common.c
fs/ksmbd/smb_common.h
fs/ksmbd/smbacl.c
fs/ksmbd/smbacl.h
fs/ksmbd/vfs.c
fs/ksmbd/vfs.h
fs/ksmbd/vfs_cache.c

index bcf13a2..cf0df78 100644 (file)
@@ -222,7 +222,9 @@ static int ndr_encode_posix_acl_entry(struct ndr *n, struct xattr_smb_acl *acl)
        return 0;
 }
 
-int ndr_encode_posix_acl(struct ndr *n, struct inode *inode,
+int ndr_encode_posix_acl(struct ndr *n,
+                        struct user_namespace *user_ns,
+                        struct inode *inode,
                         struct xattr_smb_acl *acl,
                         struct xattr_smb_acl *def_acl)
 {
@@ -250,8 +252,8 @@ int ndr_encode_posix_acl(struct ndr *n, struct inode *inode,
                ndr_write_int32(n, 0);
        }
 
-       ndr_write_int64(n, from_kuid(&init_user_ns, inode->i_uid));
-       ndr_write_int64(n, from_kgid(&init_user_ns, inode->i_gid));
+       ndr_write_int64(n, from_kuid(user_ns, inode->i_uid));
+       ndr_write_int64(n, from_kgid(user_ns, inode->i_gid));
        ndr_write_int32(n, inode->i_mode);
 
        if (acl) {
index 77b2d1a..60ca265 100644 (file)
@@ -14,8 +14,8 @@ struct ndr {
 
 int ndr_encode_dos_attr(struct ndr *n, struct xattr_dos_attrib *da);
 int ndr_decode_dos_attr(struct ndr *n, struct xattr_dos_attrib *da);
-int ndr_encode_posix_acl(struct ndr *n, struct inode *inode,
-                        struct xattr_smb_acl *acl,
+int ndr_encode_posix_acl(struct ndr *n, struct user_namespace *user_ns,
+                        struct inode *inode, struct xattr_smb_acl *acl,
                         struct xattr_smb_acl *def_acl);
 int ndr_encode_v4_ntacl(struct ndr *n, struct xattr_ntacl *acl);
 int ndr_encode_v3_ntacl(struct ndr *n, struct xattr_ntacl *acl);
index a9f171c..5484b5b 100644 (file)
@@ -1612,9 +1612,9 @@ void create_posix_rsp_buf(char *cc, struct ksmbd_file *fp)
        buf->nlink = cpu_to_le32(inode->i_nlink);
        buf->reparse_tag = cpu_to_le32(fp->volatile_id);
        buf->mode = cpu_to_le32(inode->i_mode);
-       id_to_sid(from_kuid(&init_user_ns, inode->i_uid),
+       id_to_sid(from_kuid(file_mnt_user_ns(fp->filp), inode->i_uid),
                  SIDNFS_USER, (struct smb_sid *)&buf->SidBuffer[0]);
-       id_to_sid(from_kgid(&init_user_ns, inode->i_gid),
+       id_to_sid(from_kgid(file_mnt_user_ns(fp->filp), inode->i_gid),
                  SIDNFS_GROUP, (struct smb_sid *)&buf->SidBuffer[20]);
 }
 
index d79ea3e..dda9081 100644 (file)
@@ -2081,14 +2081,16 @@ static int smb2_set_ea(struct smb2_ea_info *eabuf, struct path *path)
                value = (char *)&eabuf->name + eabuf->EaNameLength + 1;
 
                if (!eabuf->EaValueLength) {
-                       rc = ksmbd_vfs_casexattr_len(path->dentry,
+                       rc = ksmbd_vfs_casexattr_len(mnt_user_ns(path->mnt),
+                                                    path->dentry,
                                                     attr_name,
                                                     XATTR_USER_PREFIX_LEN +
                                                     eabuf->EaNameLength);
 
                        /* delete the EA only when it exits */
                        if (rc > 0) {
-                               rc = ksmbd_vfs_remove_xattr(path->dentry,
+                               rc = ksmbd_vfs_remove_xattr(mnt_user_ns(path->mnt),
+                                                           path->dentry,
                                                            attr_name);
 
                                if (rc < 0) {
@@ -2102,7 +2104,8 @@ static int smb2_set_ea(struct smb2_ea_info *eabuf, struct path *path)
                        /* if the EA doesn't exist, just do nothing. */
                        rc = 0;
                } else {
-                       rc = ksmbd_vfs_setxattr(path->dentry, attr_name, value,
+                       rc = ksmbd_vfs_setxattr(mnt_user_ns(path->mnt),
+                                               path->dentry, attr_name, value,
                                                le16_to_cpu(eabuf->EaValueLength), 0);
                        if (rc < 0) {
                                ksmbd_debug(SMB,
@@ -2155,7 +2158,8 @@ static noinline int smb2_set_stream_name_xattr(struct path *path,
        fp->stream.size = xattr_stream_size;
 
        /* Check if there is stream prefix in xattr space */
-       rc = ksmbd_vfs_casexattr_len(path->dentry,
+       rc = ksmbd_vfs_casexattr_len(mnt_user_ns(path->mnt),
+                                    path->dentry,
                                     xattr_stream_name,
                                     xattr_stream_size);
        if (rc >= 0)
@@ -2166,7 +2170,8 @@ static noinline int smb2_set_stream_name_xattr(struct path *path,
                return -EBADF;
        }
 
-       rc = ksmbd_vfs_setxattr(path->dentry, xattr_stream_name, NULL, 0, 0);
+       rc = ksmbd_vfs_setxattr(mnt_user_ns(path->mnt),
+                               path->dentry, xattr_stream_name, NULL, 0, 0);
        if (rc < 0)
                pr_err("Failed to store XATTR stream name :%d\n", rc);
        return 0;
@@ -2196,7 +2201,8 @@ static int smb2_remove_smb_xattrs(struct path *path)
                    strncmp(&name[XATTR_USER_PREFIX_LEN], STREAM_PREFIX, STREAM_PREFIX_LEN))
                        continue;
 
-               err = ksmbd_vfs_remove_xattr(path->dentry, name);
+               err = ksmbd_vfs_remove_xattr(mnt_user_ns(path->mnt),
+                                            path->dentry, name);
                if (err)
                        ksmbd_debug(SMB, "remove xattr failed : %s\n", name);
        }
@@ -2240,7 +2246,8 @@ static void smb2_new_xattrs(struct ksmbd_tree_connect *tcon, struct path *path,
        da.flags = XATTR_DOSINFO_ATTRIB | XATTR_DOSINFO_CREATE_TIME |
                XATTR_DOSINFO_ITIME;
 
-       rc = ksmbd_vfs_set_dos_attrib_xattr(path->dentry, &da);
+       rc = ksmbd_vfs_set_dos_attrib_xattr(mnt_user_ns(path->mnt),
+                                           path->dentry, &da);
        if (rc)
                ksmbd_debug(SMB, "failed to store file attribute into xattr\n");
 }
@@ -2258,7 +2265,8 @@ static void smb2_update_xattrs(struct ksmbd_tree_connect *tcon,
                                    KSMBD_SHARE_FLAG_STORE_DOS_ATTRS))
                return;
 
-       rc = ksmbd_vfs_get_dos_attrib_xattr(path->dentry, &da);
+       rc = ksmbd_vfs_get_dos_attrib_xattr(mnt_user_ns(path->mnt),
+                                           path->dentry, &da);
        if (rc > 0) {
                fp->f_ci->m_fattr = cpu_to_le32(da.attr);
                fp->create_time = da.create_time;
@@ -2634,7 +2642,7 @@ int smb2_open(struct ksmbd_work *work)
                rc = 0;
        } else {
                file_present = true;
-               generic_fillattr(&init_user_ns, d_inode(path.dentry), &stat);
+               generic_fillattr(mnt_user_ns(path.mnt), d_inode(path.dentry), &stat);
        }
        if (stream_name) {
                if (req->CreateOptions & FILE_DIRECTORY_FILE_LE) {
@@ -2695,7 +2703,8 @@ int smb2_open(struct ksmbd_work *work)
                if (!file_present) {
                        daccess = cpu_to_le32(GENERIC_ALL_FLAGS);
                } else {
-                       rc = ksmbd_vfs_query_maximal_access(path.dentry,
+                       rc = ksmbd_vfs_query_maximal_access(mnt_user_ns(path.mnt),
+                                                           path.dentry,
                                                            &daccess);
                        if (rc)
                                goto err_out;
@@ -2738,7 +2747,7 @@ int smb2_open(struct ksmbd_work *work)
                 * is already granted.
                 */
                if (daccess & ~(FILE_READ_ATTRIBUTES_LE | FILE_READ_CONTROL_LE)) {
-                       rc = inode_permission(&init_user_ns,
+                       rc = inode_permission(mnt_user_ns(path.mnt),
                                              d_inode(path.dentry),
                                              may_flags);
                        if (rc)
@@ -2746,7 +2755,8 @@ int smb2_open(struct ksmbd_work *work)
 
                        if ((daccess & FILE_DELETE_LE) ||
                            (req->CreateOptions & FILE_DELETE_ON_CLOSE_LE)) {
-                               rc = ksmbd_vfs_may_delete(path.dentry);
+                               rc = ksmbd_vfs_may_delete(mnt_user_ns(path.mnt),
+                                                         path.dentry);
                                if (rc)
                                        goto err_out;
                        }
@@ -2809,7 +2819,9 @@ int smb2_open(struct ksmbd_work *work)
                int posix_acl_rc;
                struct inode *inode = d_inode(path.dentry);
 
-               posix_acl_rc = ksmbd_vfs_inherit_posix_acl(inode, d_inode(path.dentry->d_parent));
+               posix_acl_rc = ksmbd_vfs_inherit_posix_acl(mnt_user_ns(path.mnt),
+                                                          inode,
+                                                          d_inode(path.dentry->d_parent));
                if (posix_acl_rc)
                        ksmbd_debug(SMB, "inherit posix acl failed : %d\n", posix_acl_rc);
 
@@ -2823,7 +2835,8 @@ int smb2_open(struct ksmbd_work *work)
                        rc = smb2_create_sd_buffer(work, req, &path);
                        if (rc) {
                                if (posix_acl_rc)
-                                       ksmbd_vfs_set_init_posix_acl(inode);
+                                       ksmbd_vfs_set_init_posix_acl(mnt_user_ns(path.mnt),
+                                                                    inode);
 
                                if (test_share_config_flag(work->tcon->share_conf,
                                                           KSMBD_SHARE_FLAG_ACL_XATTR)) {
@@ -2845,15 +2858,17 @@ int smb2_open(struct ksmbd_work *work)
                                        if (!pntsd)
                                                goto err_out;
 
-                                       rc = build_sec_desc(pntsd, NULL,
+                                       rc = build_sec_desc(mnt_user_ns(path.mnt),
+                                                           pntsd, NULL,
                                                            OWNER_SECINFO |
-                                                            GROUP_SECINFO |
-                                                            DACL_SECINFO,
+                                                           GROUP_SECINFO |
+                                                           DACL_SECINFO,
                                                            &pntsd_size, &fattr);
                                        posix_acl_release(fattr.cf_acls);
                                        posix_acl_release(fattr.cf_dacls);
 
                                        rc = ksmbd_vfs_set_sd_xattr(conn,
+                                                                   mnt_user_ns(path.mnt),
                                                                    path.dentry,
                                                                    pntsd,
                                                                    pntsd_size);
@@ -2895,7 +2910,7 @@ int smb2_open(struct ksmbd_work *work)
 
        rc = ksmbd_vfs_getattr(&path, &stat);
        if (rc) {
-               generic_fillattr(&init_user_ns, d_inode(path.dentry), &stat);
+               generic_fillattr(mnt_user_ns(path.mnt), d_inode(path.dentry), &stat);
                rc = 0;
        }
 
@@ -2996,7 +3011,8 @@ int smb2_open(struct ksmbd_work *work)
 
        memcpy(fp->client_guid, conn->ClientGUID, SMB2_CLIENT_GUID_SIZE);
 
-       generic_fillattr(&init_user_ns, file_inode(fp->filp), &stat);
+       generic_fillattr(file_mnt_user_ns(fp->filp), file_inode(fp->filp),
+                        &stat);
 
        rsp->StructureSize = cpu_to_le16(89);
        rcu_read_lock();
@@ -3048,7 +3064,8 @@ int smb2_open(struct ksmbd_work *work)
                struct create_context *mxac_ccontext;
 
                if (maximal_access == 0)
-                       ksmbd_vfs_query_maximal_access(path.dentry,
+                       ksmbd_vfs_query_maximal_access(mnt_user_ns(path.mnt),
+                                                      path.dentry,
                                                       &maximal_access);
                mxac_ccontext = (struct create_context *)(rsp->Buffer +
                                le32_to_cpu(rsp->CreateContextsLength));
@@ -3251,6 +3268,7 @@ static int dentry_name(struct ksmbd_dir_info *d_info, int info_level)
  * @conn:      connection instance
  * @info_level:        smb information level
  * @d_info:    structure included variables for query dir
+ * @user_ns:   user namespace
  * @ksmbd_kstat:       ksmbd wrapper of dirent stat information
  *
  * if directory has many entries, find first can't read it fully.
@@ -3260,6 +3278,7 @@ static int dentry_name(struct ksmbd_dir_info *d_info, int info_level)
  */
 static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level,
                                       struct ksmbd_dir_info *d_info,
+                                      struct user_namespace *user_ns,
                                       struct ksmbd_kstat *ksmbd_kstat)
 {
        int next_entry_offset = 0;
@@ -3412,9 +3431,9 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level,
                        S_ISDIR(ksmbd_kstat->kstat->mode) ? ATTR_DIRECTORY_LE : ATTR_ARCHIVE_LE;
                if (d_info->hide_dot_file && d_info->name[0] == '.')
                        posix_info->DosAttributes |= ATTR_HIDDEN_LE;
-               id_to_sid(from_kuid(&init_user_ns, ksmbd_kstat->kstat->uid),
+               id_to_sid(from_kuid(user_ns, ksmbd_kstat->kstat->uid),
                          SIDNFS_USER, (struct smb_sid *)&posix_info->SidBuffer[0]);
-               id_to_sid(from_kgid(&init_user_ns, ksmbd_kstat->kstat->gid),
+               id_to_sid(from_kgid(user_ns, ksmbd_kstat->kstat->gid),
                          SIDNFS_GROUP, (struct smb_sid *)&posix_info->SidBuffer[20]);
                memcpy(posix_info->name, conv_name, conv_len);
                posix_info->name_len = cpu_to_le32(conv_len);
@@ -3496,12 +3515,14 @@ static int process_query_dir_entries(struct smb2_query_dir_private *priv)
                ksmbd_kstat.kstat = &kstat;
                if (priv->info_level != FILE_NAMES_INFORMATION)
                        ksmbd_vfs_fill_dentry_attrs(priv->work,
+                                                   file_mnt_user_ns(priv->dir_fp->filp),
                                                    dent,
                                                    &ksmbd_kstat);
 
                rc = smb2_populate_readdir_entry(priv->work->conn,
                                                 priv->info_level,
                                                 priv->d_info,
+                                                file_mnt_user_ns(priv->dir_fp->filp),
                                                 &ksmbd_kstat);
                dput(dent);
                if (rc)
@@ -3710,7 +3731,8 @@ int smb2_query_dir(struct ksmbd_work *work)
        }
 
        if (!(dir_fp->daccess & FILE_LIST_DIRECTORY_LE) ||
-           inode_permission(&init_user_ns, file_inode(dir_fp->filp),
+           inode_permission(file_mnt_user_ns(dir_fp->filp),
+                            file_inode(dir_fp->filp),
                             MAY_READ | MAY_EXEC)) {
                pr_err("no right to enumerate directory (%pd)\n",
                       dir_fp->filp->f_path.dentry);
@@ -4035,7 +4057,8 @@ static int smb2_get_ea(struct ksmbd_work *work, struct ksmbd_file *fp,
                buf_free_len -= (offsetof(struct smb2_ea_info, name) +
                                name_len + 1);
                /* bailout if xattr can't fit in buf_free_len */
-               value_len = ksmbd_vfs_getxattr(path->dentry, name, &buf);
+               value_len = ksmbd_vfs_getxattr(mnt_user_ns(path->mnt),
+                                              path->dentry, name, &buf);
                if (value_len <= 0) {
                        rc = -ENOENT;
                        rsp->hdr.Status = STATUS_INVALID_HANDLE;
@@ -4124,7 +4147,8 @@ static int get_file_basic_info(struct smb2_query_info_rsp *rsp,
        }
 
        basic_info = (struct smb2_file_all_info *)rsp->Buffer;
-       generic_fillattr(&init_user_ns, file_inode(fp->filp), &stat);
+       generic_fillattr(file_mnt_user_ns(fp->filp), file_inode(fp->filp),
+                        &stat);
        basic_info->CreationTime = cpu_to_le64(fp->create_time);
        time = ksmbd_UnixTimeToNT(stat.atime);
        basic_info->LastAccessTime = cpu_to_le64(time);
@@ -4165,7 +4189,7 @@ static void get_file_standard_info(struct smb2_query_info_rsp *rsp,
        struct kstat stat;
 
        inode = file_inode(fp->filp);
-       generic_fillattr(&init_user_ns, inode, &stat);
+       generic_fillattr(file_mnt_user_ns(fp->filp), inode, &stat);
 
        sinfo = (struct smb2_file_standard_info *)rsp->Buffer;
        delete_pending = ksmbd_inode_pending_delete(fp);
@@ -4220,7 +4244,7 @@ static int get_file_all_info(struct ksmbd_work *work,
                return -ENOMEM;
 
        inode = file_inode(fp->filp);
-       generic_fillattr(&init_user_ns, inode, &stat);
+       generic_fillattr(file_mnt_user_ns(fp->filp), inode, &stat);
 
        ksmbd_debug(SMB, "filename = %s\n", filename);
        delete_pending = ksmbd_inode_pending_delete(fp);
@@ -4295,7 +4319,8 @@ static void get_file_stream_info(struct ksmbd_work *work,
        ssize_t xattr_list_len;
        int nbytes = 0, streamlen, stream_name_len, next, idx = 0;
 
-       generic_fillattr(&init_user_ns, file_inode(fp->filp), &stat);
+       generic_fillattr(file_mnt_user_ns(fp->filp), file_inode(fp->filp),
+                        &stat);
        file_info = (struct smb2_file_stream_info *)rsp->Buffer;
 
        xattr_list_len = ksmbd_vfs_listxattr(path->dentry, &xattr_list);
@@ -4374,7 +4399,8 @@ static void get_file_internal_info(struct smb2_query_info_rsp *rsp,
        struct smb2_file_internal_info *file_info;
        struct kstat stat;
 
-       generic_fillattr(&init_user_ns, file_inode(fp->filp), &stat);
+       generic_fillattr(file_mnt_user_ns(fp->filp), file_inode(fp->filp),
+                        &stat);
        file_info = (struct smb2_file_internal_info *)rsp->Buffer;
        file_info->IndexNumber = cpu_to_le64(stat.ino);
        rsp->OutputBufferLength =
@@ -4399,7 +4425,7 @@ static int get_file_network_open_info(struct smb2_query_info_rsp *rsp,
        file_info = (struct smb2_file_ntwrk_info *)rsp->Buffer;
 
        inode = file_inode(fp->filp);
-       generic_fillattr(&init_user_ns, inode, &stat);
+       generic_fillattr(file_mnt_user_ns(fp->filp), inode, &stat);
 
        file_info->CreationTime = cpu_to_le64(fp->create_time);
        time = ksmbd_UnixTimeToNT(stat.atime);
@@ -4460,7 +4486,8 @@ static void get_file_compression_info(struct smb2_query_info_rsp *rsp,
        struct smb2_file_comp_info *file_info;
        struct kstat stat;
 
-       generic_fillattr(&init_user_ns, file_inode(fp->filp), &stat);
+       generic_fillattr(file_mnt_user_ns(fp->filp), file_inode(fp->filp),
+                        &stat);
 
        file_info = (struct smb2_file_comp_info *)rsp->Buffer;
        file_info->CompressedFileSize = cpu_to_le64(stat.blocks << 9);
@@ -4933,9 +4960,11 @@ static int smb2_get_info_sec(struct ksmbd_work *work,
 
        if (test_share_config_flag(work->tcon->share_conf,
                                   KSMBD_SHARE_FLAG_ACL_XATTR))
-               ksmbd_vfs_get_sd_xattr(work->conn, fp->filp->f_path.dentry, &ppntsd);
+               ksmbd_vfs_get_sd_xattr(work->conn, file_mnt_user_ns(fp->filp),
+                                      fp->filp->f_path.dentry, &ppntsd);
 
-       rc = build_sec_desc(pntsd, ppntsd, addition_info, &secdesclen, &fattr);
+       rc = build_sec_desc(file_mnt_user_ns(fp->filp),
+                           pntsd, ppntsd, addition_info, &secdesclen, &fattr);
        posix_acl_release(fattr.cf_acls);
        posix_acl_release(fattr.cf_dacls);
        kfree(ppntsd);
@@ -5228,7 +5257,8 @@ static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
                if (rc)
                        goto out;
 
-               rc = ksmbd_vfs_setxattr(fp->filp->f_path.dentry,
+               rc = ksmbd_vfs_setxattr(file_mnt_user_ns(fp->filp),
+                                       fp->filp->f_path.dentry,
                                        xattr_stream_name,
                                        NULL, 0, 0);
                if (rc < 0) {
@@ -5412,7 +5442,8 @@ static int set_file_basic_info(struct ksmbd_file *fp, char *buf,
                da.flags = XATTR_DOSINFO_ATTRIB | XATTR_DOSINFO_CREATE_TIME |
                        XATTR_DOSINFO_ITIME;
 
-               rc = ksmbd_vfs_set_dos_attrib_xattr(filp->f_path.dentry, &da);
+               rc = ksmbd_vfs_set_dos_attrib_xattr(file_mnt_user_ns(filp),
+                                                   filp->f_path.dentry, &da);
                if (rc)
                        ksmbd_debug(SMB,
                                    "failed to restore file attribute in EA\n");
@@ -5433,14 +5464,14 @@ static int set_file_basic_info(struct ksmbd_file *fp, char *buf,
                if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
                        return -EACCES;
 
-               rc = setattr_prepare(&init_user_ns, dentry, &attrs);
+               rc = setattr_prepare(file_mnt_user_ns(filp), dentry, &attrs);
                if (rc)
                        return -EINVAL;
 
                inode_lock(inode);
-               setattr_copy(&init_user_ns, inode, &attrs);
+               setattr_copy(file_mnt_user_ns(filp), inode, &attrs);
                attrs.ia_valid &= ~ATTR_CTIME;
-               rc = notify_change(&init_user_ns, dentry, &attrs, NULL);
+               rc = notify_change(file_mnt_user_ns(filp), dentry, &attrs, NULL);
                inode_unlock(inode);
        }
        return 0;
@@ -7188,12 +7219,14 @@ static inline int fsctl_set_sparse(struct ksmbd_work *work, u64 id,
                                   KSMBD_SHARE_FLAG_STORE_DOS_ATTRS)) {
                struct xattr_dos_attrib da;
 
-               ret = ksmbd_vfs_get_dos_attrib_xattr(fp->filp->f_path.dentry, &da);
+               ret = ksmbd_vfs_get_dos_attrib_xattr(file_mnt_user_ns(fp->filp),
+                                                    fp->filp->f_path.dentry, &da);
                if (ret <= 0)
                        goto out;
 
                da.attr = le32_to_cpu(fp->f_ci->m_fattr);
-               ret = ksmbd_vfs_set_dos_attrib_xattr(fp->filp->f_path.dentry, &da);
+               ret = ksmbd_vfs_set_dos_attrib_xattr(file_mnt_user_ns(fp->filp),
+                                                    fp->filp->f_path.dentry, &da);
                if (ret)
                        fp->f_ci->m_fattr = old_fattr;
        }
index b573575..f770f3f 100644 (file)
@@ -274,6 +274,7 @@ int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, int info_level,
                                      char *search_pattern,
                                      int (*fn)(struct ksmbd_conn *, int,
                                                struct ksmbd_dir_info *,
+                                               struct user_namespace *,
                                                struct ksmbd_kstat *))
 {
        int i, rc = 0;
@@ -300,9 +301,11 @@ int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, int info_level,
 
                        ksmbd_kstat.kstat = &kstat;
                        ksmbd_vfs_fill_dentry_attrs(work,
+                                                   file_mnt_user_ns(dir->filp),
                                                    dir->filp->f_path.dentry->d_parent,
                                                    &ksmbd_kstat);
-                       rc = fn(conn, info_level, d_info, &ksmbd_kstat);
+                       rc = fn(conn, info_level, d_info,
+                               file_mnt_user_ns(dir->filp), &ksmbd_kstat);
                        if (rc)
                                break;
                        if (d_info->out_buf_len <= 0)
index 8489b92..6ab28aa 100644 (file)
@@ -514,6 +514,7 @@ int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work,
                                      int (*fn)(struct ksmbd_conn *,
                                                int,
                                                struct ksmbd_dir_info *,
+                                               struct user_namespace *,
                                                struct ksmbd_kstat *));
 
 int ksmbd_extract_shortname(struct ksmbd_conn *conn,
index e0825d3..4ee714b 100644 (file)
@@ -253,7 +253,8 @@ void id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid)
        ssid->num_subauth++;
 }
 
-static int sid_to_id(struct smb_sid *psid, uint sidtype,
+static int sid_to_id(struct user_namespace *user_ns,
+                    struct smb_sid *psid, uint sidtype,
                     struct smb_fattr *fattr)
 {
        int rc = -EINVAL;
@@ -274,8 +275,8 @@ static int sid_to_id(struct smb_sid *psid, uint sidtype,
 
                id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
                if (id > 0) {
-                       uid = make_kuid(&init_user_ns, id);
-                       if (uid_valid(uid) && kuid_has_mapping(&init_user_ns, uid)) {
+                       uid = make_kuid(user_ns, id);
+                       if (uid_valid(uid) && kuid_has_mapping(user_ns, uid)) {
                                fattr->cf_uid = uid;
                                rc = 0;
                        }
@@ -286,8 +287,8 @@ static int sid_to_id(struct smb_sid *psid, uint sidtype,
 
                id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
                if (id > 0) {
-                       gid = make_kgid(&init_user_ns, id);
-                       if (gid_valid(gid) && kgid_has_mapping(&init_user_ns, gid)) {
+                       gid = make_kgid(user_ns, id);
+                       if (gid_valid(gid) && kgid_has_mapping(user_ns, gid)) {
                                fattr->cf_gid = gid;
                                rc = 0;
                        }
@@ -362,7 +363,8 @@ void free_acl_state(struct posix_acl_state *state)
        kfree(state->groups);
 }
 
-static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
+static void parse_dacl(struct user_namespace *user_ns,
+                      struct smb_acl *pdacl, char *end_of_acl,
                       struct smb_sid *pownersid, struct smb_sid *pgrpsid,
                       struct smb_fattr *fattr)
 {
@@ -474,7 +476,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
                        acl_mode = access_flags_to_mode(fattr, ppace[i]->access_req,
                                                        ppace[i]->type);
                        temp_fattr.cf_uid = INVALID_UID;
-                       ret = sid_to_id(&ppace[i]->sid, SIDOWNER, &temp_fattr);
+                       ret = sid_to_id(user_ns, &ppace[i]->sid, SIDOWNER, &temp_fattr);
                        if (ret || uid_eq(temp_fattr.cf_uid, INVALID_UID)) {
                                pr_err("%s: Error %d mapping Owner SID to uid\n",
                                       __func__, ret);
@@ -553,7 +555,8 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
        free_acl_state(&default_acl_state);
 }
 
-static void set_posix_acl_entries_dacl(struct smb_ace *pndace,
+static void set_posix_acl_entries_dacl(struct user_namespace *user_ns,
+                                      struct smb_ace *pndace,
                                       struct smb_fattr *fattr, u32 *num_aces,
                                       u16 *size, u32 nt_aces_num)
 {
@@ -577,14 +580,14 @@ static void set_posix_acl_entries_dacl(struct smb_ace *pndace,
                        uid_t uid;
                        unsigned int sid_type = SIDOWNER;
 
-                       uid = from_kuid(&init_user_ns, pace->e_uid);
+                       uid = from_kuid(user_ns, pace->e_uid);
                        if (!uid)
                                sid_type = SIDUNIX_USER;
                        id_to_sid(uid, sid_type, sid);
                } else if (pace->e_tag == ACL_GROUP) {
                        gid_t gid;
 
-                       gid = from_kgid(&init_user_ns, pace->e_gid);
+                       gid = from_kgid(user_ns, pace->e_gid);
                        id_to_sid(gid, SIDUNIX_GROUP, sid);
                } else if (pace->e_tag == ACL_OTHER && !nt_aces_num) {
                        smb_copy_sid(sid, &sid_everyone);
@@ -643,12 +646,12 @@ posix_default_acl:
                if (pace->e_tag == ACL_USER) {
                        uid_t uid;
 
-                       uid = from_kuid(&init_user_ns, pace->e_uid);
+                       uid = from_kuid(user_ns, pace->e_uid);
                        id_to_sid(uid, SIDCREATOR_OWNER, sid);
                } else if (pace->e_tag == ACL_GROUP) {
                        gid_t gid;
 
-                       gid = from_kgid(&init_user_ns, pace->e_gid);
+                       gid = from_kgid(user_ns, pace->e_gid);
                        id_to_sid(gid, SIDCREATOR_GROUP, sid);
                } else {
                        kfree(sid);
@@ -666,7 +669,9 @@ posix_default_acl:
        }
 }
 
-static void set_ntacl_dacl(struct smb_acl *pndacl, struct smb_acl *nt_dacl,
+static void set_ntacl_dacl(struct user_namespace *user_ns,
+                          struct smb_acl *pndacl,
+                          struct smb_acl *nt_dacl,
                           const struct smb_sid *pownersid,
                           const struct smb_sid *pgrpsid,
                           struct smb_fattr *fattr)
@@ -687,12 +692,14 @@ static void set_ntacl_dacl(struct smb_acl *pndacl, struct smb_acl *nt_dacl,
                }
        }
 
-       set_posix_acl_entries_dacl(pndace, fattr, &num_aces, &size, nt_num_aces);
+       set_posix_acl_entries_dacl(user_ns, pndace, fattr,
+                                  &num_aces, &size, nt_num_aces);
        pndacl->num_aces = cpu_to_le32(num_aces);
        pndacl->size = cpu_to_le16(le16_to_cpu(pndacl->size) + size);
 }
 
-static void set_mode_dacl(struct smb_acl *pndacl, struct smb_fattr *fattr)
+static void set_mode_dacl(struct user_namespace *user_ns,
+                         struct smb_acl *pndacl, struct smb_fattr *fattr)
 {
        struct smb_ace *pace, *pndace;
        u32 num_aces = 0;
@@ -703,12 +710,13 @@ static void set_mode_dacl(struct smb_acl *pndacl, struct smb_fattr *fattr)
        pace = pndace = (struct smb_ace *)((char *)pndacl + sizeof(struct smb_acl));
 
        if (fattr->cf_acls) {
-               set_posix_acl_entries_dacl(pndace, fattr, &num_aces, &size, num_aces);
+               set_posix_acl_entries_dacl(user_ns, pndace, fattr,
+                                          &num_aces, &size, num_aces);
                goto out;
        }
 
        /* owner RID */
-       uid = from_kuid(&init_user_ns, fattr->cf_uid);
+       uid = from_kuid(user_ns, fattr->cf_uid);
        if (uid)
                sid = &server_conf.domain_sid;
        else
@@ -725,7 +733,7 @@ static void set_mode_dacl(struct smb_acl *pndacl, struct smb_fattr *fattr)
        ace_size = fill_ace_for_sid(pace, &sid_unix_groups,
                                    ACCESS_ALLOWED, 0, fattr->cf_mode, 0070);
        pace->sid.sub_auth[pace->sid.num_subauth++] =
-               cpu_to_le32(from_kgid(&init_user_ns, fattr->cf_gid));
+               cpu_to_le32(from_kgid(user_ns, fattr->cf_gid));
        pace->size = cpu_to_le16(ace_size + 4);
        size += le16_to_cpu(pace->size);
        pace = (struct smb_ace *)((char *)pndace + size);
@@ -771,8 +779,8 @@ static int parse_sid(struct smb_sid *psid, char *end_of_acl)
 }
 
 /* Convert CIFS ACL to POSIX form */
-int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len,
-                  struct smb_fattr *fattr)
+int parse_sec_desc(struct user_namespace *user_ns, struct smb_ntsd *pntsd,
+                  int acl_len, struct smb_fattr *fattr)
 {
        int rc = 0;
        struct smb_sid *owner_sid_ptr, *group_sid_ptr;
@@ -811,7 +819,7 @@ int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len,
                        return rc;
                }
 
-               rc = sid_to_id(owner_sid_ptr, SIDOWNER, fattr);
+               rc = sid_to_id(user_ns, owner_sid_ptr, SIDOWNER, fattr);
                if (rc) {
                        pr_err("%s: Error %d mapping Owner SID to uid\n",
                               __func__, rc);
@@ -826,7 +834,7 @@ int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len,
                               __func__, rc);
                        return rc;
                }
-               rc = sid_to_id(group_sid_ptr, SIDUNIX_GROUP, fattr);
+               rc = sid_to_id(user_ns, group_sid_ptr, SIDUNIX_GROUP, fattr);
                if (rc) {
                        pr_err("%s: Error %d mapping Group SID to gid\n",
                               __func__, rc);
@@ -841,15 +849,16 @@ int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len,
                pntsd->type |= cpu_to_le16(DACL_PROTECTED);
 
        if (dacloffset) {
-               parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, group_sid_ptr,
-                          fattr);
+               parse_dacl(user_ns, dacl_ptr, end_of_acl,
+                          owner_sid_ptr, group_sid_ptr, fattr);
        }
 
        return 0;
 }
 
 /* Convert permission bits from mode to equivalent CIFS ACL */
-int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd,
+int build_sec_desc(struct user_namespace *user_ns,
+                  struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd,
                   int addition_info, __u32 *secdesclen,
                   struct smb_fattr *fattr)
 {
@@ -866,7 +875,7 @@ int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd,
        if (!nowner_sid_ptr)
                return -ENOMEM;
 
-       uid = from_kuid(&init_user_ns, fattr->cf_uid);
+       uid = from_kuid(user_ns, fattr->cf_uid);
        if (!uid)
                sid_type = SIDUNIX_USER;
        id_to_sid(uid, sid_type, nowner_sid_ptr);
@@ -877,7 +886,7 @@ int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd,
                return -ENOMEM;
        }
 
-       gid = from_kgid(&init_user_ns, fattr->cf_gid);
+       gid = from_kgid(user_ns, fattr->cf_gid);
        id_to_sid(gid, SIDUNIX_GROUP, ngroup_sid_ptr);
 
        offset = sizeof(struct smb_ntsd);
@@ -909,7 +918,7 @@ int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd,
                dacl_ptr->num_aces = 0;
 
                if (!ppntsd) {
-                       set_mode_dacl(dacl_ptr, fattr);
+                       set_mode_dacl(user_ns, dacl_ptr, fattr);
                } else if (!ppntsd->dacloffset) {
                        goto out;
                } else {
@@ -917,8 +926,8 @@ int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd,
 
                        ppdacl_ptr = (struct smb_acl *)((char *)ppntsd +
                                                le32_to_cpu(ppntsd->dacloffset));
-                       set_ntacl_dacl(dacl_ptr, ppdacl_ptr, nowner_sid_ptr,
-                                      ngroup_sid_ptr, fattr);
+                       set_ntacl_dacl(user_ns, dacl_ptr, ppdacl_ptr,
+                                      nowner_sid_ptr, ngroup_sid_ptr, fattr);
                }
                pntsd->dacloffset = cpu_to_le32(offset);
                offset += le16_to_cpu(dacl_ptr->size);
@@ -956,7 +965,8 @@ int smb_inherit_dacl(struct ksmbd_conn *conn,
        char *aces_base;
        bool is_dir = S_ISDIR(d_inode(path->dentry)->i_mode);
 
-       acl_len = ksmbd_vfs_get_sd_xattr(conn, parent, &parent_pntsd);
+       acl_len = ksmbd_vfs_get_sd_xattr(conn, mnt_user_ns(path->mnt),
+                                        parent, &parent_pntsd);
        if (acl_len <= 0)
                return rc;
        dacloffset = le32_to_cpu(parent_pntsd->dacloffset);
@@ -1087,7 +1097,8 @@ pass:
                        pntsd_size += sizeof(struct smb_acl) + nt_size;
                }
 
-               ksmbd_vfs_set_sd_xattr(conn, path->dentry, pntsd, pntsd_size);
+               ksmbd_vfs_set_sd_xattr(conn, mnt_user_ns(path->mnt),
+                                      path->dentry, pntsd, pntsd_size);
                kfree(pntsd);
                rc = 0;
        }
@@ -1128,7 +1139,8 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, struct path *path,
        char *end_of_acl;
 
        ksmbd_debug(SMB, "check permission using windows acl\n");
-       acl_size = ksmbd_vfs_get_sd_xattr(conn, path->dentry, &pntsd);
+       acl_size = ksmbd_vfs_get_sd_xattr(conn, mnt_user_ns(path->mnt),
+                                         path->dentry, &pntsd);
        if (acl_size <= 0 || !pntsd || !pntsd->dacloffset) {
                kfree(pntsd);
                return 0;
@@ -1209,9 +1221,11 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, struct path *path,
                pa_entry = posix_acls->a_entries;
                for (i = 0; i < posix_acls->a_count; i++, pa_entry++) {
                        if (pa_entry->e_tag == ACL_USER)
-                               id = from_kuid(&init_user_ns, pa_entry->e_uid);
+                               id = from_kuid(mnt_user_ns(path->mnt),
+                                              pa_entry->e_uid);
                        else if (pa_entry->e_tag == ACL_GROUP)
-                               id = from_kgid(&init_user_ns, pa_entry->e_gid);
+                               id = from_kgid(mnt_user_ns(path->mnt),
+                                              pa_entry->e_gid);
                        else
                                continue;
 
@@ -1273,7 +1287,7 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
        fattr.cf_gid = INVALID_GID;
        fattr.cf_mode = inode->i_mode;
 
-       rc = parse_sec_desc(pntsd, ntsd_len, &fattr);
+       rc = parse_sec_desc(mnt_user_ns(path->mnt), pntsd, ntsd_len, &fattr);
        if (rc)
                goto out;
 
@@ -1284,13 +1298,13 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
                inode->i_gid = fattr.cf_gid;
        mark_inode_dirty(inode);
 
-       ksmbd_vfs_remove_acl_xattrs(path->dentry);
+       ksmbd_vfs_remove_acl_xattrs(mnt_user_ns(path->mnt), path->dentry);
        /* Update posix acls */
        if (fattr.cf_dacls) {
-               rc = set_posix_acl(&init_user_ns, inode, ACL_TYPE_ACCESS,
-                                  fattr.cf_acls);
+               rc = set_posix_acl(mnt_user_ns(path->mnt), inode,
+                                  ACL_TYPE_ACCESS, fattr.cf_acls);
                if (S_ISDIR(inode->i_mode) && fattr.cf_dacls)
-                       rc = set_posix_acl(&init_user_ns, inode,
+                       rc = set_posix_acl(mnt_user_ns(path->mnt), inode,
                                           ACL_TYPE_DEFAULT, fattr.cf_dacls);
        }
 
@@ -1300,8 +1314,9 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
 
        if (test_share_config_flag(tcon->share_conf, KSMBD_SHARE_FLAG_ACL_XATTR)) {
                /* Update WinACL in xattr */
-               ksmbd_vfs_remove_sd_xattrs(path->dentry);
-               ksmbd_vfs_set_sd_xattr(conn, path->dentry, pntsd, ntsd_len);
+               ksmbd_vfs_remove_sd_xattrs(mnt_user_ns(path->mnt), path->dentry);
+               ksmbd_vfs_set_sd_xattr(conn, mnt_user_ns(path->mnt),
+                                      path->dentry, pntsd, ntsd_len);
        }
 
 out:
index 4ee7bda..940f686 100644 (file)
@@ -189,11 +189,11 @@ struct posix_acl_state {
        struct posix_ace_state_array *groups;
 };
 
-int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len,
-                  struct smb_fattr *fattr);
-int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd,
-                  int addition_info, __u32 *secdesclen,
-                  struct smb_fattr *fattr);
+int parse_sec_desc(struct user_namespace *user_ns, struct smb_ntsd *pntsd,
+                  int acl_len, struct smb_fattr *fattr);
+int build_sec_desc(struct user_namespace *user_ns, struct smb_ntsd *pntsd,
+                  struct smb_ntsd *ppntsd, int addition_info,
+                  __u32 *secdesclen, struct smb_fattr *fattr);
 int init_acl_state(struct posix_acl_state *state, int cnt);
 void free_acl_state(struct posix_acl_state *state);
 void posix_state_to_acl(struct posix_acl_state *state,
index 7021662..0f5a4fb 100644 (file)
@@ -95,7 +95,8 @@ out_err:
        return ret;
 }
 
-int ksmbd_vfs_may_delete(struct dentry *dentry)
+int ksmbd_vfs_may_delete(struct user_namespace *user_ns,
+                        struct dentry *dentry)
 {
        struct dentry *parent;
        int ret;
@@ -107,7 +108,7 @@ int ksmbd_vfs_may_delete(struct dentry *dentry)
                return ret;
        }
 
-       ret = inode_permission(&init_user_ns, d_inode(parent),
+       ret = inode_permission(user_ns, d_inode(parent),
                               MAY_EXEC | MAY_WRITE);
 
        inode_unlock(d_inode(parent));
@@ -115,23 +116,24 @@ int ksmbd_vfs_may_delete(struct dentry *dentry)
        return ret;
 }
 
-int ksmbd_vfs_query_maximal_access(struct dentry *dentry, __le32 *daccess)
+int ksmbd_vfs_query_maximal_access(struct user_namespace *user_ns,
+                                  struct dentry *dentry, __le32 *daccess)
 {
        struct dentry *parent;
        int ret = 0;
 
        *daccess = cpu_to_le32(FILE_READ_ATTRIBUTES | READ_CONTROL);
 
-       if (!inode_permission(&init_user_ns, d_inode(dentry), MAY_OPEN | MAY_WRITE))
+       if (!inode_permission(user_ns, d_inode(dentry), MAY_OPEN | MAY_WRITE))
                *daccess |= cpu_to_le32(WRITE_DAC | WRITE_OWNER | SYNCHRONIZE |
                                FILE_WRITE_DATA | FILE_APPEND_DATA |
                                FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES |
                                FILE_DELETE_CHILD);
 
-       if (!inode_permission(&init_user_ns, d_inode(dentry), MAY_OPEN | MAY_READ))
+       if (!inode_permission(user_ns, d_inode(dentry), MAY_OPEN | MAY_READ))
                *daccess |= FILE_READ_DATA_LE | FILE_READ_EA_LE;
 
-       if (!inode_permission(&init_user_ns, d_inode(dentry), MAY_OPEN | MAY_EXEC))
+       if (!inode_permission(user_ns, d_inode(dentry), MAY_OPEN | MAY_EXEC))
                *daccess |= FILE_EXECUTE_LE;
 
        parent = dget_parent(dentry);
@@ -141,7 +143,7 @@ int ksmbd_vfs_query_maximal_access(struct dentry *dentry, __le32 *daccess)
                return ret;
        }
 
-       if (!inode_permission(&init_user_ns, d_inode(parent), MAY_EXEC | MAY_WRITE))
+       if (!inode_permission(user_ns, d_inode(parent), MAY_EXEC | MAY_WRITE))
                *daccess |= FILE_DELETE_LE;
 
        inode_unlock(d_inode(parent));
@@ -173,7 +175,8 @@ int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mode)
        }
 
        mode |= S_IFREG;
-       err = vfs_create(&init_user_ns, d_inode(path.dentry), dentry, mode, true);
+       err = vfs_create(mnt_user_ns(path.mnt), d_inode(path.dentry),
+                        dentry, mode, true);
        if (!err) {
                ksmbd_vfs_inherit_owner(work, d_inode(path.dentry),
                                        d_inode(dentry));
@@ -208,7 +211,8 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode)
        }
 
        mode |= S_IFDIR;
-       err = vfs_mkdir(&init_user_ns, d_inode(path.dentry), dentry, mode);
+       err = vfs_mkdir(mnt_user_ns(path.mnt), d_inode(path.dentry),
+                       dentry, mode);
        if (err) {
                goto out;
        } else if (d_unhashed(dentry)) {
@@ -236,7 +240,8 @@ out:
        return err;
 }
 
-static ssize_t ksmbd_vfs_getcasexattr(struct dentry *dentry, char *attr_name,
+static ssize_t ksmbd_vfs_getcasexattr(struct user_namespace *user_ns,
+                                     struct dentry *dentry, char *attr_name,
                                      int attr_name_len, char **attr_value)
 {
        char *name, *xattr_list = NULL;
@@ -252,7 +257,8 @@ static ssize_t ksmbd_vfs_getcasexattr(struct dentry *dentry, char *attr_name,
                if (strncasecmp(attr_name, name, attr_name_len))
                        continue;
 
-               value_len = ksmbd_vfs_getxattr(dentry,
+               value_len = ksmbd_vfs_getxattr(user_ns,
+                                              dentry,
                                               name,
                                               attr_value);
                if (value_len < 0)
@@ -274,7 +280,8 @@ static int ksmbd_vfs_stream_read(struct ksmbd_file *fp, char *buf, loff_t *pos,
        ksmbd_debug(VFS, "read stream data pos : %llu, count : %zd\n",
                    *pos, count);
 
-       v_len = ksmbd_vfs_getcasexattr(fp->filp->f_path.dentry,
+       v_len = ksmbd_vfs_getcasexattr(file_mnt_user_ns(fp->filp),
+                                      fp->filp->f_path.dentry,
                                       fp->stream.name,
                                       fp->stream.size,
                                       &stream_buf);
@@ -411,7 +418,8 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos,
                count = (*pos + count) - XATTR_SIZE_MAX;
        }
 
-       v_len = ksmbd_vfs_getcasexattr(fp->filp->f_path.dentry,
+       v_len = ksmbd_vfs_getcasexattr(file_mnt_user_ns(fp->filp),
+                                      fp->filp->f_path.dentry,
                                       fp->stream.name,
                                       fp->stream.size,
                                       &stream_buf);
@@ -436,7 +444,8 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos,
 
        memcpy(&stream_buf[*pos], buf, count);
 
-       err = ksmbd_vfs_setxattr(fp->filp->f_path.dentry,
+       err = ksmbd_vfs_setxattr(file_mnt_user_ns(fp->filp),
+                                fp->filp->f_path.dentry,
                                 fp->stream.name,
                                 (void *)stream_buf,
                                 size,
@@ -606,13 +615,14 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name)
        }
 
        if (S_ISDIR(d_inode(path.dentry)->i_mode)) {
-               err = vfs_rmdir(&init_user_ns, d_inode(parent), path.dentry);
+               err = vfs_rmdir(mnt_user_ns(path.mnt), d_inode(parent),
+                               path.dentry);
                if (err && err != -ENOTEMPTY)
                        ksmbd_debug(VFS, "%s: rmdir failed, err %d\n", name,
                                    err);
        } else {
-               err = vfs_unlink(&init_user_ns, d_inode(parent), path.dentry,
-                                NULL);
+               err = vfs_unlink(mnt_user_ns(path.mnt), d_inode(parent),
+                                path.dentry, NULL);
                if (err)
                        ksmbd_debug(VFS, "%s: unlink failed, err %d\n", name,
                                    err);
@@ -669,7 +679,8 @@ int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname,
                goto out3;
        }
 
-       err = vfs_link(oldpath.dentry, &init_user_ns, d_inode(newpath.dentry),
+       err = vfs_link(oldpath.dentry, mnt_user_ns(newpath.mnt),
+                      d_inode(newpath.dentry),
                       dentry, NULL);
        if (err)
                ksmbd_debug(VFS, "vfs_link failed err %d\n", err);
@@ -707,8 +718,10 @@ static int ksmbd_validate_entry_in_use(struct dentry *src_dent)
 }
 
 static int __ksmbd_vfs_rename(struct ksmbd_work *work,
+                             struct user_namespace *src_user_ns,
                              struct dentry *src_dent_parent,
                              struct dentry *src_dent,
+                             struct user_namespace *dst_user_ns,
                              struct dentry *dst_dent_parent,
                              struct dentry *trap_dent,
                              char *dst_name)
@@ -744,10 +757,10 @@ static int __ksmbd_vfs_rename(struct ksmbd_work *work,
        err = -ENOTEMPTY;
        if (dst_dent != trap_dent && !d_really_is_positive(dst_dent)) {
                struct renamedata rd = {
-                       .old_mnt_userns = &init_user_ns,
+                       .old_mnt_userns = src_user_ns,
                        .old_dir        = d_inode(src_dent_parent),
                        .old_dentry     = src_dent,
-                       .new_mnt_userns = &init_user_ns,
+                       .new_mnt_userns = dst_user_ns,
                        .new_dir        = d_inode(dst_dent_parent),
                        .new_dentry     = dst_dent,
                };
@@ -809,8 +822,10 @@ int ksmbd_vfs_fp_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
        dput(src_child);
 
        err = __ksmbd_vfs_rename(work,
+                                file_mnt_user_ns(fp->filp),
                                 src_dent_parent,
                                 src_dent,
+                                mnt_user_ns(dst_path.mnt),
                                 dst_dent_parent,
                                 trap_dent,
                                 dst_name);
@@ -917,27 +932,30 @@ ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char **list)
        return size;
 }
 
-static ssize_t ksmbd_vfs_xattr_len(struct dentry *dentry, char *xattr_name)
+static ssize_t ksmbd_vfs_xattr_len(struct user_namespace *user_ns,
+                                  struct dentry *dentry, char *xattr_name)
 {
-       return vfs_getxattr(&init_user_ns, dentry, xattr_name, NULL, 0);
+       return vfs_getxattr(user_ns, dentry, xattr_name, NULL, 0);
 }
 
 /**
  * ksmbd_vfs_getxattr() - vfs helper for smb get extended attributes value
+ * @user_ns:   user namespace
  * @dentry:    dentry of file for getting xattrs
  * @xattr_name:        name of xattr name to query
  * @xattr_buf: destination buffer xattr value
  *
  * Return:     read xattr value length on success, otherwise error
  */
-ssize_t ksmbd_vfs_getxattr(struct dentry *dentry, char *xattr_name,
-                          char **xattr_buf)
+ssize_t ksmbd_vfs_getxattr(struct user_namespace *user_ns,
+                          struct dentry *dentry,
+                          char *xattr_name, char **xattr_buf)
 {
        ssize_t xattr_len;
        char *buf;
 
        *xattr_buf = NULL;
-       xattr_len = ksmbd_vfs_xattr_len(dentry, xattr_name);
+       xattr_len = ksmbd_vfs_xattr_len(user_ns, dentry, xattr_name);
        if (xattr_len < 0)
                return xattr_len;
 
@@ -945,7 +963,7 @@ ssize_t ksmbd_vfs_getxattr(struct dentry *dentry, char *xattr_name,
        if (!buf)
                return -ENOMEM;
 
-       xattr_len = vfs_getxattr(&init_user_ns, dentry, xattr_name,
+       xattr_len = vfs_getxattr(user_ns, dentry, xattr_name,
                                 (void *)buf, xattr_len);
        if (xattr_len > 0)
                *xattr_buf = buf;
@@ -956,6 +974,7 @@ ssize_t ksmbd_vfs_getxattr(struct dentry *dentry, char *xattr_name,
 
 /**
  * ksmbd_vfs_setxattr() - vfs helper for smb set extended attributes value
+ * @user_ns:   user namespace
  * @dentry:    dentry to set XATTR at
  * @name:      xattr name for setxattr
  * @value:     xattr value to set
@@ -964,12 +983,14 @@ ssize_t ksmbd_vfs_getxattr(struct dentry *dentry, char *xattr_name,
  *
  * Return:     0 on success, otherwise error
  */
-int ksmbd_vfs_setxattr(struct dentry *dentry, const char *attr_name,
+int ksmbd_vfs_setxattr(struct user_namespace *user_ns,
+                      struct dentry *dentry, const char *attr_name,
                       const void *attr_value, size_t attr_size, int flags)
 {
        int err;
 
-       err = vfs_setxattr(&init_user_ns, dentry,
+       err = vfs_setxattr(user_ns,
+                          dentry,
                           attr_name,
                           attr_value,
                           attr_size,
@@ -1076,12 +1097,14 @@ int ksmbd_vfs_fqar_lseek(struct ksmbd_file *fp, loff_t start, loff_t length,
        return ret;
 }
 
-int ksmbd_vfs_remove_xattr(struct dentry *dentry, char *attr_name)
+int ksmbd_vfs_remove_xattr(struct user_namespace *user_ns,
+                          struct dentry *dentry, char *attr_name)
 {
-       return vfs_removexattr(&init_user_ns, dentry, attr_name);
+       return vfs_removexattr(user_ns, dentry, attr_name);
 }
 
-int ksmbd_vfs_unlink(struct dentry *dir, struct dentry *dentry)
+int ksmbd_vfs_unlink(struct user_namespace *user_ns,
+                    struct dentry *dir, struct dentry *dentry)
 {
        int err = 0;
 
@@ -1091,9 +1114,9 @@ int ksmbd_vfs_unlink(struct dentry *dir, struct dentry *dentry)
        dget(dentry);
 
        if (S_ISDIR(d_inode(dentry)->i_mode))
-               err = vfs_rmdir(&init_user_ns, d_inode(dir), dentry);
+               err = vfs_rmdir(user_ns, d_inode(dir), dentry);
        else
-               err = vfs_unlink(&init_user_ns, d_inode(dir), dentry, NULL);
+               err = vfs_unlink(user_ns, d_inode(dir), dentry, NULL);
 
        dput(dentry);
        inode_unlock(d_inode(dir));
@@ -1267,7 +1290,8 @@ out:
        return err;
 }
 
-int ksmbd_vfs_remove_acl_xattrs(struct dentry *dentry)
+int ksmbd_vfs_remove_acl_xattrs(struct user_namespace *user_ns,
+                               struct dentry *dentry)
 {
        char *name, *xattr_list = NULL;
        ssize_t xattr_list_len;
@@ -1289,7 +1313,7 @@ int ksmbd_vfs_remove_acl_xattrs(struct dentry *dentry)
                             sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1) ||
                    !strncmp(name, XATTR_NAME_POSIX_ACL_DEFAULT,
                             sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1)) {
-                       err = ksmbd_vfs_remove_xattr(dentry, name);
+                       err = ksmbd_vfs_remove_xattr(user_ns, dentry, name);
                        if (err)
                                ksmbd_debug(SMB,
                                            "remove acl xattr failed : %s\n", name);
@@ -1300,7 +1324,8 @@ out:
        return err;
 }
 
-int ksmbd_vfs_remove_sd_xattrs(struct dentry *dentry)
+int ksmbd_vfs_remove_sd_xattrs(struct user_namespace *user_ns,
+                              struct dentry *dentry)
 {
        char *name, *xattr_list = NULL;
        ssize_t xattr_list_len;
@@ -1319,7 +1344,7 @@ int ksmbd_vfs_remove_sd_xattrs(struct dentry *dentry)
                ksmbd_debug(SMB, "%s, len %zd\n", name, strlen(name));
 
                if (!strncmp(name, XATTR_NAME_SD, XATTR_NAME_SD_LEN)) {
-                       err = ksmbd_vfs_remove_xattr(dentry, name);
+                       err = ksmbd_vfs_remove_xattr(user_ns, dentry, name);
                        if (err)
                                ksmbd_debug(SMB, "remove xattr failed : %s\n", name);
                }
@@ -1329,7 +1354,8 @@ out:
        return err;
 }
 
-static struct xattr_smb_acl *ksmbd_vfs_make_xattr_posix_acl(struct inode *inode,
+static struct xattr_smb_acl *ksmbd_vfs_make_xattr_posix_acl(struct user_namespace *user_ns,
+                                                           struct inode *inode,
                                                            int acl_type)
 {
        struct xattr_smb_acl *smb_acl = NULL;
@@ -1355,14 +1381,14 @@ static struct xattr_smb_acl *ksmbd_vfs_make_xattr_posix_acl(struct inode *inode,
                switch (pa_entry->e_tag) {
                case ACL_USER:
                        xa_entry->type = SMB_ACL_USER;
-                       xa_entry->uid = from_kuid(&init_user_ns, pa_entry->e_uid);
+                       xa_entry->uid = from_kuid(user_ns, pa_entry->e_uid);
                        break;
                case ACL_USER_OBJ:
                        xa_entry->type = SMB_ACL_USER_OBJ;
                        break;
                case ACL_GROUP:
                        xa_entry->type = SMB_ACL_GROUP;
-                       xa_entry->gid = from_kgid(&init_user_ns, pa_entry->e_gid);
+                       xa_entry->gid = from_kgid(user_ns, pa_entry->e_gid);
                        break;
                case ACL_GROUP_OBJ:
                        xa_entry->type = SMB_ACL_GROUP_OBJ;
@@ -1390,7 +1416,9 @@ out:
        return smb_acl;
 }
 
-int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry,
+int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn,
+                          struct user_namespace *user_ns,
+                          struct dentry *dentry,
                           struct smb_ntsd *pntsd, int len)
 {
        int rc;
@@ -1422,12 +1450,14 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry,
                return rc;
        }
 
-       smb_acl = ksmbd_vfs_make_xattr_posix_acl(inode, ACL_TYPE_ACCESS);
+       smb_acl = ksmbd_vfs_make_xattr_posix_acl(user_ns, inode,
+                                                ACL_TYPE_ACCESS);
        if (S_ISDIR(inode->i_mode))
-               def_smb_acl = ksmbd_vfs_make_xattr_posix_acl(inode,
+               def_smb_acl = ksmbd_vfs_make_xattr_posix_acl(user_ns, inode,
                                                             ACL_TYPE_DEFAULT);
 
-       rc = ndr_encode_posix_acl(&acl_ndr, inode, smb_acl, def_smb_acl);
+       rc = ndr_encode_posix_acl(&acl_ndr, user_ns, inode,
+                                 smb_acl, def_smb_acl);
        if (rc) {
                pr_err("failed to encode ndr to posix acl\n");
                goto out;
@@ -1446,7 +1476,8 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry,
                goto out;
        }
 
-       rc = ksmbd_vfs_setxattr(dentry, XATTR_NAME_SD, sd_ndr.data,
+       rc = ksmbd_vfs_setxattr(user_ns, dentry,
+                               XATTR_NAME_SD, sd_ndr.data,
                                sd_ndr.offset, 0);
        if (rc < 0)
                pr_err("Failed to store XATTR ntacl :%d\n", rc);
@@ -1459,13 +1490,15 @@ out:
        return rc;
 }
 
-int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry,
+int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn,
+                          struct user_namespace *user_ns,
+                          struct dentry *dentry,
                           struct smb_ntsd **pntsd)
 {
        int rc;
        struct ndr n;
 
-       rc = ksmbd_vfs_getxattr(dentry, XATTR_NAME_SD, &n.data);
+       rc = ksmbd_vfs_getxattr(user_ns, dentry, XATTR_NAME_SD, &n.data);
        if (rc > 0) {
                struct inode *inode = d_inode(dentry);
                struct ndr acl_ndr = {0};
@@ -1478,13 +1511,15 @@ int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry,
                if (rc)
                        return rc;
 
-               smb_acl = ksmbd_vfs_make_xattr_posix_acl(inode,
+               smb_acl = ksmbd_vfs_make_xattr_posix_acl(user_ns, inode,
                                                         ACL_TYPE_ACCESS);
                if (S_ISDIR(inode->i_mode))
-                       def_smb_acl = ksmbd_vfs_make_xattr_posix_acl(inode,
+                       def_smb_acl = ksmbd_vfs_make_xattr_posix_acl(user_ns,
+                                                                    inode,
                                                                     ACL_TYPE_DEFAULT);
 
-               rc = ndr_encode_posix_acl(&acl_ndr, inode, smb_acl, def_smb_acl);
+               rc = ndr_encode_posix_acl(&acl_ndr, user_ns, inode,
+                                         smb_acl, def_smb_acl);
                if (rc) {
                        pr_err("failed to encode ndr to posix acl\n");
                        goto out;
@@ -1522,7 +1557,8 @@ out:
        return rc;
 }
 
-int ksmbd_vfs_set_dos_attrib_xattr(struct dentry *dentry,
+int ksmbd_vfs_set_dos_attrib_xattr(struct user_namespace *user_ns,
+                                  struct dentry *dentry,
                                   struct xattr_dos_attrib *da)
 {
        struct ndr n;
@@ -1532,7 +1568,7 @@ int ksmbd_vfs_set_dos_attrib_xattr(struct dentry *dentry,
        if (err)
                return err;
 
-       err = ksmbd_vfs_setxattr(dentry, XATTR_NAME_DOS_ATTRIBUTE,
+       err = ksmbd_vfs_setxattr(user_ns, dentry, XATTR_NAME_DOS_ATTRIBUTE,
                                 (void *)n.data, n.offset, 0);
        if (err)
                ksmbd_debug(SMB, "failed to store dos attribute in xattr\n");
@@ -1541,13 +1577,14 @@ int ksmbd_vfs_set_dos_attrib_xattr(struct dentry *dentry,
        return err;
 }
 
-int ksmbd_vfs_get_dos_attrib_xattr(struct dentry *dentry,
+int ksmbd_vfs_get_dos_attrib_xattr(struct user_namespace *user_ns,
+                                  struct dentry *dentry,
                                   struct xattr_dos_attrib *da)
 {
        struct ndr n;
        int err;
 
-       err = ksmbd_vfs_getxattr(dentry, XATTR_NAME_DOS_ATTRIBUTE,
+       err = ksmbd_vfs_getxattr(user_ns, dentry, XATTR_NAME_DOS_ATTRIBUTE,
                                 (char **)&n.data);
        if (err > 0) {
                n.length = err;
@@ -1593,13 +1630,15 @@ void *ksmbd_vfs_init_kstat(char **p, struct ksmbd_kstat *ksmbd_kstat)
        return info;
 }
 
-int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work, struct dentry *dentry,
+int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work,
+                               struct user_namespace *user_ns,
+                               struct dentry *dentry,
                                struct ksmbd_kstat *ksmbd_kstat)
 {
        u64 time;
        int rc;
 
-       generic_fillattr(&init_user_ns, d_inode(dentry), ksmbd_kstat->kstat);
+       generic_fillattr(user_ns, d_inode(dentry), ksmbd_kstat->kstat);
 
        time = ksmbd_UnixTimeToNT(ksmbd_kstat->kstat->ctime);
        ksmbd_kstat->create_time = time;
@@ -1617,7 +1656,7 @@ int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work, struct dentry *dentry,
                                   KSMBD_SHARE_FLAG_STORE_DOS_ATTRS)) {
                struct xattr_dos_attrib da;
 
-               rc = ksmbd_vfs_get_dos_attrib_xattr(dentry, &da);
+               rc = ksmbd_vfs_get_dos_attrib_xattr(user_ns, dentry, &da);
                if (rc > 0) {
                        ksmbd_kstat->file_attributes = cpu_to_le32(da.attr);
                        ksmbd_kstat->create_time = da.create_time;
@@ -1629,7 +1668,8 @@ int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work, struct dentry *dentry,
        return 0;
 }
 
-ssize_t ksmbd_vfs_casexattr_len(struct dentry *dentry, char *attr_name,
+ssize_t ksmbd_vfs_casexattr_len(struct user_namespace *user_ns,
+                               struct dentry *dentry, char *attr_name,
                                int attr_name_len)
 {
        char *name, *xattr_list = NULL;
@@ -1645,7 +1685,7 @@ ssize_t ksmbd_vfs_casexattr_len(struct dentry *dentry, char *attr_name,
                if (strncasecmp(attr_name, name, attr_name_len))
                        continue;
 
-               value_len = ksmbd_vfs_xattr_len(dentry, name);
+               value_len = ksmbd_vfs_xattr_len(user_ns, dentry, name);
                break;
        }
 
@@ -1775,7 +1815,8 @@ void ksmbd_vfs_posix_lock_unblock(struct file_lock *flock)
        locks_delete_block(flock);
 }
 
-int ksmbd_vfs_set_init_posix_acl(struct inode *inode)
+int ksmbd_vfs_set_init_posix_acl(struct user_namespace *user_ns,
+                                struct inode *inode)
 {
        struct posix_acl_state acl_state;
        struct posix_acl *acls;
@@ -1804,13 +1845,13 @@ int ksmbd_vfs_set_init_posix_acl(struct inode *inode)
                return -ENOMEM;
        }
        posix_state_to_acl(&acl_state, acls->a_entries);
-       rc = set_posix_acl(&init_user_ns, inode, ACL_TYPE_ACCESS, acls);
+       rc = set_posix_acl(user_ns, inode, ACL_TYPE_ACCESS, acls);
        if (rc < 0)
                ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n",
                            rc);
        else if (S_ISDIR(inode->i_mode)) {
                posix_state_to_acl(&acl_state, acls->a_entries);
-               rc = set_posix_acl(&init_user_ns, inode, ACL_TYPE_DEFAULT,
+               rc = set_posix_acl(user_ns, inode, ACL_TYPE_DEFAULT,
                                   acls);
                if (rc < 0)
                        ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n",
@@ -1821,7 +1862,8 @@ int ksmbd_vfs_set_init_posix_acl(struct inode *inode)
        return rc;
 }
 
-int ksmbd_vfs_inherit_posix_acl(struct inode *inode, struct inode *parent_inode)
+int ksmbd_vfs_inherit_posix_acl(struct user_namespace *user_ns,
+                               struct inode *inode, struct inode *parent_inode)
 {
        struct posix_acl *acls;
        struct posix_acl_entry *pace;
@@ -1839,12 +1881,12 @@ int ksmbd_vfs_inherit_posix_acl(struct inode *inode, struct inode *parent_inode)
                }
        }
 
-       rc = set_posix_acl(&init_user_ns, inode, ACL_TYPE_ACCESS, acls);
+       rc = set_posix_acl(user_ns, inode, ACL_TYPE_ACCESS, acls);
        if (rc < 0)
                ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n",
                            rc);
        if (S_ISDIR(inode->i_mode)) {
-               rc = set_posix_acl(&init_user_ns, inode, ACL_TYPE_DEFAULT,
+               rc = set_posix_acl(user_ns, inode, ACL_TYPE_DEFAULT,
                                   acls);
                if (rc < 0)
                        ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n",
index e30174a..b255f90 100644 (file)
@@ -108,8 +108,9 @@ struct ksmbd_kstat {
 };
 
 int ksmbd_vfs_lock_parent(struct dentry *parent, struct dentry *child);
-int ksmbd_vfs_may_delete(struct dentry *dentry);
-int ksmbd_vfs_query_maximal_access(struct dentry *dentry, __le32 *daccess);
+int ksmbd_vfs_may_delete(struct user_namespace *user_ns, struct dentry *dentry);
+int ksmbd_vfs_query_maximal_access(struct user_namespace *user_ns,
+                                  struct dentry *dentry, __le32 *daccess);
 int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mode);
 int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode);
 int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp,
@@ -136,15 +137,20 @@ int ksmbd_vfs_copy_file_ranges(struct ksmbd_work *work,
                               unsigned int *chunk_size_written,
                               loff_t  *total_size_written);
 ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char **list);
-ssize_t ksmbd_vfs_getxattr(struct dentry *dentry, char *xattr_name,
+ssize_t ksmbd_vfs_getxattr(struct user_namespace *user_ns,
+                          struct dentry *dentry,
+                          char *xattr_name,
                           char **xattr_buf);
-ssize_t ksmbd_vfs_casexattr_len(struct dentry *dentry, char *attr_name,
+ssize_t ksmbd_vfs_casexattr_len(struct user_namespace *user_ns,
+                               struct dentry *dentry, char *attr_name,
                                int attr_name_len);
-int ksmbd_vfs_setxattr(struct dentry *dentry, const char *attr_name,
+int ksmbd_vfs_setxattr(struct user_namespace *user_ns,
+                      struct dentry *dentry, const char *attr_name,
                       const void *attr_value, size_t attr_size, int flags);
 int ksmbd_vfs_xattr_stream_name(char *stream_name, char **xattr_stream_name,
                                size_t *xattr_stream_name_size, int s_type);
-int ksmbd_vfs_remove_xattr(struct dentry *dentry, char *attr_name);
+int ksmbd_vfs_remove_xattr(struct user_namespace *user_ns,
+                          struct dentry *dentry, char *attr_name);
 int ksmbd_vfs_kern_path(char *name, unsigned int flags, struct path *path,
                        bool caseless);
 int ksmbd_vfs_empty_dir(struct ksmbd_file *fp);
@@ -155,24 +161,37 @@ struct file_allocated_range_buffer;
 int ksmbd_vfs_fqar_lseek(struct ksmbd_file *fp, loff_t start, loff_t length,
                         struct file_allocated_range_buffer *ranges,
                         int in_count, int *out_count);
-int ksmbd_vfs_unlink(struct dentry *dir, struct dentry *dentry);
+int ksmbd_vfs_unlink(struct user_namespace *user_ns,
+                    struct dentry *dir, struct dentry *dentry);
 void *ksmbd_vfs_init_kstat(char **p, struct ksmbd_kstat *ksmbd_kstat);
-int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work, struct dentry *dentry,
+int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work,
+                               struct user_namespace *user_ns,
+                               struct dentry *dentry,
                                struct ksmbd_kstat *ksmbd_kstat);
 int ksmbd_vfs_posix_lock_wait(struct file_lock *flock);
 int ksmbd_vfs_posix_lock_wait_timeout(struct file_lock *flock, long timeout);
 void ksmbd_vfs_posix_lock_unblock(struct file_lock *flock);
-int ksmbd_vfs_remove_acl_xattrs(struct dentry *dentry);
-int ksmbd_vfs_remove_sd_xattrs(struct dentry *dentry);
-int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry,
+int ksmbd_vfs_remove_acl_xattrs(struct user_namespace *user_ns,
+                               struct dentry *dentry);
+int ksmbd_vfs_remove_sd_xattrs(struct user_namespace *user_ns,
+                              struct dentry *dentry);
+int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn,
+                          struct user_namespace *user_ns,
+                          struct dentry *dentry,
                           struct smb_ntsd *pntsd, int len);
-int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry,
+int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn,
+                          struct user_namespace *user_ns,
+                          struct dentry *dentry,
                           struct smb_ntsd **pntsd);
-int ksmbd_vfs_set_dos_attrib_xattr(struct dentry *dentry,
+int ksmbd_vfs_set_dos_attrib_xattr(struct user_namespace *user_ns,
+                                  struct dentry *dentry,
                                   struct xattr_dos_attrib *da);
-int ksmbd_vfs_get_dos_attrib_xattr(struct dentry *dentry,
+int ksmbd_vfs_get_dos_attrib_xattr(struct user_namespace *user_ns,
+                                  struct dentry *dentry,
                                   struct xattr_dos_attrib *da);
-int ksmbd_vfs_set_init_posix_acl(struct inode *inode);
-int ksmbd_vfs_inherit_posix_acl(struct inode *inode,
+int ksmbd_vfs_set_init_posix_acl(struct user_namespace *user_ns,
+                                struct inode *inode);
+int ksmbd_vfs_inherit_posix_acl(struct user_namespace *user_ns,
+                               struct inode *inode,
                                struct inode *parent_inode);
 #endif /* __KSMBD_VFS_H__ */
index 5c9efcf..1941ad3 100644 (file)
@@ -251,7 +251,8 @@ static void __ksmbd_inode_close(struct ksmbd_file *fp)
        filp = fp->filp;
        if (ksmbd_stream_fd(fp) && (ci->m_flags & S_DEL_ON_CLS_STREAM)) {
                ci->m_flags &= ~S_DEL_ON_CLS_STREAM;
-               err = ksmbd_vfs_remove_xattr(filp->f_path.dentry,
+               err = ksmbd_vfs_remove_xattr(file_mnt_user_ns(filp),
+                                            filp->f_path.dentry,
                                             fp->stream.name);
                if (err)
                        pr_err("remove xattr failed : %s\n",
@@ -265,7 +266,7 @@ static void __ksmbd_inode_close(struct ksmbd_file *fp)
                        dir = dentry->d_parent;
                        ci->m_flags &= ~(S_DEL_ON_CLS | S_DEL_PENDING);
                        write_unlock(&ci->m_lock);
-                       ksmbd_vfs_unlink(dir, dentry);
+                       ksmbd_vfs_unlink(file_mnt_user_ns(filp), dir, dentry);
                        write_lock(&ci->m_lock);
                }
                write_unlock(&ci->m_lock);