Commit bf9f243f authored by Linus Torvalds's avatar Linus Torvalds

Merge tag '5.15-rc-ksmbd-part2' of git://git.samba.org/ksmbd

Pull ksmbd fixes from Steve French:

 - various fixes pointed out by coverity, and a minor cleanup patch

 - id mapping and ownership fixes

 - an smbdirect fix

* tag '5.15-rc-ksmbd-part2' of git://git.samba.org/ksmbd:
  ksmbd: fix control flow issues in sid_to_id()
  ksmbd: fix read of uninitialized variable ret in set_file_basic_info
  ksmbd: add missing assignments to ret on ndr_read_int64 read calls
  ksmbd: add validation for ndr read/write functions
  ksmbd: remove unused ksmbd_file_table_flush function
  ksmbd: smbd: fix dma mapping error in smb_direct_post_send_data
  ksmbd: Reduce error log 'speed is unknown' to debug
  ksmbd: defer notify_change() call
  ksmbd: remove setattr preparations in set_file_basic_info()
  ksmbd: ensure error is surfaced in set_file_basic_info()
  ndr: fix translation in ndr_encode_posix_acl()
  ksmbd: fix translation in sid_to_id()
  ksmbd: fix subauth 0 handling in sid_to_id()
  ksmbd: fix translation in acl entries
  ksmbd: fix translation in ksmbd_acls_fattr()
  ksmbd: fix translation in create_posix_rsp_buf()
  ksmbd: fix translation in smb2_populate_readdir_entry()
  ksmbd: fix lookup on idmapped mounts
parents 8dde2086 4cf0ccd0
This diff is collapsed.
......@@ -1614,9 +1614,11 @@ 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(user_ns, inode->i_uid),
id_to_sid(from_kuid_munged(&init_user_ns,
i_uid_into_mnt(user_ns, inode)),
SIDNFS_USER, (struct smb_sid *)&buf->SidBuffer[0]);
id_to_sid(from_kgid(user_ns, inode->i_gid),
id_to_sid(from_kgid_munged(&init_user_ns,
i_gid_into_mnt(user_ns, inode)),
SIDNFS_GROUP, (struct smb_sid *)&buf->SidBuffer[20]);
}
......
......@@ -2381,10 +2381,12 @@ static int smb2_create_sd_buffer(struct ksmbd_work *work,
le32_to_cpu(sd_buf->ccontext.DataLength), true);
}
static void ksmbd_acls_fattr(struct smb_fattr *fattr, struct inode *inode)
static void ksmbd_acls_fattr(struct smb_fattr *fattr,
struct user_namespace *mnt_userns,
struct inode *inode)
{
fattr->cf_uid = inode->i_uid;
fattr->cf_gid = inode->i_gid;
fattr->cf_uid = i_uid_into_mnt(mnt_userns, inode);
fattr->cf_gid = i_gid_into_mnt(mnt_userns, inode);
fattr->cf_mode = inode->i_mode;
fattr->cf_acls = NULL;
fattr->cf_dacls = NULL;
......@@ -2893,7 +2895,7 @@ int smb2_open(struct ksmbd_work *work)
struct smb_ntsd *pntsd;
int pntsd_size, ace_num = 0;
ksmbd_acls_fattr(&fattr, inode);
ksmbd_acls_fattr(&fattr, user_ns, inode);
if (fattr.cf_acls)
ace_num = fattr.cf_acls->a_count;
if (fattr.cf_dacls)
......@@ -3324,7 +3326,6 @@ 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;
......@@ -3478,9 +3479,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(user_ns, ksmbd_kstat->kstat->uid),
id_to_sid(from_kuid_munged(&init_user_ns, ksmbd_kstat->kstat->uid),
SIDNFS_USER, (struct smb_sid *)&posix_info->SidBuffer[0]);
id_to_sid(from_kgid(user_ns, ksmbd_kstat->kstat->gid),
id_to_sid(from_kgid_munged(&init_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);
......@@ -3543,9 +3544,9 @@ static int process_query_dir_entries(struct smb2_query_dir_private *priv)
return -EINVAL;
lock_dir(priv->dir_fp);
dent = lookup_one_len(priv->d_info->name,
priv->dir_fp->filp->f_path.dentry,
priv->d_info->name_len);
dent = lookup_one(user_ns, priv->d_info->name,
priv->dir_fp->filp->f_path.dentry,
priv->d_info->name_len);
unlock_dir(priv->dir_fp);
if (IS_ERR(dent)) {
......@@ -3571,7 +3572,6 @@ static int process_query_dir_entries(struct smb2_query_dir_private *priv)
rc = smb2_populate_readdir_entry(priv->work->conn,
priv->info_level,
priv->d_info,
user_ns,
&ksmbd_kstat);
dput(dent);
if (rc)
......@@ -5008,7 +5008,7 @@ static int smb2_get_info_sec(struct ksmbd_work *work,
user_ns = file_mnt_user_ns(fp->filp);
inode = file_inode(fp->filp);
ksmbd_acls_fattr(&fattr, inode);
ksmbd_acls_fattr(&fattr, user_ns, inode);
if (test_share_config_flag(work->tcon->share_conf,
KSMBD_SHARE_FLAG_ACL_XATTR))
......@@ -5246,7 +5246,9 @@ int smb2_echo(struct ksmbd_work *work)
return 0;
}
static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
static int smb2_rename(struct ksmbd_work *work,
struct ksmbd_file *fp,
struct user_namespace *user_ns,
struct smb2_file_rename_info *file_info,
struct nls_table *local_nls)
{
......@@ -5310,7 +5312,7 @@ static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
if (rc)
goto out;
rc = ksmbd_vfs_setxattr(file_mnt_user_ns(fp->filp),
rc = ksmbd_vfs_setxattr(user_ns,
fp->filp->f_path.dentry,
xattr_stream_name,
NULL, 0, 0);
......@@ -5438,11 +5440,11 @@ static int set_file_basic_info(struct ksmbd_file *fp, char *buf,
{
struct smb2_file_all_info *file_info;
struct iattr attrs;
struct iattr temp_attrs;
struct timespec64 ctime;
struct file *filp;
struct inode *inode;
struct user_namespace *user_ns;
int rc;
int rc = 0;
if (!(fp->daccess & FILE_WRITE_ATTRIBUTES_LE))
return -EACCES;
......@@ -5462,11 +5464,11 @@ static int set_file_basic_info(struct ksmbd_file *fp, char *buf,
}
if (file_info->ChangeTime) {
temp_attrs.ia_ctime = ksmbd_NTtimeToUnix(file_info->ChangeTime);
attrs.ia_ctime = temp_attrs.ia_ctime;
attrs.ia_ctime = ksmbd_NTtimeToUnix(file_info->ChangeTime);
ctime = attrs.ia_ctime;
attrs.ia_valid |= ATTR_CTIME;
} else {
temp_attrs.ia_ctime = inode->i_ctime;
ctime = inode->i_ctime;
}
if (file_info->LastWriteTime) {
......@@ -5505,13 +5507,6 @@ static int set_file_basic_info(struct ksmbd_file *fp, char *buf,
rc = 0;
}
/*
* HACK : set ctime here to avoid ctime changed
* when file_info->ChangeTime is zero.
*/
attrs.ia_ctime = temp_attrs.ia_ctime;
attrs.ia_valid |= ATTR_CTIME;
if (attrs.ia_valid) {
struct dentry *dentry = filp->f_path.dentry;
struct inode *inode = d_inode(dentry);
......@@ -5519,17 +5514,15 @@ static int set_file_basic_info(struct ksmbd_file *fp, char *buf,
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
return -EACCES;
rc = setattr_prepare(user_ns, dentry, &attrs);
if (rc)
return -EINVAL;
inode_lock(inode);
setattr_copy(user_ns, inode, &attrs);
attrs.ia_valid &= ~ATTR_CTIME;
rc = notify_change(user_ns, dentry, &attrs, NULL);
if (!rc) {
inode->i_ctime = ctime;
mark_inode_dirty(inode);
}
inode_unlock(inode);
}
return 0;
return rc;
}
static int set_file_allocation_info(struct ksmbd_work *work,
......@@ -5624,6 +5617,7 @@ static int set_end_of_file_info(struct ksmbd_work *work, struct ksmbd_file *fp,
static int set_rename_info(struct ksmbd_work *work, struct ksmbd_file *fp,
char *buf)
{
struct user_namespace *user_ns;
struct ksmbd_file *parent_fp;
struct dentry *parent;
struct dentry *dentry = fp->filp->f_path.dentry;
......@@ -5634,11 +5628,12 @@ static int set_rename_info(struct ksmbd_work *work, struct ksmbd_file *fp,
return -EACCES;
}
user_ns = file_mnt_user_ns(fp->filp);
if (ksmbd_stream_fd(fp))
goto next;
parent = dget_parent(dentry);
ret = ksmbd_vfs_lock_parent(parent, dentry);
ret = ksmbd_vfs_lock_parent(user_ns, parent, dentry);
if (ret) {
dput(parent);
return ret;
......@@ -5655,7 +5650,7 @@ static int set_rename_info(struct ksmbd_work *work, struct ksmbd_file *fp,
}
}
next:
return smb2_rename(work, fp,
return smb2_rename(work, fp, user_ns,
(struct smb2_file_rename_info *)buf,
work->sess->conn->local_nls);
}
......@@ -7116,8 +7111,8 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn,
netdev->ethtool_ops->get_link_ksettings(netdev, &cmd);
speed = cmd.base.speed;
} else {
pr_err("%s %s\n", netdev->name,
"speed is unknown, defaulting to 1Gb/sec");
ksmbd_debug(SMB, "%s %s\n", netdev->name,
"speed is unknown, defaulting to 1Gb/sec");
speed = SPEED_1000;
}
......
......@@ -291,7 +291,6 @@ 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;
......@@ -322,8 +321,7 @@ int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, int info_level,
user_ns,
dir->filp->f_path.dentry->d_parent,
&ksmbd_kstat);
rc = fn(conn, info_level, d_info,
user_ns, &ksmbd_kstat);
rc = fn(conn, info_level, d_info, &ksmbd_kstat);
if (rc)
break;
if (d_info->out_buf_len <= 0)
......
......@@ -511,7 +511,6 @@ 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,
......
......@@ -274,24 +274,34 @@ static int sid_to_id(struct user_namespace *user_ns,
uid_t id;
id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
if (id > 0) {
uid = make_kuid(user_ns, id);
if (uid_valid(uid) && kuid_has_mapping(user_ns, uid)) {
fattr->cf_uid = uid;
rc = 0;
}
/*
* Translate raw sid into kuid in the server's user
* namespace.
*/
uid = make_kuid(&init_user_ns, id);
/* If this is an idmapped mount, apply the idmapping. */
uid = kuid_from_mnt(user_ns, uid);
if (uid_valid(uid)) {
fattr->cf_uid = uid;
rc = 0;
}
} else {
kgid_t gid;
gid_t id;
id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
if (id > 0) {
gid = make_kgid(user_ns, id);
if (gid_valid(gid) && kgid_has_mapping(user_ns, gid)) {
fattr->cf_gid = gid;
rc = 0;
}
/*
* Translate raw sid into kgid in the server's user
* namespace.
*/
gid = make_kgid(&init_user_ns, id);
/* If this is an idmapped mount, apply the idmapping. */
gid = kgid_from_mnt(user_ns, gid);
if (gid_valid(gid)) {
fattr->cf_gid = gid;
rc = 0;
}
}
......@@ -587,14 +597,14 @@ static void set_posix_acl_entries_dacl(struct user_namespace *user_ns,
uid_t uid;
unsigned int sid_type = SIDOWNER;
uid = from_kuid(user_ns, pace->e_uid);
uid = posix_acl_uid_translate(user_ns, pace);
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(user_ns, pace->e_gid);
gid = posix_acl_gid_translate(user_ns, pace);
id_to_sid(gid, SIDUNIX_GROUP, sid);
} else if (pace->e_tag == ACL_OTHER && !nt_aces_num) {
smb_copy_sid(sid, &sid_everyone);
......@@ -653,12 +663,12 @@ static void set_posix_acl_entries_dacl(struct user_namespace *user_ns,
if (pace->e_tag == ACL_USER) {
uid_t uid;
uid = from_kuid(user_ns, pace->e_uid);
uid = posix_acl_uid_translate(user_ns, pace);
id_to_sid(uid, SIDCREATOR_OWNER, sid);
} else if (pace->e_tag == ACL_GROUP) {
gid_t gid;
gid = from_kgid(user_ns, pace->e_gid);
gid = posix_acl_gid_translate(user_ns, pace);
id_to_sid(gid, SIDCREATOR_GROUP, sid);
} else {
kfree(sid);
......@@ -723,7 +733,7 @@ static void set_mode_dacl(struct user_namespace *user_ns,
}
/* owner RID */
uid = from_kuid(user_ns, fattr->cf_uid);
uid = from_kuid(&init_user_ns, fattr->cf_uid);
if (uid)
sid = &server_conf.domain_sid;
else
......@@ -739,7 +749,7 @@ static void set_mode_dacl(struct user_namespace *user_ns,
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(user_ns, fattr->cf_gid));
cpu_to_le32(from_kgid(&init_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);
......@@ -880,7 +890,7 @@ int build_sec_desc(struct user_namespace *user_ns,
if (!nowner_sid_ptr)
return -ENOMEM;
uid = from_kuid(user_ns, fattr->cf_uid);
uid = from_kuid(&init_user_ns, fattr->cf_uid);
if (!uid)
sid_type = SIDUNIX_USER;
id_to_sid(uid, sid_type, nowner_sid_ptr);
......@@ -891,7 +901,7 @@ int build_sec_desc(struct user_namespace *user_ns,
return -ENOMEM;
}
gid = from_kgid(user_ns, fattr->cf_gid);
gid = from_kgid(&init_user_ns, fattr->cf_gid);
id_to_sid(gid, SIDUNIX_GROUP, ngroup_sid_ptr);
offset = sizeof(struct smb_ntsd);
......@@ -1234,11 +1244,9 @@ 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(user_ns,
pa_entry->e_uid);
id = posix_acl_uid_translate(user_ns, pa_entry);
else if (pa_entry->e_tag == ACL_GROUP)
id = from_kgid(user_ns,
pa_entry->e_gid);
id = posix_acl_gid_translate(user_ns, pa_entry);
else
continue;
......@@ -1322,22 +1330,31 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
newattrs.ia_valid |= ATTR_MODE;
newattrs.ia_mode = (inode->i_mode & ~0777) | (fattr.cf_mode & 0777);
inode_lock(inode);
rc = notify_change(user_ns, path->dentry, &newattrs, NULL);
inode_unlock(inode);
if (rc)
goto out;
ksmbd_vfs_remove_acl_xattrs(user_ns, path->dentry);
/* Update posix acls */
if (IS_ENABLED(CONFIG_FS_POSIX_ACL) && fattr.cf_dacls) {
rc = set_posix_acl(user_ns, inode,
ACL_TYPE_ACCESS, fattr.cf_acls);
if (S_ISDIR(inode->i_mode) && fattr.cf_dacls)
if (rc < 0)
ksmbd_debug(SMB,
"Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n",
rc);
if (S_ISDIR(inode->i_mode) && fattr.cf_dacls) {
rc = set_posix_acl(user_ns, inode,
ACL_TYPE_DEFAULT, fattr.cf_dacls);
if (rc)
ksmbd_debug(SMB,
"Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n",
rc);
}
}
inode_lock(inode);
rc = notify_change(user_ns, path->dentry, &newattrs, NULL);
inode_unlock(inode);
if (rc)
goto out;
/* Check it only calling from SD BUFFER context */
if (type_check && !(le16_to_cpu(pntsd->type) & DACL_PRESENT))
goto out;
......
......@@ -209,4 +209,29 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
bool type_check);
void id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid);
void ksmbd_init_domain(u32 *sub_auth);
static inline uid_t posix_acl_uid_translate(struct user_namespace *mnt_userns,
struct posix_acl_entry *pace)
{
kuid_t kuid;
/* If this is an idmapped mount, apply the idmapping. */
kuid = kuid_into_mnt(mnt_userns, pace->e_uid);
/* Translate the kuid into a userspace id ksmbd would see. */
return from_kuid(&init_user_ns, kuid);
}
static inline gid_t posix_acl_gid_translate(struct user_namespace *mnt_userns,
struct posix_acl_entry *pace)
{
kgid_t kgid;
/* If this is an idmapped mount, apply the idmapping. */
kgid = kgid_into_mnt(mnt_userns, pace->e_gid);
/* Translate the kgid into a userspace id ksmbd would see. */
return from_kgid(&init_user_ns, kgid);
}
#endif /* _SMBACL_H */
......@@ -1168,7 +1168,7 @@ static int smb_direct_post_send_data(struct smb_direct_transport *t,
pr_err("failed to map buffer\n");
ret = -ENOMEM;
goto err;
} else if (sg_cnt + msg->num_sge > SMB_DIRECT_MAX_SEND_SGES - 1) {
} else if (sg_cnt + msg->num_sge > SMB_DIRECT_MAX_SEND_SGES) {
pr_err("buffer not fitted into sges\n");
ret = -E2BIG;
ib_dma_unmap_sg(t->cm_id->device, sg, sg_cnt,
......
......@@ -69,14 +69,15 @@ static void ksmbd_vfs_inherit_owner(struct ksmbd_work *work,
*
* the reference count of @parent isn't incremented.
*/
int ksmbd_vfs_lock_parent(struct dentry *parent, struct dentry *child)
int ksmbd_vfs_lock_parent(struct user_namespace *user_ns, struct dentry *parent,
struct dentry *child)
{
struct dentry *dentry;
int ret = 0;
inode_lock_nested(d_inode(parent), I_MUTEX_PARENT);
dentry = lookup_one_len(child->d_name.name, parent,
child->d_name.len);
dentry = lookup_one(user_ns, child->d_name.name, parent,
child->d_name.len);
if (IS_ERR(dentry)) {
ret = PTR_ERR(dentry);
goto out_err;
......@@ -102,7 +103,7 @@ int ksmbd_vfs_may_delete(struct user_namespace *user_ns,
int ret;
parent = dget_parent(dentry);
ret = ksmbd_vfs_lock_parent(parent, dentry);
ret = ksmbd_vfs_lock_parent(user_ns, parent, dentry);
if (ret) {
dput(parent);
return ret;
......@@ -137,7 +138,7 @@ int ksmbd_vfs_query_maximal_access(struct user_namespace *user_ns,
*daccess |= FILE_EXECUTE_LE;
parent = dget_parent(dentry);
ret = ksmbd_vfs_lock_parent(parent, dentry);
ret = ksmbd_vfs_lock_parent(user_ns, parent, dentry);
if (ret) {
dput(parent);
return ret;
......@@ -197,6 +198,7 @@ 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)
{
struct user_namespace *user_ns;
struct path path;
struct dentry *dentry;
int err;
......@@ -210,16 +212,16 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode)
return err;
}
user_ns = mnt_user_ns(path.mnt);
mode |= S_IFDIR;
err = vfs_mkdir(mnt_user_ns(path.mnt), d_inode(path.dentry),
dentry, mode);
err = vfs_mkdir(user_ns, d_inode(path.dentry), dentry, mode);
if (err) {
goto out;
} else if (d_unhashed(dentry)) {
struct dentry *d;
d = lookup_one_len(dentry->d_name.name, dentry->d_parent,
dentry->d_name.len);
d = lookup_one(user_ns, dentry->d_name.name, dentry->d_parent,
dentry->d_name.len);
if (IS_ERR(d)) {
err = PTR_ERR(d);
goto out;
......@@ -582,6 +584,7 @@ int ksmbd_vfs_fsync(struct ksmbd_work *work, u64 fid, u64 p_id)
*/
int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name)
{
struct user_namespace *user_ns;
struct path path;
struct dentry *parent;
int err;
......@@ -601,8 +604,9 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name)
return err;
}
user_ns = mnt_user_ns(path.mnt);
parent = dget_parent(path.dentry);
err = ksmbd_vfs_lock_parent(parent, path.dentry);
err = ksmbd_vfs_lock_parent(user_ns, parent, path.dentry);
if (err) {
dput(parent);
path_put(&path);
......@@ -616,14 +620,12 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name)
}
if (S_ISDIR(d_inode(path.dentry)->i_mode)) {
err = vfs_rmdir(mnt_user_ns(path.mnt), d_inode(parent),
path.dentry);
err = vfs_rmdir(user_ns, d_inode(parent), path.dentry);
if (err && err != -ENOTEMPTY)
ksmbd_debug(VFS, "%s: rmdir failed, err %d\n", name,
err);
} else {
err = vfs_unlink(mnt_user_ns(path.mnt), d_inode(parent),
path.dentry, NULL);
err = vfs_unlink(user_ns, d_inode(parent), path.dentry, NULL);
if (err)
ksmbd_debug(VFS, "%s: unlink failed, err %d\n", name,
err);
......@@ -748,7 +750,8 @@ static int __ksmbd_vfs_rename(struct ksmbd_work *work,
if (ksmbd_override_fsids(work))
return -ENOMEM;
dst_dent = lookup_one_len(dst_name, dst_dent_parent, strlen(dst_name));
dst_dent = lookup_one(dst_user_ns, dst_name, dst_dent_parent,
strlen(dst_name));
err = PTR_ERR(dst_dent);
if (IS_ERR(dst_dent)) {
pr_err("lookup failed %s [%d]\n", dst_name, err);
......@@ -779,6 +782,7 @@ static int __ksmbd_vfs_rename(struct ksmbd_work *work,
int ksmbd_vfs_fp_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
char *newname)
{
struct user_namespace *user_ns;
struct path dst_path;
struct dentry *src_dent_parent, *dst_dent_parent;
struct dentry *src_dent, *trap_dent, *src_child;
......@@ -808,8 +812,9 @@ int ksmbd_vfs_fp_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
trap_dent = lock_rename(src_dent_parent, dst_dent_parent);
dget(src_dent);
dget(dst_dent_parent);
src_child = lookup_one_len(src_dent->d_name.name, src_dent_parent,
src_dent->d_name.len);
user_ns = file_mnt_user_ns(fp->filp);
src_child = lookup_one(user_ns, src_dent->d_name.name, src_dent_parent,
src_dent->d_name.len);
if (IS_ERR(src_child)) {
err = PTR_ERR(src_child);
goto out_lock;
......@@ -823,7 +828,7 @@ 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),
user_ns,
src_dent_parent,
src_dent,
mnt_user_ns(dst_path.mnt),
......@@ -1109,7 +1114,7 @@ int ksmbd_vfs_unlink(struct user_namespace *user_ns,
{
int err = 0;
err = ksmbd_vfs_lock_parent(dir, dentry);
err = ksmbd_vfs_lock_parent(user_ns, dir, dentry);
if (err)
return err;
dget(dentry);
......@@ -1385,14 +1390,14 @@ static struct xattr_smb_acl *ksmbd_vfs_make_xattr_posix_acl(struct user_namespac
switch (pa_entry->e_tag) {
case ACL_USER:
xa_entry->type = SMB_ACL_USER;
xa_entry->uid = from_kuid(user_ns, pa_entry->e_uid);
xa_entry->uid = posix_acl_uid_translate(user_ns, pa_entry);
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(user_ns, pa_entry->e_gid);
xa_entry->gid = posix_acl_gid_translate(user_ns, pa_entry);
break;
case ACL_GROUP_OBJ:
xa_entry->type = SMB_ACL_GROUP_OBJ;
......
......@@ -107,7 +107,8 @@ struct ksmbd_kstat {
__le32 file_attributes;
};
int ksmbd_vfs_lock_parent(struct dentry *parent, struct dentry *child);
int ksmbd_vfs_lock_parent(struct user_namespace *user_ns, struct dentry *parent,
struct dentry *child);
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);
......
......@@ -666,22 +666,6 @@ void ksmbd_free_global_file_table(void)
ksmbd_destroy_file_table(&global_ft);
}
int ksmbd_file_table_flush(struct ksmbd_work *work)
{
struct ksmbd_file *fp = NULL;
unsigned int id;
int ret;
read_lock(&work->sess->file_table.lock);
idr_for_each_entry(work->sess->file_table.idr, fp, id) {
ret = ksmbd_vfs_fsync(work, fp->volatile_id, KSMBD_NO_FID);
if (ret)
break;
}
read_unlock(&work->sess->file_table.lock);
return ret;
}
int ksmbd_init_file_table(struct ksmbd_file_table *ft)
{
ft->idr = kzalloc(sizeof(struct idr), GFP_KERNEL);
......
......@@ -152,7 +152,6 @@ void ksmbd_close_session_fds(struct ksmbd_work *work);
int ksmbd_close_inode_fds(struct ksmbd_work *work, struct inode *inode);
int ksmbd_init_global_file_table(void);
void ksmbd_free_global_file_table(void);
int ksmbd_file_table_flush(struct ksmbd_work *work);
void ksmbd_set_fd_limit(unsigned long limit);
/*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment