Skip to content

Commit 4ea4779

Browse files
namjaejeonsmfrench
authored andcommitted
ksmbd: remove follow symlinks support
Use LOOKUP_NO_SYMLINKS flags for default lookup to prohibit the middle of symlink component lookup and remove follow symlinks parameter support. We re-implement it as reparse point later. Test result: smbclient -Ulinkinjeon%1234 //172.30.1.42/share -c "get hacked/passwd passwd" NT_STATUS_OBJECT_NAME_NOT_FOUND opening remote file \hacked\passwd Cc: Ralph Böhme <[email protected]> Cc: Steve French <[email protected]> Acked-by: Ronnie Sahlberg <[email protected]> Signed-off-by: Namjae Jeon <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 18a015b commit 4ea4779

File tree

2 files changed

+19
-56
lines changed

2 files changed

+19
-56
lines changed

fs/ksmbd/smb2pdu.c

Lines changed: 10 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2632,13 +2632,9 @@ int smb2_open(struct ksmbd_work *work)
26322632
goto err_out1;
26332633
}
26342634

2635-
if (req->CreateOptions & FILE_DELETE_ON_CLOSE_LE) {
2636-
/*
2637-
* On delete request, instead of following up, need to
2638-
* look the current entity
2639-
*/
2640-
rc = ksmbd_vfs_kern_path(name, 0, &path, 1);
2641-
if (!rc) {
2635+
rc = ksmbd_vfs_kern_path(name, LOOKUP_NO_SYMLINKS, &path, 1);
2636+
if (!rc) {
2637+
if (req->CreateOptions & FILE_DELETE_ON_CLOSE_LE) {
26422638
/*
26432639
* If file exists with under flags, return access
26442640
* denied error.
@@ -2657,25 +2653,10 @@ int smb2_open(struct ksmbd_work *work)
26572653
path_put(&path);
26582654
goto err_out;
26592655
}
2660-
}
2661-
} else {
2662-
if (test_share_config_flag(work->tcon->share_conf,
2663-
KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS)) {
2664-
/*
2665-
* Use LOOKUP_FOLLOW to follow the path of
2666-
* symlink in path buildup
2667-
*/
2668-
rc = ksmbd_vfs_kern_path(name, LOOKUP_FOLLOW, &path, 1);
2669-
if (rc) { /* Case for broken link ?*/
2670-
rc = ksmbd_vfs_kern_path(name, 0, &path, 1);
2671-
}
2672-
} else {
2673-
rc = ksmbd_vfs_kern_path(name, 0, &path, 1);
2674-
if (!rc && d_is_symlink(path.dentry)) {
2675-
rc = -EACCES;
2676-
path_put(&path);
2677-
goto err_out;
2678-
}
2656+
} else if (d_is_symlink(path.dentry)) {
2657+
rc = -EACCES;
2658+
path_put(&path);
2659+
goto err_out;
26792660
}
26802661
}
26812662

@@ -4751,12 +4732,8 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
47514732
struct path path;
47524733
int rc = 0, len;
47534734
int fs_infoclass_size = 0;
4754-
int lookup_flags = 0;
4755-
4756-
if (test_share_config_flag(share, KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS))
4757-
lookup_flags = LOOKUP_FOLLOW;
47584735

4759-
rc = ksmbd_vfs_kern_path(share->path, lookup_flags, &path, 0);
4736+
rc = ksmbd_vfs_kern_path(share->path, LOOKUP_NO_SYMLINKS, &path, 0);
47604737
if (rc) {
47614738
pr_err("cannot create vfs path\n");
47624739
return -EIO;
@@ -5333,7 +5310,7 @@ static int smb2_rename(struct ksmbd_work *work,
53335310
}
53345311

53355312
ksmbd_debug(SMB, "new name %s\n", new_name);
5336-
rc = ksmbd_vfs_kern_path(new_name, 0, &path, 1);
5313+
rc = ksmbd_vfs_kern_path(new_name, LOOKUP_NO_SYMLINKS, &path, 1);
53375314
if (rc)
53385315
file_present = false;
53395316
else
@@ -5407,7 +5384,7 @@ static int smb2_create_link(struct ksmbd_work *work,
54075384
}
54085385

54095386
ksmbd_debug(SMB, "target name is %s\n", target_name);
5410-
rc = ksmbd_vfs_kern_path(link_name, 0, &path, 0);
5387+
rc = ksmbd_vfs_kern_path(link_name, LOOKUP_NO_SYMLINKS, &path, 0);
54115388
if (rc)
54125389
file_present = false;
54135390
else

fs/ksmbd/vfs.c

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mode)
166166
struct dentry *dentry;
167167
int err;
168168

169-
dentry = kern_path_create(AT_FDCWD, name, &path, 0);
169+
dentry = kern_path_create(AT_FDCWD, name, &path, LOOKUP_NO_SYMLINKS);
170170
if (IS_ERR(dentry)) {
171171
err = PTR_ERR(dentry);
172172
if (err != -ENOENT)
@@ -203,7 +203,8 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode)
203203
struct dentry *dentry;
204204
int err;
205205

206-
dentry = kern_path_create(AT_FDCWD, name, &path, LOOKUP_DIRECTORY);
206+
dentry = kern_path_create(AT_FDCWD, name, &path,
207+
LOOKUP_NO_SYMLINKS | LOOKUP_DIRECTORY);
207208
if (IS_ERR(dentry)) {
208209
err = PTR_ERR(dentry);
209210
if (err != -EEXIST)
@@ -588,16 +589,11 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name)
588589
struct path path;
589590
struct dentry *parent;
590591
int err;
591-
int flags = 0;
592592

593593
if (ksmbd_override_fsids(work))
594594
return -ENOMEM;
595595

596-
if (test_share_config_flag(work->tcon->share_conf,
597-
KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS))
598-
flags = LOOKUP_FOLLOW;
599-
600-
err = kern_path(name, flags, &path);
596+
err = kern_path(name, LOOKUP_NO_SYMLINKS, &path);
601597
if (err) {
602598
ksmbd_debug(VFS, "can't get %s, err %d\n", name, err);
603599
ksmbd_revert_fsids(work);
@@ -652,24 +648,19 @@ int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname,
652648
struct path oldpath, newpath;
653649
struct dentry *dentry;
654650
int err;
655-
int flags = 0;
656651

657652
if (ksmbd_override_fsids(work))
658653
return -ENOMEM;
659654

660-
if (test_share_config_flag(work->tcon->share_conf,
661-
KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS))
662-
flags = LOOKUP_FOLLOW;
663-
664-
err = kern_path(oldname, flags, &oldpath);
655+
err = kern_path(oldname, LOOKUP_NO_SYMLINKS, &oldpath);
665656
if (err) {
666657
pr_err("cannot get linux path for %s, err = %d\n",
667658
oldname, err);
668659
goto out1;
669660
}
670661

671662
dentry = kern_path_create(AT_FDCWD, newname, &newpath,
672-
flags | LOOKUP_REVAL);
663+
LOOKUP_NO_SYMLINKS | LOOKUP_REVAL);
673664
if (IS_ERR(dentry)) {
674665
err = PTR_ERR(dentry);
675666
pr_err("path create err for %s, err %d\n", newname, err);
@@ -788,7 +779,6 @@ int ksmbd_vfs_fp_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
788779
struct dentry *src_dent, *trap_dent, *src_child;
789780
char *dst_name;
790781
int err;
791-
int flags;
792782

793783
dst_name = extract_last_component(newname);
794784
if (!dst_name)
@@ -797,12 +787,8 @@ int ksmbd_vfs_fp_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
797787
src_dent_parent = dget_parent(fp->filp->f_path.dentry);
798788
src_dent = fp->filp->f_path.dentry;
799789

800-
flags = LOOKUP_DIRECTORY;
801-
if (test_share_config_flag(work->tcon->share_conf,
802-
KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS))
803-
flags |= LOOKUP_FOLLOW;
804-
805-
err = kern_path(newname, flags, &dst_path);
790+
err = kern_path(newname, LOOKUP_NO_SYMLINKS | LOOKUP_DIRECTORY,
791+
&dst_path);
806792
if (err) {
807793
ksmbd_debug(VFS, "Cannot get path for %s [%d]\n", newname, err);
808794
goto out;
@@ -861,7 +847,7 @@ int ksmbd_vfs_truncate(struct ksmbd_work *work, const char *name,
861847
int err = 0;
862848

863849
if (name) {
864-
err = kern_path(name, 0, &path);
850+
err = kern_path(name, LOOKUP_NO_SYMLINKS, &path);
865851
if (err) {
866852
pr_err("cannot get linux path for %s, err %d\n",
867853
name, err);

0 commit comments

Comments
 (0)