Skip to content
Permalink
Browse files
cifsd: handle idmapped mounts
This patch handle it as idmapped mounts patch is merged into linux-5.12.

Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
  • Loading branch information
namjaejeon authored and Steve French committed Mar 14, 2021
1 parent 8e1b809 commit 60f4e4de78688253a2d2ceaa693ee0e28aafa6d9
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 40 deletions.
@@ -2777,7 +2777,7 @@ int smb2_open(struct ksmbd_work *work)
rc = 0;
} else {
file_present = true;
generic_fillattr(d_inode(path.dentry), &stat);
generic_fillattr(&init_user_ns, d_inode(path.dentry), &stat);
}
if (stream_name) {
if (req->CreateOptions & FILE_DIRECTORY_FILE_LE) {
@@ -3043,7 +3043,7 @@ int smb2_open(struct ksmbd_work *work)

rc = ksmbd_vfs_getattr(&path, &stat);
if (rc) {
generic_fillattr(d_inode(path.dentry), &stat);
generic_fillattr(&init_user_ns, d_inode(path.dentry), &stat);
rc = 0;
}

@@ -3167,7 +3167,7 @@ int smb2_open(struct ksmbd_work *work)
}

reconnected:
generic_fillattr(FP_INODE(fp), &stat);
generic_fillattr(&init_user_ns, FP_INODE(fp), &stat);

rsp->StructureSize = cpu_to_le16(89);
rcu_read_lock();
@@ -3911,7 +3911,7 @@ int smb2_query_dir(struct ksmbd_work *work)
}

if (!(dir_fp->daccess & FILE_LIST_DIRECTORY_LE) ||
inode_permission(file_inode(dir_fp->filp),
inode_permission(&init_user_ns, file_inode(dir_fp->filp),
MAY_READ | MAY_EXEC)) {
ksmbd_err("no right to enumerate directory (%s)\n",
FP_FILENAME(dir_fp));
@@ -4339,8 +4339,7 @@ static int get_file_basic_info(struct smb2_query_info_rsp *rsp,
}

basic_info = (struct smb2_file_all_info *)rsp->Buffer;
generic_fillattr(FP_INODE(fp), &stat);

generic_fillattr(&init_user_ns, FP_INODE(fp), &stat);
basic_info->CreationTime = cpu_to_le64(fp->create_time);
time = ksmbd_UnixTimeToNT(stat.atime);
basic_info->LastAccessTime = cpu_to_le64(time);
@@ -4384,7 +4383,7 @@ static void get_file_standard_info(struct smb2_query_info_rsp *rsp,
struct kstat stat;

inode = FP_INODE(fp);
generic_fillattr(inode, &stat);
generic_fillattr(&init_user_ns, inode, &stat);

sinfo = (struct smb2_file_standard_info *)rsp->Buffer;
delete_pending = ksmbd_inode_pending_delete(fp);
@@ -4439,7 +4438,7 @@ static int get_file_all_info(struct ksmbd_work *work,
return -ENOMEM;

inode = FP_INODE(fp);
generic_fillattr(inode, &stat);
generic_fillattr(&init_user_ns, inode, &stat);

ksmbd_debug(SMB, "filename = %s\n", filename);
delete_pending = ksmbd_inode_pending_delete(fp);
@@ -4516,7 +4515,7 @@ 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(FP_INODE(fp), &stat);
generic_fillattr(&init_user_ns, FP_INODE(fp), &stat);
file_info = (struct smb2_file_stream_info *)rsp->Buffer;

xattr_list_len = ksmbd_vfs_listxattr(path->dentry, &xattr_list);
@@ -4599,7 +4598,7 @@ static void get_file_internal_info(struct smb2_query_info_rsp *rsp,
struct smb2_file_internal_info *file_info;
struct kstat stat;

generic_fillattr(FP_INODE(fp), &stat);
generic_fillattr(&init_user_ns, FP_INODE(fp), &stat);
file_info = (struct smb2_file_internal_info *)rsp->Buffer;
file_info->IndexNumber = cpu_to_le64(stat.ino);
rsp->OutputBufferLength =
@@ -4625,7 +4624,7 @@ static int get_file_network_open_info(struct smb2_query_info_rsp *rsp,
file_info = (struct smb2_file_ntwrk_info *)rsp->Buffer;

inode = FP_INODE(fp);
generic_fillattr(inode, &stat);
generic_fillattr(&init_user_ns, inode, &stat);

file_info->CreationTime = cpu_to_le64(fp->create_time);
time = ksmbd_UnixTimeToNT(stat.atime);
@@ -4690,7 +4689,7 @@ static void get_file_compression_info(struct smb2_query_info_rsp *rsp,
struct smb2_file_comp_info *file_info;
struct kstat stat;

generic_fillattr(FP_INODE(fp), &stat);
generic_fillattr(&init_user_ns, FP_INODE(fp), &stat);

file_info = (struct smb2_file_comp_info *)rsp->Buffer;
file_info->CompressedFileSize = cpu_to_le64(stat.blocks << 9);
@@ -5702,14 +5701,14 @@ static int set_file_basic_info(struct ksmbd_file *fp,
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
return -EACCES;

rc = setattr_prepare(dentry, &attrs);
rc = setattr_prepare(&init_user_ns, dentry, &attrs);
if (rc)
return -EINVAL;

inode_lock(inode);
setattr_copy(inode, &attrs);
setattr_copy(&init_user_ns, inode, &attrs);
attrs.ia_valid &= ~ATTR_CTIME;
rc = notify_change(dentry, &attrs, NULL);
rc = notify_change(&init_user_ns, dentry, &attrs, NULL);
inode_unlock(inode);
}
return 0;
@@ -126,7 +126,7 @@ int ksmbd_vfs_inode_permission(struct dentry *dentry, int acc_mode, bool delete)
else if (acc_mode == O_RDWR)
mask = MAY_READ | MAY_WRITE;

if (inode_permission(d_inode(dentry), mask | MAY_OPEN))
if (inode_permission(&init_user_ns, d_inode(dentry), mask | MAY_OPEN))
return -EACCES;

if (delete) {
@@ -136,7 +136,7 @@ int ksmbd_vfs_inode_permission(struct dentry *dentry, int acc_mode, bool delete)
if (!parent)
return -EINVAL;

if (inode_permission(d_inode(parent), MAY_EXEC | MAY_WRITE)) {
if (inode_permission(&init_user_ns, d_inode(parent), MAY_EXEC | MAY_WRITE)) {
dput(parent);
return -EACCES;
}
@@ -151,23 +151,23 @@ int ksmbd_vfs_query_maximal_access(struct dentry *dentry, __le32 *daccess)

*daccess = cpu_to_le32(FILE_READ_ATTRIBUTES | READ_CONTROL);

if (inode_permission(d_inode(dentry), MAY_OPEN | MAY_WRITE) == 0)
if (!inode_permission(&init_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(d_inode(dentry), MAY_OPEN | MAY_READ) == 0)
if (!inode_permission(&init_user_ns, d_inode(dentry), MAY_OPEN | MAY_READ))
*daccess |= FILE_READ_DATA_LE | FILE_READ_EA_LE;

if (inode_permission(d_inode(dentry), MAY_OPEN | MAY_EXEC) == 0)
if (!inode_permission(&init_user_ns, d_inode(dentry), MAY_OPEN | MAY_EXEC))
*daccess |= FILE_EXECUTE_LE;

parent = dget_parent(dentry);
if (!parent)
return 0;

if (inode_permission(d_inode(parent), MAY_EXEC | MAY_WRITE) == 0)
if (!inode_permission(&init_user_ns, d_inode(parent), MAY_EXEC | MAY_WRITE))
*daccess |= FILE_DELETE_LE;
dput(parent);
return 0;
@@ -200,7 +200,7 @@ int ksmbd_vfs_create(struct ksmbd_work *work,
}

mode |= S_IFREG;
err = vfs_create(d_inode(path.dentry), dentry, mode, true);
err = vfs_create(&init_user_ns, d_inode(path.dentry), dentry, mode, true);
if (!err) {
ksmbd_vfs_inherit_owner(work, d_inode(path.dentry),
d_inode(dentry));
@@ -238,7 +238,7 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work,
}

mode |= S_IFDIR;
err = vfs_mkdir(d_inode(path.dentry), dentry, mode);
err = vfs_mkdir(&init_user_ns, d_inode(path.dentry), dentry, mode);
if (!err) {
ksmbd_vfs_inherit_owner(work, d_inode(path.dentry),
d_inode(dentry));
@@ -623,12 +623,12 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name)
}

if (S_ISDIR(d_inode(dentry)->i_mode)) {
err = vfs_rmdir(d_inode(dir), dentry);
err = vfs_rmdir(&init_user_ns, d_inode(dir), dentry);
if (err && err != -ENOTEMPTY)
ksmbd_debug(VFS, "%s: rmdir failed, err %d\n", name,
err);
} else {
err = vfs_unlink(d_inode(dir), dentry, NULL);
err = vfs_unlink(&init_user_ns, d_inode(dir), dentry, NULL);
if (err)
ksmbd_debug(VFS, "%s: unlink failed, err %d\n", name,
err);
@@ -682,7 +682,8 @@ int ksmbd_vfs_link(struct ksmbd_work *work,
goto out3;
}

err = vfs_link(oldpath.dentry, d_inode(newpath.dentry), dentry, NULL);
err = vfs_link(oldpath.dentry, &init_user_ns, d_inode(newpath.dentry),
dentry, NULL);
if (err)
ksmbd_debug(VFS, "vfs_link failed err %d\n", err);

@@ -742,12 +743,15 @@ static int __ksmbd_vfs_rename(struct ksmbd_work *work,

err = -ENOTEMPTY;
if (dst_dent != trap_dent && !d_really_is_positive(dst_dent)) {
err = vfs_rename(d_inode(src_dent_parent),
src_dent,
d_inode(dst_dent_parent),
dst_dent,
NULL,
0);
struct renamedata rd = {
.old_mnt_userns = &init_user_ns,
.old_dir = d_inode(src_dent_parent),
.old_dentry = src_dent,
.new_mnt_userns = &init_user_ns,
.new_dir = d_inode(dst_dent_parent),
.new_dentry = dst_dent,
};
err = vfs_rename(&rd);
}
if (err)
ksmbd_err("vfs_rename failed err %d\n", err);
@@ -896,7 +900,7 @@ ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char **list)
static ssize_t ksmbd_vfs_xattr_len(struct dentry *dentry,
char *xattr_name)
{
return vfs_getxattr(dentry, xattr_name, NULL, 0);
return vfs_getxattr(&init_user_ns, dentry, xattr_name, NULL, 0);
}

/**
@@ -923,7 +927,8 @@ ssize_t ksmbd_vfs_getxattr(struct dentry *dentry,
if (!buf)
return -ENOMEM;

xattr_len = vfs_getxattr(dentry, xattr_name, (void *)buf, xattr_len);
xattr_len = vfs_getxattr(&init_user_ns, dentry, xattr_name, (void *)buf,
xattr_len);
if (xattr_len > 0)
*xattr_buf = buf;
else
@@ -949,7 +954,7 @@ int ksmbd_vfs_setxattr(struct dentry *dentry,
{
int err;

err = vfs_setxattr(dentry,
err = vfs_setxattr(&init_user_ns, dentry,
attr_name,
attr_value,
attr_size,
@@ -1086,7 +1091,7 @@ int ksmbd_vfs_fqar_lseek(struct ksmbd_file *fp, loff_t start, loff_t length,

int ksmbd_vfs_remove_xattr(struct dentry *dentry, char *attr_name)
{
return vfs_removexattr(dentry, attr_name);
return vfs_removexattr(&init_user_ns, dentry, attr_name);
}

void ksmbd_vfs_xattr_free(char *xattr)
@@ -1106,9 +1111,9 @@ int ksmbd_vfs_unlink(struct dentry *dir, struct dentry *dentry)
}

if (S_ISDIR(d_inode(dentry)->i_mode))
err = vfs_rmdir(d_inode(dir), dentry);
err = vfs_rmdir(&init_user_ns, d_inode(dir), dentry);
else
err = vfs_unlink(d_inode(dir), dentry, NULL);
err = vfs_unlink(&init_user_ns, d_inode(dir), dentry, NULL);

out:
inode_unlock(d_inode(dir));
@@ -1635,7 +1640,7 @@ int ksmbd_vfs_set_posix_acl(struct inode *inode, int type,
struct posix_acl *acl)
{
#if IS_ENABLED(CONFIG_FS_POSIX_ACL)
return set_posix_acl(inode, type, acl);
return set_posix_acl(&init_user_ns, inode, type, acl);
#else
return -EOPNOTSUPP;
#endif
@@ -1680,7 +1685,7 @@ int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work,
u64 time;
int rc;

generic_fillattr(d_inode(dentry), ksmbd_kstat->kstat);
generic_fillattr(&init_user_ns, d_inode(dentry), ksmbd_kstat->kstat);

time = ksmbd_UnixTimeToNT(ksmbd_kstat->kstat->ctime);
ksmbd_kstat->create_time = time;

0 comments on commit 60f4e4d

Please sign in to comment.