Skip to content

Commit 2b4592c

Browse files
namjaejeongregkh
authored andcommitted
ksmbd: use opener credentials for ADS I/O
commit baa5e09 upstream. 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent e72c150 commit 2b4592c

1 file changed

Lines changed: 9 additions & 2 deletions

File tree

fs/smb/server/vfs.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,17 +278,20 @@ static ssize_t ksmbd_vfs_getcasexattr(struct mnt_idmap *idmap,
278278
static int ksmbd_vfs_stream_read(struct ksmbd_file *fp, char *buf, loff_t *pos,
279279
size_t count)
280280
{
281+
const struct cred *saved_cred;
281282
ssize_t v_len;
282283
char *stream_buf = NULL;
283284

284285
ksmbd_debug(VFS, "read stream data pos : %llu, count : %zd\n",
285286
*pos, count);
286287

288+
saved_cred = override_creds(fp->filp->f_cred);
287289
v_len = ksmbd_vfs_getcasexattr(file_mnt_idmap(fp->filp),
288290
fp->filp->f_path.dentry,
289291
fp->stream.name,
290292
fp->stream.size,
291293
&stream_buf);
294+
revert_creds(saved_cred);
292295
if ((int)v_len <= 0)
293296
return (int)v_len;
294297

@@ -411,6 +414,7 @@ int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, size_t count,
411414
static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos,
412415
size_t count)
413416
{
417+
const struct cred *saved_cred;
414418
char *stream_buf = NULL, *wbuf;
415419
struct mnt_idmap *idmap = file_mnt_idmap(fp->filp);
416420
size_t size;
@@ -431,6 +435,7 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos,
431435
count = XATTR_SIZE_MAX - *pos;
432436
}
433437

438+
saved_cred = override_creds(fp->filp->f_cred);
434439
v_len = ksmbd_vfs_getcasexattr(idmap,
435440
fp->filp->f_path.dentry,
436441
fp->stream.name,
@@ -439,14 +444,14 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos,
439444
if (v_len < 0) {
440445
pr_err("not found stream in xattr : %zd\n", v_len);
441446
err = v_len;
442-
goto out;
447+
goto out_revert;
443448
}
444449

445450
if (v_len < size) {
446451
wbuf = kvzalloc(size, KSMBD_DEFAULT_GFP);
447452
if (!wbuf) {
448453
err = -ENOMEM;
449-
goto out;
454+
goto out_revert;
450455
}
451456

452457
if (v_len > 0)
@@ -464,6 +469,8 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos,
464469
size,
465470
0,
466471
true);
472+
out_revert:
473+
revert_creds(saved_cred);
467474
if (err < 0)
468475
goto out;
469476
else

0 commit comments

Comments
 (0)