mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-26 04:34:41 -04:00
ksmbd: use opener credentials for ADS I/O
Alternate data streams are stored as xattrs. Unlike regular file I/O, their read and write paths therefore call VFS xattr helpers which recheck inode permissions and LSM policy using the current task credentials. Run ADS I/O with the credentials captured when the SMB handle was opened. Cc: stable@vger.kernel.org Reported-by: Musaab Khan <musaab.khan@protonmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
committed by
Steve French
parent
cedff600f1
commit
baa5e09488
@@ -248,17 +248,20 @@ static ssize_t ksmbd_vfs_getcasexattr(struct mnt_idmap *idmap,
|
||||
static int ksmbd_vfs_stream_read(struct ksmbd_file *fp, char *buf, loff_t *pos,
|
||||
size_t count)
|
||||
{
|
||||
const struct cred *saved_cred;
|
||||
ssize_t v_len;
|
||||
char *stream_buf = NULL;
|
||||
|
||||
ksmbd_debug(VFS, "read stream data pos : %llu, count : %zd\n",
|
||||
*pos, count);
|
||||
|
||||
saved_cred = override_creds(fp->filp->f_cred);
|
||||
v_len = ksmbd_vfs_getcasexattr(file_mnt_idmap(fp->filp),
|
||||
fp->filp->f_path.dentry,
|
||||
fp->stream.name,
|
||||
fp->stream.size,
|
||||
&stream_buf);
|
||||
revert_creds(saved_cred);
|
||||
if ((int)v_len <= 0)
|
||||
return (int)v_len;
|
||||
|
||||
@@ -382,6 +385,7 @@ int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, size_t count,
|
||||
static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos,
|
||||
size_t count)
|
||||
{
|
||||
const struct cred *saved_cred;
|
||||
char *stream_buf = NULL, *wbuf;
|
||||
struct mnt_idmap *idmap = file_mnt_idmap(fp->filp);
|
||||
size_t size;
|
||||
@@ -402,6 +406,7 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos,
|
||||
count = XATTR_SIZE_MAX - *pos;
|
||||
}
|
||||
|
||||
saved_cred = override_creds(fp->filp->f_cred);
|
||||
v_len = ksmbd_vfs_getcasexattr(idmap,
|
||||
fp->filp->f_path.dentry,
|
||||
fp->stream.name,
|
||||
@@ -410,14 +415,14 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos,
|
||||
if (v_len < 0) {
|
||||
pr_err("not found stream in xattr : %zd\n", v_len);
|
||||
err = v_len;
|
||||
goto out;
|
||||
goto out_revert;
|
||||
}
|
||||
|
||||
if (v_len < size) {
|
||||
wbuf = kvzalloc(size, KSMBD_DEFAULT_GFP);
|
||||
if (!wbuf) {
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
goto out_revert;
|
||||
}
|
||||
|
||||
if (v_len > 0)
|
||||
@@ -435,6 +440,8 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos,
|
||||
size,
|
||||
0,
|
||||
true);
|
||||
out_revert:
|
||||
revert_creds(saved_cred);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user