]> git.baikalelectronics.ru Git - kernel.git/commitdiff
ksmbd: remove follow symlinks support
authorNamjae Jeon <linkinjeon@kernel.org>
Tue, 21 Sep 2021 05:19:33 +0000 (14:19 +0900)
committerSteve French <stfrench@microsoft.com>
Thu, 23 Sep 2021 04:37:38 +0000 (23:37 -0500)
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>
fs/ksmbd/smb2pdu.c
fs/ksmbd/vfs.c

index fd9d5595a5cadc75e53680b0787cb6d2f0ab69d0..0c49a0e887d3804d6b0182daaea03d1e135c0b4a 100644 (file)
@@ -2632,13 +2632,9 @@ int smb2_open(struct ksmbd_work *work)
                goto err_out1;
        }
 
-       if (req->CreateOptions & FILE_DELETE_ON_CLOSE_LE) {
-               /*
-                * On delete request, instead of following up, need to
-                * look the current entity
-                */
-               rc = ksmbd_vfs_kern_path(name, 0, &path, 1);
-               if (!rc) {
+       rc = ksmbd_vfs_kern_path(name, LOOKUP_NO_SYMLINKS, &path, 1);
+       if (!rc) {
+               if (req->CreateOptions & FILE_DELETE_ON_CLOSE_LE) {
                        /*
                         * If file exists with under flags, return access
                         * denied error.
@@ -2657,25 +2653,10 @@ int smb2_open(struct ksmbd_work *work)
                                path_put(&path);
                                goto err_out;
                        }
-               }
-       } 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;
-                               path_put(&path);
-                               goto err_out;
-                       }
+               } else if (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,
        struct path path;
        int rc = 0, len;
        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) {
                pr_err("cannot create vfs path\n");
                return -EIO;
@@ -5333,7 +5310,7 @@ static int smb2_rename(struct ksmbd_work *work,
        }
 
        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)
                file_present = false;
        else
@@ -5407,7 +5384,7 @@ static int smb2_create_link(struct ksmbd_work *work,
        }
 
        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)
                file_present = false;
        else
index b047f2980d96c6a32190c8822760b8e1d01fa907..3733e4944c1d784736991c9dfa3dc0ba6d07f7ad 100644 (file)
@@ -166,7 +166,7 @@ int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mode)
        struct dentry *dentry;
        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)) {
                err = PTR_ERR(dentry);
                if (err != -ENOENT)
@@ -203,7 +203,8 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode)
        struct dentry *dentry;
        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)) {
                err = PTR_ERR(dentry);
                if (err != -EEXIST)
@@ -588,16 +589,11 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name)
        struct path path;
        struct dentry *parent;
        int err;
-       int flags = 0;
 
        if (ksmbd_override_fsids(work))
                return -ENOMEM;
 
-       if (test_share_config_flag(work->tcon->share_conf,
-                                  KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS))
-               flags = LOOKUP_FOLLOW;
-
-       err = kern_path(name, flags, &path);
+       err = kern_path(name, LOOKUP_NO_SYMLINKS, &path);
        if (err) {
                ksmbd_debug(VFS, "can't get %s, err %d\n", name, err);
                ksmbd_revert_fsids(work);
@@ -652,16 +648,11 @@ int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname,
        struct path oldpath, newpath;
        struct dentry *dentry;
        int err;
-       int flags = 0;
 
        if (ksmbd_override_fsids(work))
                return -ENOMEM;
 
-       if (test_share_config_flag(work->tcon->share_conf,
-                                  KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS))
-               flags = LOOKUP_FOLLOW;
-
-       err = kern_path(oldname, flags, &oldpath);
+       err = kern_path(oldname, LOOKUP_NO_SYMLINKS, &oldpath);
        if (err) {
                pr_err("cannot get linux path for %s, err = %d\n",
                       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,
-                                 flags | LOOKUP_REVAL);
+                                 LOOKUP_NO_SYMLINKS | LOOKUP_REVAL);
        if (IS_ERR(dentry)) {
                err = PTR_ERR(dentry);
                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;
        char *dst_name;
        int err;
-       int flags;
 
        dst_name = extract_last_component(newname);
        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 = fp->filp->f_path.dentry;
 
-       flags = LOOKUP_DIRECTORY;
-       if (test_share_config_flag(work->tcon->share_conf,
-                                  KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS))
-               flags |= LOOKUP_FOLLOW;
-
-       err = kern_path(newname, flags, &dst_path);
+       err = kern_path(newname, LOOKUP_NO_SYMLINKS | LOOKUP_DIRECTORY,
+                       &dst_path);
        if (err) {
                ksmbd_debug(VFS, "Cannot get path for %s [%d]\n", newname, err);
                goto out;
@@ -861,7 +847,7 @@ int ksmbd_vfs_truncate(struct ksmbd_work *work, const char *name,
        int err = 0;
 
        if (name) {
-               err = kern_path(name, 0, &path);
+               err = kern_path(name, LOOKUP_NO_SYMLINKS, &path);
                if (err) {
                        pr_err("cannot get linux path for %s, err %d\n",
                               name, err);