mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-27 00:51:35 +00:00
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: Ronnie Sahlberg <lsahlber@redhat.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
18a015bccf
commit
4ea477988c
2 changed files with 19 additions and 56 deletions
|
@ -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);
|
||||||
/*
|
|
||||||
* On delete request, instead of following up, need to
|
|
||||||
* look the current entity
|
|
||||||
*/
|
|
||||||
rc = ksmbd_vfs_kern_path(name, 0, &path, 1);
|
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
|
if (req->CreateOptions & FILE_DELETE_ON_CLOSE_LE) {
|
||||||
/*
|
/*
|
||||||
* If file exists with under flags, return access
|
* If file exists with under flags, return access
|
||||||
* denied error.
|
* denied error.
|
||||||
|
@ -2657,27 +2653,12 @@ 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 {
|
|
||||||
if (test_share_config_flag(work->tcon->share_conf,
|
|
||||||
KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS)) {
|
|
||||||
/*
|
|
||||||
* 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;
|
rc = -EACCES;
|
||||||
path_put(&path);
|
path_put(&path);
|
||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (rc) {
|
if (rc) {
|
||||||
if (rc == -EACCES) {
|
if (rc == -EACCES) {
|
||||||
|
@ -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))
|
rc = ksmbd_vfs_kern_path(share->path, LOOKUP_NO_SYMLINKS, &path, 0);
|
||||||
lookup_flags = LOOKUP_FOLLOW;
|
|
||||||
|
|
||||||
rc = ksmbd_vfs_kern_path(share->path, lookup_flags, &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,
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue