diff mbox series

[RESEND] ksmbd: remove filename in ksmbd_file

Message ID 20220412225706.5464-1-linkinjeon@kernel.org
State New
Headers show
Series [RESEND] ksmbd: remove filename in ksmbd_file | expand

Commit Message

Namjae Jeon April 12, 2022, 10:57 p.m. UTC
If the filename is change by underlying rename the server, fp->filename
and real filename can be different. This patch remove the uses of
fp->filename in ksmbd and replace it with d_path().

Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
---
 fs/ksmbd/misc.c      | 40 +++++++++++++++++++++++++++++++---------
 fs/ksmbd/misc.h      |  3 ++-
 fs/ksmbd/oplock.c    | 30 ------------------------------
 fs/ksmbd/oplock.h    |  2 --
 fs/ksmbd/smb2pdu.c   | 21 +++++++--------------
 fs/ksmbd/vfs.c       |  6 ++----
 fs/ksmbd/vfs_cache.c |  1 -
 fs/ksmbd/vfs_cache.h |  1 -
 8 files changed, 42 insertions(+), 62 deletions(-)

Comments

Hyunchul Lee April 13, 2022, 11:29 p.m. UTC | #1
2022년 4월 13일 (수) 오전 7:57, Namjae Jeon <linkinjeon@kernel.org>님이 작성:
>
> If the filename is change by underlying rename the server, fp->filename
> and real filename can be different. This patch remove the uses of
> fp->filename in ksmbd and replace it with d_path().
>
> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
> ---
>  fs/ksmbd/misc.c      | 40 +++++++++++++++++++++++++++++++---------
>  fs/ksmbd/misc.h      |  3 ++-
>  fs/ksmbd/oplock.c    | 30 ------------------------------
>  fs/ksmbd/oplock.h    |  2 --
>  fs/ksmbd/smb2pdu.c   | 21 +++++++--------------
>  fs/ksmbd/vfs.c       |  6 ++----
>  fs/ksmbd/vfs_cache.c |  1 -
>  fs/ksmbd/vfs_cache.h |  1 -
>  8 files changed, 42 insertions(+), 62 deletions(-)
>
> diff --git a/fs/ksmbd/misc.c b/fs/ksmbd/misc.c
> index 60e7ac62c917..20d4455a0a99 100644
> --- a/fs/ksmbd/misc.c
> +++ b/fs/ksmbd/misc.c
> @@ -158,19 +158,41 @@ int parse_stream_name(char *filename, char **stream_name, int *s_type)
>   * Return : windows path string or error
>   */
>
> -char *convert_to_nt_pathname(char *filename)
> +char *convert_to_nt_pathname(struct ksmbd_share_config *share,
> +                            struct path *path)
>  {
> -       char *ab_pathname;
> +       char *pathname, *ab_pathname, *nt_pathname;
> +       int share_path_len = strlen(share->path);

We can use share->path_sz instead of calling strlen.

>
> -       if (strlen(filename) == 0)
> -               filename = "\\";
> +       pathname = kmalloc(PATH_MAX, GFP_KERNEL);
> +       if (!pathname)
> +               return ERR_PTR(-EACCES);
>
> -       ab_pathname = kstrdup(filename, GFP_KERNEL);
> -       if (!ab_pathname)
> -               return NULL;
> +       ab_pathname = d_path(path, pathname, PATH_MAX);
> +       if (IS_ERR(ab_pathname)) {
> +               nt_pathname = ERR_PTR(-EACCES);
> +               goto free_pathname;
> +       }
> +
> +       if (strncmp(ab_pathname, share->path, share_path_len)) {
> +               nt_pathname = ERR_PTR(-EACCES);
> +               goto free_pathname;
> +       }
> +
> +       nt_pathname = kzalloc(strlen(&ab_pathname[share_path_len]) + 1, GFP_KERNEL);
> +       if (!nt_pathname) {
> +               nt_pathname = ERR_PTR(-ENOMEM);
> +               goto free_pathname;
> +       }
> +       if (ab_pathname[share_path_len] == '\0')
> +               strcpy(nt_pathname, "/");

If ab_pathname and share->path store the same string literal,
the size of nt_pathname is 1 byte. Could this strcpy make
buffer overrun?

> +       strcat(nt_pathname, &ab_pathname[share_path_len]);
> +
> +       ksmbd_conv_path_to_windows(nt_pathname);
>
> -       ksmbd_conv_path_to_windows(ab_pathname);
> -       return ab_pathname;
> +free_pathname:
> +       kfree(pathname);
> +       return nt_pathname;
>  }
>
>  int get_nlink(struct kstat *st)
> diff --git a/fs/ksmbd/misc.h b/fs/ksmbd/misc.h
> index 253366bd0951..aae2a252945f 100644
> --- a/fs/ksmbd/misc.h
> +++ b/fs/ksmbd/misc.h
> @@ -14,7 +14,8 @@ struct ksmbd_file;
>  int match_pattern(const char *str, size_t len, const char *pattern);
>  int ksmbd_validate_filename(char *filename);
>  int parse_stream_name(char *filename, char **stream_name, int *s_type);
> -char *convert_to_nt_pathname(char *filename);
> +char *convert_to_nt_pathname(struct ksmbd_share_config *share,
> +                            struct path *path);
>  int get_nlink(struct kstat *st);
>  void ksmbd_conv_path_to_unix(char *path);
>  void ksmbd_strip_last_slash(char *path);
> diff --git a/fs/ksmbd/oplock.c b/fs/ksmbd/oplock.c
> index 23871b18a429..8b5560574d4c 100644
> --- a/fs/ksmbd/oplock.c
> +++ b/fs/ksmbd/oplock.c
> @@ -1694,33 +1694,3 @@ struct oplock_info *lookup_lease_in_table(struct ksmbd_conn *conn,
>         read_unlock(&lease_list_lock);
>         return ret_op;
>  }
> -
> -int smb2_check_durable_oplock(struct ksmbd_file *fp,
> -                             struct lease_ctx_info *lctx, char *name)
> -{
> -       struct oplock_info *opinfo = opinfo_get(fp);
> -       int ret = 0;
> -
> -       if (opinfo && opinfo->is_lease) {
> -               if (!lctx) {
> -                       pr_err("open does not include lease\n");
> -                       ret = -EBADF;
> -                       goto out;
> -               }
> -               if (memcmp(opinfo->o_lease->lease_key, lctx->lease_key,
> -                          SMB2_LEASE_KEY_SIZE)) {
> -                       pr_err("invalid lease key\n");
> -                       ret = -EBADF;
> -                       goto out;
> -               }
> -               if (name && strcmp(fp->filename, name)) {
> -                       pr_err("invalid name reconnect %s\n", name);
> -                       ret = -EINVAL;
> -                       goto out;
> -               }
> -       }
> -out:
> -       if (opinfo)
> -               opinfo_put(opinfo);
> -       return ret;
> -}
> diff --git a/fs/ksmbd/oplock.h b/fs/ksmbd/oplock.h
> index 0cf7a2b5bbc0..09753448f779 100644
> --- a/fs/ksmbd/oplock.h
> +++ b/fs/ksmbd/oplock.h
> @@ -124,6 +124,4 @@ struct oplock_info *lookup_lease_in_table(struct ksmbd_conn *conn,
>  int find_same_lease_key(struct ksmbd_session *sess, struct ksmbd_inode *ci,
>                         struct lease_ctx_info *lctx);
>  void destroy_lease_table(struct ksmbd_conn *conn);
> -int smb2_check_durable_oplock(struct ksmbd_file *fp,
> -                             struct lease_ctx_info *lctx, char *name);
>  #endif /* __KSMBD_OPLOCK_H */
> diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c
> index 3bf6c56c654c..e38fb68ded21 100644
> --- a/fs/ksmbd/smb2pdu.c
> +++ b/fs/ksmbd/smb2pdu.c
> @@ -2918,7 +2918,6 @@ int smb2_open(struct ksmbd_work *work)
>                 goto err_out;
>         }
>
> -       fp->filename = name;
>         fp->cdoption = req->CreateDisposition;
>         fp->daccess = daccess;
>         fp->saccess = req->ShareAccess;
> @@ -3270,14 +3269,13 @@ int smb2_open(struct ksmbd_work *work)
>                 if (!rsp->hdr.Status)
>                         rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR;
>
> -               if (!fp || !fp->filename)
> -                       kfree(name);
>                 if (fp)
>                         ksmbd_fd_put(work, fp);
>                 smb2_set_err_rsp(work);
>                 ksmbd_debug(SMB, "Error response: %x\n", rsp->hdr.Status);
>         }
>
> +       kfree(name);
>         kfree(lc);
>
>         return 0;
> @@ -3895,8 +3893,6 @@ int smb2_query_dir(struct ksmbd_work *work)
>                 ksmbd_debug(SMB, "Search pattern is %s\n", srch_ptr);
>         }
>
> -       ksmbd_debug(SMB, "Directory name is %s\n", dir_fp->filename);
> -
>         if (srch_flag & SMB2_REOPEN || srch_flag & SMB2_RESTART_SCANS) {
>                 ksmbd_debug(SMB, "Restart directory scan\n");
>                 generic_file_llseek(dir_fp->filp, 0, SEEK_SET);
> @@ -4390,9 +4386,9 @@ static int get_file_all_info(struct ksmbd_work *work,
>                 return -EACCES;
>         }
>
> -       filename = convert_to_nt_pathname(fp->filename);
> -       if (!filename)
> -               return -ENOMEM;
> +       filename = convert_to_nt_pathname(work->tcon->share_conf, &fp->filp->f_path);
> +       if (IS_ERR(filename))
> +               return PTR_ERR(filename);
>
>         inode = file_inode(fp->filp);
>         generic_fillattr(file_mnt_user_ns(fp->filp), inode, &stat);
> @@ -5683,8 +5679,7 @@ static int set_file_allocation_info(struct ksmbd_work *work,
>                 size = i_size_read(inode);
>                 rc = ksmbd_vfs_truncate(work, fp, alloc_blks * 512);
>                 if (rc) {
> -                       pr_err("truncate failed! filename : %s, err %d\n",
> -                              fp->filename, rc);
> +                       pr_err("truncate failed!, err %d\n", rc);
>                         return rc;
>                 }
>                 if (size < alloc_blks * 512)
> @@ -5714,12 +5709,10 @@ static int set_end_of_file_info(struct ksmbd_work *work, struct ksmbd_file *fp,
>          * truncated range.
>          */
>         if (inode->i_sb->s_magic != MSDOS_SUPER_MAGIC) {
> -               ksmbd_debug(SMB, "filename : %s truncated to newsize %lld\n",
> -                           fp->filename, newsize);
> +               ksmbd_debug(SMB, "truncated to newsize %lld\n", newsize);
>                 rc = ksmbd_vfs_truncate(work, fp, newsize);
>                 if (rc) {
> -                       ksmbd_debug(SMB, "truncate failed! filename : %s err %d\n",
> -                                   fp->filename, rc);
> +                       ksmbd_debug(SMB, "truncate failed!, err %d\n", rc);
>                         if (rc != -EAGAIN)
>                                 rc = -EBADF;
>                         return rc;
> diff --git a/fs/ksmbd/vfs.c b/fs/ksmbd/vfs.c
> index 9cebb6ba555b..dcdd07c6efff 100644
> --- a/fs/ksmbd/vfs.c
> +++ b/fs/ksmbd/vfs.c
> @@ -398,8 +398,7 @@ int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, size_t count,
>
>         nbytes = kernel_read(filp, rbuf, count, pos);
>         if (nbytes < 0) {
> -               pr_err("smb read failed for (%s), err = %zd\n",
> -                      fp->filename, nbytes);
> +               pr_err("smb read failed, err = %zd\n", nbytes);
>                 return nbytes;
>         }
>
> @@ -875,8 +874,7 @@ int ksmbd_vfs_truncate(struct ksmbd_work *work,
>
>         err = vfs_truncate(&filp->f_path, size);
>         if (err)
> -               pr_err("truncate failed for filename : %s err %d\n",
> -                      fp->filename, err);
> +               pr_err("truncate failed, err %d\n", err);
>         return err;
>  }
>
> diff --git a/fs/ksmbd/vfs_cache.c b/fs/ksmbd/vfs_cache.c
> index 29c1db66bd0f..0974d2e972b9 100644
> --- a/fs/ksmbd/vfs_cache.c
> +++ b/fs/ksmbd/vfs_cache.c
> @@ -328,7 +328,6 @@ static void __ksmbd_close_fd(struct ksmbd_file_table *ft, struct ksmbd_file *fp)
>                 kfree(smb_lock);
>         }
>
> -       kfree(fp->filename);
>         if (ksmbd_stream_fd(fp))
>                 kfree(fp->stream.name);
>         kmem_cache_free(filp_cache, fp);
> diff --git a/fs/ksmbd/vfs_cache.h b/fs/ksmbd/vfs_cache.h
> index 36239ce31afd..fcb13413fa8d 100644
> --- a/fs/ksmbd/vfs_cache.h
> +++ b/fs/ksmbd/vfs_cache.h
> @@ -62,7 +62,6 @@ struct ksmbd_inode {
>
>  struct ksmbd_file {
>         struct file                     *filp;
> -       char                            *filename;
>         u64                             persistent_id;
>         u64                             volatile_id;
>
> --
> 2.25.1
>
Namjae Jeon April 14, 2022, 12:29 a.m. UTC | #2
2022-04-14 8:29 GMT+09:00, Hyunchul Lee <hyc.lee@gmail.com>:
> 2022년 4월 13일 (수) 오전 7:57, Namjae Jeon <linkinjeon@kernel.org>님이 작성:
>>
>> If the filename is change by underlying rename the server, fp->filename
>> and real filename can be different. This patch remove the uses of
>> fp->filename in ksmbd and replace it with d_path().
>>
>> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
>> ---
>>  fs/ksmbd/misc.c      | 40 +++++++++++++++++++++++++++++++---------
>>  fs/ksmbd/misc.h      |  3 ++-
>>  fs/ksmbd/oplock.c    | 30 ------------------------------
>>  fs/ksmbd/oplock.h    |  2 --
>>  fs/ksmbd/smb2pdu.c   | 21 +++++++--------------
>>  fs/ksmbd/vfs.c       |  6 ++----
>>  fs/ksmbd/vfs_cache.c |  1 -
>>  fs/ksmbd/vfs_cache.h |  1 -
>>  8 files changed, 42 insertions(+), 62 deletions(-)
>>
>> diff --git a/fs/ksmbd/misc.c b/fs/ksmbd/misc.c
>> index 60e7ac62c917..20d4455a0a99 100644
>> --- a/fs/ksmbd/misc.c
>> +++ b/fs/ksmbd/misc.c
>> @@ -158,19 +158,41 @@ int parse_stream_name(char *filename, char
>> **stream_name, int *s_type)
>>   * Return : windows path string or error
>>   */
>>
>> -char *convert_to_nt_pathname(char *filename)
>> +char *convert_to_nt_pathname(struct ksmbd_share_config *share,
>> +                            struct path *path)
>>  {
>> -       char *ab_pathname;
>> +       char *pathname, *ab_pathname, *nt_pathname;
>> +       int share_path_len = strlen(share->path);
>
Hi Hyunchul,
> We can use share->path_sz instead of calling strlen.
Okay.
>
>>
>> -       if (strlen(filename) == 0)
>> -               filename = "\\";
>> +       pathname = kmalloc(PATH_MAX, GFP_KERNEL);
>> +       if (!pathname)
>> +               return ERR_PTR(-EACCES);
>>
>> -       ab_pathname = kstrdup(filename, GFP_KERNEL);
>> -       if (!ab_pathname)
>> -               return NULL;
>> +       ab_pathname = d_path(path, pathname, PATH_MAX);
>> +       if (IS_ERR(ab_pathname)) {
>> +               nt_pathname = ERR_PTR(-EACCES);
>> +               goto free_pathname;
>> +       }
>> +
>> +       if (strncmp(ab_pathname, share->path, share_path_len)) {
>> +               nt_pathname = ERR_PTR(-EACCES);
>> +               goto free_pathname;
>> +       }
>> +
>> +       nt_pathname = kzalloc(strlen(&ab_pathname[share_path_len]) + 1,
>> GFP_KERNEL);
>> +       if (!nt_pathname) {
>> +               nt_pathname = ERR_PTR(-ENOMEM);
>> +               goto free_pathname;
>> +       }
>> +       if (ab_pathname[share_path_len] == '\0')
>> +               strcpy(nt_pathname, "/");
>
> If ab_pathname and share->path store the same string literal,
> the size of nt_pathname is 1 byte. Could this strcpy make
> buffer overrun?
Will fix it.
Thanks:)
>
>> +       strcat(nt_pathname, &ab_pathname[share_path_len]);
>> +
>> +       ksmbd_conv_path_to_windows(nt_pathname);
>>
>> -       ksmbd_conv_path_to_windows(ab_pathname);
>> -       return ab_pathname;
>> +free_pathname:
>> +       kfree(pathname);
>> +       return nt_pathname;
>>  }
>>
>>  int get_nlink(struct kstat *st)
>> diff --git a/fs/ksmbd/misc.h b/fs/ksmbd/misc.h
>> index 253366bd0951..aae2a252945f 100644
>> --- a/fs/ksmbd/misc.h
>> +++ b/fs/ksmbd/misc.h
>> @@ -14,7 +14,8 @@ struct ksmbd_file;
>>  int match_pattern(const char *str, size_t len, const char *pattern);
>>  int ksmbd_validate_filename(char *filename);
>>  int parse_stream_name(char *filename, char **stream_name, int *s_type);
>> -char *convert_to_nt_pathname(char *filename);
>> +char *convert_to_nt_pathname(struct ksmbd_share_config *share,
>> +                            struct path *path);
>>  int get_nlink(struct kstat *st);
>>  void ksmbd_conv_path_to_unix(char *path);
>>  void ksmbd_strip_last_slash(char *path);
>> diff --git a/fs/ksmbd/oplock.c b/fs/ksmbd/oplock.c
>> index 23871b18a429..8b5560574d4c 100644
>> --- a/fs/ksmbd/oplock.c
>> +++ b/fs/ksmbd/oplock.c
>> @@ -1694,33 +1694,3 @@ struct oplock_info *lookup_lease_in_table(struct
>> ksmbd_conn *conn,
>>         read_unlock(&lease_list_lock);
>>         return ret_op;
>>  }
>> -
>> -int smb2_check_durable_oplock(struct ksmbd_file *fp,
>> -                             struct lease_ctx_info *lctx, char *name)
>> -{
>> -       struct oplock_info *opinfo = opinfo_get(fp);
>> -       int ret = 0;
>> -
>> -       if (opinfo && opinfo->is_lease) {
>> -               if (!lctx) {
>> -                       pr_err("open does not include lease\n");
>> -                       ret = -EBADF;
>> -                       goto out;
>> -               }
>> -               if (memcmp(opinfo->o_lease->lease_key, lctx->lease_key,
>> -                          SMB2_LEASE_KEY_SIZE)) {
>> -                       pr_err("invalid lease key\n");
>> -                       ret = -EBADF;
>> -                       goto out;
>> -               }
>> -               if (name && strcmp(fp->filename, name)) {
>> -                       pr_err("invalid name reconnect %s\n", name);
>> -                       ret = -EINVAL;
>> -                       goto out;
>> -               }
>> -       }
>> -out:
>> -       if (opinfo)
>> -               opinfo_put(opinfo);
>> -       return ret;
>> -}
>> diff --git a/fs/ksmbd/oplock.h b/fs/ksmbd/oplock.h
>> index 0cf7a2b5bbc0..09753448f779 100644
>> --- a/fs/ksmbd/oplock.h
>> +++ b/fs/ksmbd/oplock.h
>> @@ -124,6 +124,4 @@ struct oplock_info *lookup_lease_in_table(struct
>> ksmbd_conn *conn,
>>  int find_same_lease_key(struct ksmbd_session *sess, struct ksmbd_inode
>> *ci,
>>                         struct lease_ctx_info *lctx);
>>  void destroy_lease_table(struct ksmbd_conn *conn);
>> -int smb2_check_durable_oplock(struct ksmbd_file *fp,
>> -                             struct lease_ctx_info *lctx, char *name);
>>  #endif /* __KSMBD_OPLOCK_H */
>> diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c
>> index 3bf6c56c654c..e38fb68ded21 100644
>> --- a/fs/ksmbd/smb2pdu.c
>> +++ b/fs/ksmbd/smb2pdu.c
>> @@ -2918,7 +2918,6 @@ int smb2_open(struct ksmbd_work *work)
>>                 goto err_out;
>>         }
>>
>> -       fp->filename = name;
>>         fp->cdoption = req->CreateDisposition;
>>         fp->daccess = daccess;
>>         fp->saccess = req->ShareAccess;
>> @@ -3270,14 +3269,13 @@ int smb2_open(struct ksmbd_work *work)
>>                 if (!rsp->hdr.Status)
>>                         rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR;
>>
>> -               if (!fp || !fp->filename)
>> -                       kfree(name);
>>                 if (fp)
>>                         ksmbd_fd_put(work, fp);
>>                 smb2_set_err_rsp(work);
>>                 ksmbd_debug(SMB, "Error response: %x\n",
>> rsp->hdr.Status);
>>         }
>>
>> +       kfree(name);
>>         kfree(lc);
>>
>>         return 0;
>> @@ -3895,8 +3893,6 @@ int smb2_query_dir(struct ksmbd_work *work)
>>                 ksmbd_debug(SMB, "Search pattern is %s\n", srch_ptr);
>>         }
>>
>> -       ksmbd_debug(SMB, "Directory name is %s\n", dir_fp->filename);
>> -
>>         if (srch_flag & SMB2_REOPEN || srch_flag & SMB2_RESTART_SCANS) {
>>                 ksmbd_debug(SMB, "Restart directory scan\n");
>>                 generic_file_llseek(dir_fp->filp, 0, SEEK_SET);
>> @@ -4390,9 +4386,9 @@ static int get_file_all_info(struct ksmbd_work
>> *work,
>>                 return -EACCES;
>>         }
>>
>> -       filename = convert_to_nt_pathname(fp->filename);
>> -       if (!filename)
>> -               return -ENOMEM;
>> +       filename = convert_to_nt_pathname(work->tcon->share_conf,
>> &fp->filp->f_path);
>> +       if (IS_ERR(filename))
>> +               return PTR_ERR(filename);
>>
>>         inode = file_inode(fp->filp);
>>         generic_fillattr(file_mnt_user_ns(fp->filp), inode, &stat);
>> @@ -5683,8 +5679,7 @@ static int set_file_allocation_info(struct
>> ksmbd_work *work,
>>                 size = i_size_read(inode);
>>                 rc = ksmbd_vfs_truncate(work, fp, alloc_blks * 512);
>>                 if (rc) {
>> -                       pr_err("truncate failed! filename : %s, err
>> %d\n",
>> -                              fp->filename, rc);
>> +                       pr_err("truncate failed!, err %d\n", rc);
>>                         return rc;
>>                 }
>>                 if (size < alloc_blks * 512)
>> @@ -5714,12 +5709,10 @@ static int set_end_of_file_info(struct ksmbd_work
>> *work, struct ksmbd_file *fp,
>>          * truncated range.
>>          */
>>         if (inode->i_sb->s_magic != MSDOS_SUPER_MAGIC) {
>> -               ksmbd_debug(SMB, "filename : %s truncated to newsize
>> %lld\n",
>> -                           fp->filename, newsize);
>> +               ksmbd_debug(SMB, "truncated to newsize %lld\n", newsize);
>>                 rc = ksmbd_vfs_truncate(work, fp, newsize);
>>                 if (rc) {
>> -                       ksmbd_debug(SMB, "truncate failed! filename : %s
>> err %d\n",
>> -                                   fp->filename, rc);
>> +                       ksmbd_debug(SMB, "truncate failed!, err %d\n",
>> rc);
>>                         if (rc != -EAGAIN)
>>                                 rc = -EBADF;
>>                         return rc;
>> diff --git a/fs/ksmbd/vfs.c b/fs/ksmbd/vfs.c
>> index 9cebb6ba555b..dcdd07c6efff 100644
>> --- a/fs/ksmbd/vfs.c
>> +++ b/fs/ksmbd/vfs.c
>> @@ -398,8 +398,7 @@ int ksmbd_vfs_read(struct ksmbd_work *work, struct
>> ksmbd_file *fp, size_t count,
>>
>>         nbytes = kernel_read(filp, rbuf, count, pos);
>>         if (nbytes < 0) {
>> -               pr_err("smb read failed for (%s), err = %zd\n",
>> -                      fp->filename, nbytes);
>> +               pr_err("smb read failed, err = %zd\n", nbytes);
>>                 return nbytes;
>>         }
>>
>> @@ -875,8 +874,7 @@ int ksmbd_vfs_truncate(struct ksmbd_work *work,
>>
>>         err = vfs_truncate(&filp->f_path, size);
>>         if (err)
>> -               pr_err("truncate failed for filename : %s err %d\n",
>> -                      fp->filename, err);
>> +               pr_err("truncate failed, err %d\n", err);
>>         return err;
>>  }
>>
>> diff --git a/fs/ksmbd/vfs_cache.c b/fs/ksmbd/vfs_cache.c
>> index 29c1db66bd0f..0974d2e972b9 100644
>> --- a/fs/ksmbd/vfs_cache.c
>> +++ b/fs/ksmbd/vfs_cache.c
>> @@ -328,7 +328,6 @@ static void __ksmbd_close_fd(struct ksmbd_file_table
>> *ft, struct ksmbd_file *fp)
>>                 kfree(smb_lock);
>>         }
>>
>> -       kfree(fp->filename);
>>         if (ksmbd_stream_fd(fp))
>>                 kfree(fp->stream.name);
>>         kmem_cache_free(filp_cache, fp);
>> diff --git a/fs/ksmbd/vfs_cache.h b/fs/ksmbd/vfs_cache.h
>> index 36239ce31afd..fcb13413fa8d 100644
>> --- a/fs/ksmbd/vfs_cache.h
>> +++ b/fs/ksmbd/vfs_cache.h
>> @@ -62,7 +62,6 @@ struct ksmbd_inode {
>>
>>  struct ksmbd_file {
>>         struct file                     *filp;
>> -       char                            *filename;
>>         u64                             persistent_id;
>>         u64                             volatile_id;
>>
>> --
>> 2.25.1
>>
>
>
> --
> Thanks,
> Hyunchul
>
diff mbox series

Patch

diff --git a/fs/ksmbd/misc.c b/fs/ksmbd/misc.c
index 60e7ac62c917..20d4455a0a99 100644
--- a/fs/ksmbd/misc.c
+++ b/fs/ksmbd/misc.c
@@ -158,19 +158,41 @@  int parse_stream_name(char *filename, char **stream_name, int *s_type)
  * Return : windows path string or error
  */
 
-char *convert_to_nt_pathname(char *filename)
+char *convert_to_nt_pathname(struct ksmbd_share_config *share,
+			     struct path *path)
 {
-	char *ab_pathname;
+	char *pathname, *ab_pathname, *nt_pathname;
+	int share_path_len = strlen(share->path);
 
-	if (strlen(filename) == 0)
-		filename = "\\";
+	pathname = kmalloc(PATH_MAX, GFP_KERNEL);
+	if (!pathname)
+		return ERR_PTR(-EACCES);
 
-	ab_pathname = kstrdup(filename, GFP_KERNEL);
-	if (!ab_pathname)
-		return NULL;
+	ab_pathname = d_path(path, pathname, PATH_MAX);
+	if (IS_ERR(ab_pathname)) {
+		nt_pathname = ERR_PTR(-EACCES);
+		goto free_pathname;
+	}
+
+	if (strncmp(ab_pathname, share->path, share_path_len)) {
+		nt_pathname = ERR_PTR(-EACCES);
+		goto free_pathname;
+	}
+
+	nt_pathname = kzalloc(strlen(&ab_pathname[share_path_len]) + 1, GFP_KERNEL);
+	if (!nt_pathname) {
+		nt_pathname = ERR_PTR(-ENOMEM);
+		goto free_pathname;
+	}
+	if (ab_pathname[share_path_len] == '\0')
+		strcpy(nt_pathname, "/");
+	strcat(nt_pathname, &ab_pathname[share_path_len]);
+
+	ksmbd_conv_path_to_windows(nt_pathname);
 
-	ksmbd_conv_path_to_windows(ab_pathname);
-	return ab_pathname;
+free_pathname:
+	kfree(pathname);
+	return nt_pathname;
 }
 
 int get_nlink(struct kstat *st)
diff --git a/fs/ksmbd/misc.h b/fs/ksmbd/misc.h
index 253366bd0951..aae2a252945f 100644
--- a/fs/ksmbd/misc.h
+++ b/fs/ksmbd/misc.h
@@ -14,7 +14,8 @@  struct ksmbd_file;
 int match_pattern(const char *str, size_t len, const char *pattern);
 int ksmbd_validate_filename(char *filename);
 int parse_stream_name(char *filename, char **stream_name, int *s_type);
-char *convert_to_nt_pathname(char *filename);
+char *convert_to_nt_pathname(struct ksmbd_share_config *share,
+			     struct path *path);
 int get_nlink(struct kstat *st);
 void ksmbd_conv_path_to_unix(char *path);
 void ksmbd_strip_last_slash(char *path);
diff --git a/fs/ksmbd/oplock.c b/fs/ksmbd/oplock.c
index 23871b18a429..8b5560574d4c 100644
--- a/fs/ksmbd/oplock.c
+++ b/fs/ksmbd/oplock.c
@@ -1694,33 +1694,3 @@  struct oplock_info *lookup_lease_in_table(struct ksmbd_conn *conn,
 	read_unlock(&lease_list_lock);
 	return ret_op;
 }
-
-int smb2_check_durable_oplock(struct ksmbd_file *fp,
-			      struct lease_ctx_info *lctx, char *name)
-{
-	struct oplock_info *opinfo = opinfo_get(fp);
-	int ret = 0;
-
-	if (opinfo && opinfo->is_lease) {
-		if (!lctx) {
-			pr_err("open does not include lease\n");
-			ret = -EBADF;
-			goto out;
-		}
-		if (memcmp(opinfo->o_lease->lease_key, lctx->lease_key,
-			   SMB2_LEASE_KEY_SIZE)) {
-			pr_err("invalid lease key\n");
-			ret = -EBADF;
-			goto out;
-		}
-		if (name && strcmp(fp->filename, name)) {
-			pr_err("invalid name reconnect %s\n", name);
-			ret = -EINVAL;
-			goto out;
-		}
-	}
-out:
-	if (opinfo)
-		opinfo_put(opinfo);
-	return ret;
-}
diff --git a/fs/ksmbd/oplock.h b/fs/ksmbd/oplock.h
index 0cf7a2b5bbc0..09753448f779 100644
--- a/fs/ksmbd/oplock.h
+++ b/fs/ksmbd/oplock.h
@@ -124,6 +124,4 @@  struct oplock_info *lookup_lease_in_table(struct ksmbd_conn *conn,
 int find_same_lease_key(struct ksmbd_session *sess, struct ksmbd_inode *ci,
 			struct lease_ctx_info *lctx);
 void destroy_lease_table(struct ksmbd_conn *conn);
-int smb2_check_durable_oplock(struct ksmbd_file *fp,
-			      struct lease_ctx_info *lctx, char *name);
 #endif /* __KSMBD_OPLOCK_H */
diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c
index 3bf6c56c654c..e38fb68ded21 100644
--- a/fs/ksmbd/smb2pdu.c
+++ b/fs/ksmbd/smb2pdu.c
@@ -2918,7 +2918,6 @@  int smb2_open(struct ksmbd_work *work)
 		goto err_out;
 	}
 
-	fp->filename = name;
 	fp->cdoption = req->CreateDisposition;
 	fp->daccess = daccess;
 	fp->saccess = req->ShareAccess;
@@ -3270,14 +3269,13 @@  int smb2_open(struct ksmbd_work *work)
 		if (!rsp->hdr.Status)
 			rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR;
 
-		if (!fp || !fp->filename)
-			kfree(name);
 		if (fp)
 			ksmbd_fd_put(work, fp);
 		smb2_set_err_rsp(work);
 		ksmbd_debug(SMB, "Error response: %x\n", rsp->hdr.Status);
 	}
 
+	kfree(name);
 	kfree(lc);
 
 	return 0;
@@ -3895,8 +3893,6 @@  int smb2_query_dir(struct ksmbd_work *work)
 		ksmbd_debug(SMB, "Search pattern is %s\n", srch_ptr);
 	}
 
-	ksmbd_debug(SMB, "Directory name is %s\n", dir_fp->filename);
-
 	if (srch_flag & SMB2_REOPEN || srch_flag & SMB2_RESTART_SCANS) {
 		ksmbd_debug(SMB, "Restart directory scan\n");
 		generic_file_llseek(dir_fp->filp, 0, SEEK_SET);
@@ -4390,9 +4386,9 @@  static int get_file_all_info(struct ksmbd_work *work,
 		return -EACCES;
 	}
 
-	filename = convert_to_nt_pathname(fp->filename);
-	if (!filename)
-		return -ENOMEM;
+	filename = convert_to_nt_pathname(work->tcon->share_conf, &fp->filp->f_path);
+	if (IS_ERR(filename))
+		return PTR_ERR(filename);
 
 	inode = file_inode(fp->filp);
 	generic_fillattr(file_mnt_user_ns(fp->filp), inode, &stat);
@@ -5683,8 +5679,7 @@  static int set_file_allocation_info(struct ksmbd_work *work,
 		size = i_size_read(inode);
 		rc = ksmbd_vfs_truncate(work, fp, alloc_blks * 512);
 		if (rc) {
-			pr_err("truncate failed! filename : %s, err %d\n",
-			       fp->filename, rc);
+			pr_err("truncate failed!, err %d\n", rc);
 			return rc;
 		}
 		if (size < alloc_blks * 512)
@@ -5714,12 +5709,10 @@  static int set_end_of_file_info(struct ksmbd_work *work, struct ksmbd_file *fp,
 	 * truncated range.
 	 */
 	if (inode->i_sb->s_magic != MSDOS_SUPER_MAGIC) {
-		ksmbd_debug(SMB, "filename : %s truncated to newsize %lld\n",
-			    fp->filename, newsize);
+		ksmbd_debug(SMB, "truncated to newsize %lld\n", newsize);
 		rc = ksmbd_vfs_truncate(work, fp, newsize);
 		if (rc) {
-			ksmbd_debug(SMB, "truncate failed! filename : %s err %d\n",
-				    fp->filename, rc);
+			ksmbd_debug(SMB, "truncate failed!, err %d\n", rc);
 			if (rc != -EAGAIN)
 				rc = -EBADF;
 			return rc;
diff --git a/fs/ksmbd/vfs.c b/fs/ksmbd/vfs.c
index 9cebb6ba555b..dcdd07c6efff 100644
--- a/fs/ksmbd/vfs.c
+++ b/fs/ksmbd/vfs.c
@@ -398,8 +398,7 @@  int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, size_t count,
 
 	nbytes = kernel_read(filp, rbuf, count, pos);
 	if (nbytes < 0) {
-		pr_err("smb read failed for (%s), err = %zd\n",
-		       fp->filename, nbytes);
+		pr_err("smb read failed, err = %zd\n", nbytes);
 		return nbytes;
 	}
 
@@ -875,8 +874,7 @@  int ksmbd_vfs_truncate(struct ksmbd_work *work,
 
 	err = vfs_truncate(&filp->f_path, size);
 	if (err)
-		pr_err("truncate failed for filename : %s err %d\n",
-		       fp->filename, err);
+		pr_err("truncate failed, err %d\n", err);
 	return err;
 }
 
diff --git a/fs/ksmbd/vfs_cache.c b/fs/ksmbd/vfs_cache.c
index 29c1db66bd0f..0974d2e972b9 100644
--- a/fs/ksmbd/vfs_cache.c
+++ b/fs/ksmbd/vfs_cache.c
@@ -328,7 +328,6 @@  static void __ksmbd_close_fd(struct ksmbd_file_table *ft, struct ksmbd_file *fp)
 		kfree(smb_lock);
 	}
 
-	kfree(fp->filename);
 	if (ksmbd_stream_fd(fp))
 		kfree(fp->stream.name);
 	kmem_cache_free(filp_cache, fp);
diff --git a/fs/ksmbd/vfs_cache.h b/fs/ksmbd/vfs_cache.h
index 36239ce31afd..fcb13413fa8d 100644
--- a/fs/ksmbd/vfs_cache.h
+++ b/fs/ksmbd/vfs_cache.h
@@ -62,7 +62,6 @@  struct ksmbd_inode {
 
 struct ksmbd_file {
 	struct file			*filp;
-	char				*filename;
 	u64				persistent_id;
 	u64				volatile_id;