提交 4ea47798 编写于 作者: N Namjae Jeon 提交者: Steve French

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 <slow@samba.org>
Cc: Steve French <smfrench@gmail.com>
Acked-by: NRonnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: NNamjae Jeon <linkinjeon@kernel.org>
Signed-off-by: NSteve French <stfrench@microsoft.com>
上级 18a015bc
...@@ -2632,13 +2632,9 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2632,13 +2632,9 @@ int smb2_open(struct ksmbd_work *work)
goto err_out1; goto err_out1;
} }
if (req->CreateOptions & FILE_DELETE_ON_CLOSE_LE) { rc = ksmbd_vfs_kern_path(name, LOOKUP_NO_SYMLINKS, &path, 1);
/* if (!rc) {
* On delete request, instead of following up, need to if (req->CreateOptions & FILE_DELETE_ON_CLOSE_LE) {
* look the current entity
*/
rc = ksmbd_vfs_kern_path(name, 0, &path, 1);
if (!rc) {
/* /*
* If file exists with under flags, return access * If file exists with under flags, return access
* denied error. * denied error.
...@@ -2657,25 +2653,10 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2657,25 +2653,10 @@ int smb2_open(struct ksmbd_work *work)
path_put(&path); path_put(&path);
goto err_out; goto err_out;
} }
} } else if (d_is_symlink(path.dentry)) {
} else { rc = -EACCES;
if (test_share_config_flag(work->tcon->share_conf, path_put(&path);
KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS)) { goto err_out;
/*
* Use LOOKUP_FOLLOW to follow the path of
* symlink in path buildup
*/
rc = ksmbd_vfs_kern_path(name, LOOKUP_FOLLOW, &path, 1);
if (rc) { /* Case for broken link ?*/
rc = ksmbd_vfs_kern_path(name, 0, &path, 1);
}
} else {
rc = ksmbd_vfs_kern_path(name, 0, &path, 1);
if (!rc && d_is_symlink(path.dentry)) {
rc = -EACCES;
path_put(&path);
goto err_out;
}
} }
} }
...@@ -4751,12 +4732,8 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, ...@@ -4751,12 +4732,8 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
struct path path; struct path path;
int rc = 0, len; int rc = 0, len;
int fs_infoclass_size = 0; int fs_infoclass_size = 0;
int lookup_flags = 0;
if (test_share_config_flag(share, KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS))
lookup_flags = LOOKUP_FOLLOW;
rc = ksmbd_vfs_kern_path(share->path, lookup_flags, &path, 0); rc = ksmbd_vfs_kern_path(share->path, LOOKUP_NO_SYMLINKS, &path, 0);
if (rc) { if (rc) {
pr_err("cannot create vfs path\n"); pr_err("cannot create vfs path\n");
return -EIO; return -EIO;
...@@ -5333,7 +5310,7 @@ static int smb2_rename(struct ksmbd_work *work, ...@@ -5333,7 +5310,7 @@ static int smb2_rename(struct ksmbd_work *work,
} }
ksmbd_debug(SMB, "new name %s\n", new_name); ksmbd_debug(SMB, "new name %s\n", new_name);
rc = ksmbd_vfs_kern_path(new_name, 0, &path, 1); rc = ksmbd_vfs_kern_path(new_name, LOOKUP_NO_SYMLINKS, &path, 1);
if (rc) if (rc)
file_present = false; file_present = false;
else else
...@@ -5407,7 +5384,7 @@ static int smb2_create_link(struct ksmbd_work *work, ...@@ -5407,7 +5384,7 @@ static int smb2_create_link(struct ksmbd_work *work,
} }
ksmbd_debug(SMB, "target name is %s\n", target_name); ksmbd_debug(SMB, "target name is %s\n", target_name);
rc = ksmbd_vfs_kern_path(link_name, 0, &path, 0); rc = ksmbd_vfs_kern_path(link_name, LOOKUP_NO_SYMLINKS, &path, 0);
if (rc) if (rc)
file_present = false; file_present = false;
else else
......
...@@ -166,7 +166,7 @@ int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mode) ...@@ -166,7 +166,7 @@ int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mode)
struct dentry *dentry; struct dentry *dentry;
int err; int err;
dentry = kern_path_create(AT_FDCWD, name, &path, 0); dentry = kern_path_create(AT_FDCWD, name, &path, LOOKUP_NO_SYMLINKS);
if (IS_ERR(dentry)) { if (IS_ERR(dentry)) {
err = PTR_ERR(dentry); err = PTR_ERR(dentry);
if (err != -ENOENT) if (err != -ENOENT)
...@@ -203,7 +203,8 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode) ...@@ -203,7 +203,8 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode)
struct dentry *dentry; struct dentry *dentry;
int err; int err;
dentry = kern_path_create(AT_FDCWD, name, &path, LOOKUP_DIRECTORY); dentry = kern_path_create(AT_FDCWD, name, &path,
LOOKUP_NO_SYMLINKS | LOOKUP_DIRECTORY);
if (IS_ERR(dentry)) { if (IS_ERR(dentry)) {
err = PTR_ERR(dentry); err = PTR_ERR(dentry);
if (err != -EEXIST) if (err != -EEXIST)
...@@ -588,16 +589,11 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name) ...@@ -588,16 +589,11 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name)
struct path path; struct path path;
struct dentry *parent; struct dentry *parent;
int err; int err;
int flags = 0;
if (ksmbd_override_fsids(work)) if (ksmbd_override_fsids(work))
return -ENOMEM; return -ENOMEM;
if (test_share_config_flag(work->tcon->share_conf, err = kern_path(name, LOOKUP_NO_SYMLINKS, &path);
KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS))
flags = LOOKUP_FOLLOW;
err = kern_path(name, flags, &path);
if (err) { if (err) {
ksmbd_debug(VFS, "can't get %s, err %d\n", name, err); ksmbd_debug(VFS, "can't get %s, err %d\n", name, err);
ksmbd_revert_fsids(work); ksmbd_revert_fsids(work);
...@@ -652,16 +648,11 @@ int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname, ...@@ -652,16 +648,11 @@ int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname,
struct path oldpath, newpath; struct path oldpath, newpath;
struct dentry *dentry; struct dentry *dentry;
int err; int err;
int flags = 0;
if (ksmbd_override_fsids(work)) if (ksmbd_override_fsids(work))
return -ENOMEM; return -ENOMEM;
if (test_share_config_flag(work->tcon->share_conf, err = kern_path(oldname, LOOKUP_NO_SYMLINKS, &oldpath);
KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS))
flags = LOOKUP_FOLLOW;
err = kern_path(oldname, flags, &oldpath);
if (err) { if (err) {
pr_err("cannot get linux path for %s, err = %d\n", pr_err("cannot get linux path for %s, err = %d\n",
oldname, err); oldname, err);
...@@ -669,7 +660,7 @@ int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname, ...@@ -669,7 +660,7 @@ int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname,
} }
dentry = kern_path_create(AT_FDCWD, newname, &newpath, dentry = kern_path_create(AT_FDCWD, newname, &newpath,
flags | LOOKUP_REVAL); LOOKUP_NO_SYMLINKS | LOOKUP_REVAL);
if (IS_ERR(dentry)) { if (IS_ERR(dentry)) {
err = PTR_ERR(dentry); err = PTR_ERR(dentry);
pr_err("path create err for %s, err %d\n", newname, err); 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, ...@@ -788,7 +779,6 @@ int ksmbd_vfs_fp_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
struct dentry *src_dent, *trap_dent, *src_child; struct dentry *src_dent, *trap_dent, *src_child;
char *dst_name; char *dst_name;
int err; int err;
int flags;
dst_name = extract_last_component(newname); dst_name = extract_last_component(newname);
if (!dst_name) if (!dst_name)
...@@ -797,12 +787,8 @@ int ksmbd_vfs_fp_rename(struct ksmbd_work *work, struct ksmbd_file *fp, ...@@ -797,12 +787,8 @@ int ksmbd_vfs_fp_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
src_dent_parent = dget_parent(fp->filp->f_path.dentry); src_dent_parent = dget_parent(fp->filp->f_path.dentry);
src_dent = fp->filp->f_path.dentry; src_dent = fp->filp->f_path.dentry;
flags = LOOKUP_DIRECTORY; err = kern_path(newname, LOOKUP_NO_SYMLINKS | LOOKUP_DIRECTORY,
if (test_share_config_flag(work->tcon->share_conf, &dst_path);
KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS))
flags |= LOOKUP_FOLLOW;
err = kern_path(newname, flags, &dst_path);
if (err) { if (err) {
ksmbd_debug(VFS, "Cannot get path for %s [%d]\n", newname, err); ksmbd_debug(VFS, "Cannot get path for %s [%d]\n", newname, err);
goto out; goto out;
...@@ -861,7 +847,7 @@ int ksmbd_vfs_truncate(struct ksmbd_work *work, const char *name, ...@@ -861,7 +847,7 @@ int ksmbd_vfs_truncate(struct ksmbd_work *work, const char *name,
int err = 0; int err = 0;
if (name) { if (name) {
err = kern_path(name, 0, &path); err = kern_path(name, LOOKUP_NO_SYMLINKS, &path);
if (err) { if (err) {
pr_err("cannot get linux path for %s, err %d\n", pr_err("cannot get linux path for %s, err %d\n",
name, err); name, err);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册