From patchwork Sun Mar 6 01:10:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namjae Jeon X-Patchwork-Id: 12770515 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5896FC433EF for ; Sun, 6 Mar 2022 01:10:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232170AbiCFBLs (ORCPT ); Sat, 5 Mar 2022 20:11:48 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37776 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230025AbiCFBLr (ORCPT ); Sat, 5 Mar 2022 20:11:47 -0500 Received: from mail-pl1-f175.google.com (mail-pl1-f175.google.com [209.85.214.175]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 61C8535DCC; Sat, 5 Mar 2022 17:10:56 -0800 (PST) Received: by mail-pl1-f175.google.com with SMTP id e13so10897022plh.3; Sat, 05 Mar 2022 17:10:56 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=hP0S734wwC7pJwjk7blXilh0iBBGpOed5Zt7sWmFDBc=; b=8BjM8tBotYzlBRq5fS17+PMjBbCtlvQUMDCydjz5nVZ4YRLGTXUxzhOx2qu0QILA8f s1gHZzJpKwopxa7LXowZCO03ZLP1sPQZFjCJo/9J1Rr2jIuDCTN1jcqIz9Gzu2TepPgW QiVblafcxTm3ME5QEZe51agUljSzvZk8xdbEuWdZU7HSD/8ACgSgjiWSqhXDLtmlcgus fXaCKc8px1deV0D3Il/2/fXmJ5hcgbQY+pJGMSi7kz6oDn/prv40Ra6OFzYNDbToSejf t8d7zfvaFi2omGlXzb4kdchJw/aTYHWzxlZEHL5N2LPKgXT43TZs2sQuStb9itGxK5d+ Hr1g== X-Gm-Message-State: AOAM530wdfhBd/bS2zOQcmbxGAtyBPBRZ351Kq+dRDeWEES/gTVS7Fzn dOClPZx0akV+1E7yonLdzjbapR8PgdM= X-Google-Smtp-Source: ABdhPJw/BbHe5c5KXzInOg/T8oKGoHflYa7mAUS0UN1ErXaLf37QSc0SvlefrsVUZjoU74jkuGJy2Q== X-Received: by 2002:a17:902:aa8e:b0:14f:fa5e:fe80 with SMTP id d14-20020a170902aa8e00b0014ffa5efe80mr6011236plr.84.1646529055480; Sat, 05 Mar 2022 17:10:55 -0800 (PST) Received: from localhost.localdomain ([61.74.27.164]) by smtp.gmail.com with ESMTPSA id d2-20020a056a0024c200b004f6b6817549sm7668110pfv.173.2022.03.05.17.10.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 05 Mar 2022 17:10:55 -0800 (PST) From: Namjae Jeon To: linux-cifs@vger.kernel.org, linux-fsdevel@vger.kernel.org Cc: smfrench@gmail.com, hyc.lee@gmail.com, senozhatsky@chromium.org, Namjae Jeon , Al Viro Subject: [PATCH 1/4] ksmbd: remove internal.h include Date: Sun, 6 Mar 2022 10:10:42 +0900 Message-Id: <20220306011045.13014-1-linkinjeon@kernel.org> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Since vfs_path_lookup is exported, It should not be internal. Move vfs_path_lookup prototype in internal.h to linux/namei.h. Suggested-by: Al Viro Signed-off-by: Namjae Jeon --- fs/internal.h | 2 -- fs/ksmbd/vfs.c | 2 -- include/linux/namei.h | 2 ++ 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/fs/internal.h b/fs/internal.h index 8590c973c2f4..deee2367df44 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -58,8 +58,6 @@ extern int finish_clean_context(struct fs_context *fc); */ extern int filename_lookup(int dfd, struct filename *name, unsigned flags, struct path *path, struct path *root); -extern int vfs_path_lookup(struct dentry *, struct vfsmount *, - const char *, unsigned int, struct path *); int do_rmdir(int dfd, struct filename *name); int do_unlinkat(int dfd, struct filename *name); int may_linkat(struct user_namespace *mnt_userns, struct path *link); diff --git a/fs/ksmbd/vfs.c b/fs/ksmbd/vfs.c index 19d36393974c..a1ab0aaceba5 100644 --- a/fs/ksmbd/vfs.c +++ b/fs/ksmbd/vfs.c @@ -19,8 +19,6 @@ #include #include -#include "../internal.h" /* for vfs_path_lookup */ - #include "glob.h" #include "oplock.h" #include "connection.h" diff --git a/include/linux/namei.h b/include/linux/namei.h index e89329bb3134..4858c3cdf7c6 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h @@ -63,6 +63,8 @@ extern struct dentry *kern_path_create(int, const char *, struct path *, unsigne extern struct dentry *user_path_create(int, const char __user *, struct path *, unsigned int); extern void done_path_create(struct path *, struct dentry *); extern struct dentry *kern_path_locked(const char *, struct path *); +int vfs_path_lookup(struct dentry *, struct vfsmount *, const char *, + unsigned int, struct path *); extern struct dentry *try_lookup_one_len(const char *, struct dentry *, int); extern struct dentry *lookup_one_len(const char *, struct dentry *, int); From patchwork Sun Mar 6 01:10:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namjae Jeon X-Patchwork-Id: 12770516 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2C853C433FE for ; Sun, 6 Mar 2022 01:11:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231703AbiCFBLv (ORCPT ); Sat, 5 Mar 2022 20:11:51 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37796 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230025AbiCFBLu (ORCPT ); Sat, 5 Mar 2022 20:11:50 -0500 Received: from mail-pj1-f47.google.com (mail-pj1-f47.google.com [209.85.216.47]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A7E0435DCD; Sat, 5 Mar 2022 17:10:59 -0800 (PST) Received: by mail-pj1-f47.google.com with SMTP id 15-20020a17090a098f00b001bef0376d5cso11120666pjo.5; Sat, 05 Mar 2022 17:10:59 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=pDp9KIidbDutFqdrytURsuZNhhsxtwT8hJXfFhz+dhc=; b=SuCWAP1kK8VRhkC5z5gep3UyPFIC73v5AsJkR4e5XxwzSojhnlfvT2ARZtf++OENXy nRpLDAkSUJ9lMhebUVlAI21IAuAxPOzWpFf8ngVlbEwZNyLa8XImQxLVhs285oAMANlI u/NPpYiwbCPckC1kE9F7PK7tiPkWvxXstOkhzHW4d9cmv8qgg0/adIauqcDVPpV7XpMu nsyvUC3IpnEx/vB8xt+wOKIgjtuMx+QpUNkRGNh0CU9+70//AHULYkigIc/WW+Kv2Uil Iariikov2EQIB2disl7GdAh7K0wSWIuHEuqlXYdL1466r4zYC/b2fh23J8v9BmYYqm1c y/Qw== X-Gm-Message-State: AOAM531FDEu27Wp+0N3KULgy2NPYSpKrE9mBV8qgmmxx/n5RtqMdkLkT fje9Q0QIRGbBS63HON8mdXD+kqeY4uU= X-Google-Smtp-Source: ABdhPJyZzvy2o5M0PAx21K9gU2Ucqw0MTs95q7fV2fj4cG0O9mXG8R4AjuHcU/G2xNqS9DmZE6JINg== X-Received: by 2002:a17:90b:4f8d:b0:1bf:a53:48dd with SMTP id qe13-20020a17090b4f8d00b001bf0a5348ddmr17158456pjb.89.1646529058739; Sat, 05 Mar 2022 17:10:58 -0800 (PST) Received: from localhost.localdomain ([61.74.27.164]) by smtp.gmail.com with ESMTPSA id d2-20020a056a0024c200b004f6b6817549sm7668110pfv.173.2022.03.05.17.10.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 05 Mar 2022 17:10:58 -0800 (PST) From: Namjae Jeon To: linux-cifs@vger.kernel.org, linux-fsdevel@vger.kernel.org Cc: smfrench@gmail.com, hyc.lee@gmail.com, senozhatsky@chromium.org, Namjae Jeon , Al Viro Subject: [PATCH v2 2/4] ksmbd: remove filename in ksmbd_file Date: Sun, 6 Mar 2022 10:10:43 +0900 Message-Id: <20220306011045.13014-2-linkinjeon@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220306011045.13014-1-linkinjeon@kernel.org> References: <20220306011045.13014-1-linkinjeon@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.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(). Cc: Al Viro Signed-off-by: Namjae Jeon --- v2: - remove unnecessary initialization of nt_pathname. 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); - 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 077b8761d099..5db5cba67d62 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 67e8e28e3fc3..3151ab7d7410 100644 --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -2922,7 +2922,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; @@ -3274,14 +3273,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; @@ -3901,8 +3899,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); @@ -4396,9 +4392,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); @@ -5689,8 +5685,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) @@ -5720,12 +5715,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 a1ab0aaceba5..487617f729ec 100644 --- a/fs/ksmbd/vfs.c +++ b/fs/ksmbd/vfs.c @@ -397,8 +397,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; } @@ -874,8 +873,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; From patchwork Sun Mar 6 01:10:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namjae Jeon X-Patchwork-Id: 12770517 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9E537C433EF for ; Sun, 6 Mar 2022 01:11:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232218AbiCFBLz (ORCPT ); Sat, 5 Mar 2022 20:11:55 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37838 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232200AbiCFBLy (ORCPT ); Sat, 5 Mar 2022 20:11:54 -0500 Received: from mail-pj1-f49.google.com (mail-pj1-f49.google.com [209.85.216.49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0AF7835DDB; Sat, 5 Mar 2022 17:11:03 -0800 (PST) Received: by mail-pj1-f49.google.com with SMTP id b8so10299491pjb.4; Sat, 05 Mar 2022 17:11:03 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=z5VAtpWyJhIa1cE2gPZTnGlgjaKGfrsIbKG71K6xJ2E=; b=515dPU1bSsWGNpVlebhUQXXpQ7kQXJryUzGUU9i0skBAmdiKk2VQr2vcPiclJCt9qd 1s3Mb1CjHdOAgV4xcZvlvzdHXlQgv85tkSR80PJi+B42y5I5zuWFwUHOVvmDZRs9zNRt dXK9i86qCeKGbdOBu+ovRdToLBklu06Hw7hvPxVRedIuXTCCjuEJH4IFJMHTpX7rkbp8 k4kc55sNQOp/eRC2WiALgCU2cOLqBry2CEKNL9X9XLCWFYV0SpaABAH14q+qjGd85/q8 slxJUZVugkpJsrEDXBikp2nNgZMXdt8vVOi/hHfQQmERPFQ+bbsY4V1mqSufaCrA6Dgm OiXg== X-Gm-Message-State: AOAM532/h4vV85jKn2qYuW0o+l7nAZ79qOkiZx7ncUQAHcF/cfPjUylY rqZw/cVmNoWQmJ+jG3IXvNv4y+v8Btg= X-Google-Smtp-Source: ABdhPJxzac8DowXP2s8zXp/f7dDK680uQHgTgZSUUchWb5c8fPNu5A/B768Uwf/+s9QDYRhdacicPg== X-Received: by 2002:a17:90b:3ec7:b0:1bf:457e:c281 with SMTP id rm7-20020a17090b3ec700b001bf457ec281mr3578717pjb.145.1646529061833; Sat, 05 Mar 2022 17:11:01 -0800 (PST) Received: from localhost.localdomain ([61.74.27.164]) by smtp.gmail.com with ESMTPSA id d2-20020a056a0024c200b004f6b6817549sm7668110pfv.173.2022.03.05.17.10.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 05 Mar 2022 17:11:01 -0800 (PST) From: Namjae Jeon To: linux-cifs@vger.kernel.org, linux-fsdevel@vger.kernel.org Cc: smfrench@gmail.com, hyc.lee@gmail.com, senozhatsky@chromium.org, Namjae Jeon , Al Viro Subject: [PATCH v4 3/4] ksmbd: fix racy issue from using ->d_parent and ->d_name Date: Sun, 6 Mar 2022 10:10:44 +0900 Message-Id: <20220306011045.13014-3-linkinjeon@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220306011045.13014-1-linkinjeon@kernel.org> References: <20220306011045.13014-1-linkinjeon@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Al pointed out that ksmbd has racy issue from using ->d_parent and ->d_name in ksmbd_vfs_unlink and smb2_vfs_rename(). add dget_parent() in ksmbd_vfs_unlink() and use take_dentry_name_snapshot() to verify underlying rename for lookup. Introduce vfs_path_parent_lookup helper to avoid out of share access and export vfs functions like the following ones to use vfs_path_parent_lookup(). - __lookup_hash(). - getname_kernel() and putname(). vfs_path_parent_lookup() is used for parent lookup of destination file using absolute pathname given from FILE_RENAME_INFORMATION request. Cc: Al Viro Signed-off-by: Namjae Jeon --- v4: - switch the order of 3/4 and 4/4 patch. - fix vfs_path_parent_lookup() parameter description mismatch. v3: - use dget_parent + take_dentry_name_snapshot() to check stability of source rename in smb2_vfs_rename(). - change to struct path *root argument from two argument of dentry and mnt. - check if old and new file are on same filesystem. - add retry_estale() check and retry. v2: - add filename_lock to avoid racy issue from fp->filename. (Sergey Senozhatsky) - fix warning: variable 'old_dentry' is used uninitialized (kernel test robot) fs/ksmbd/smb2pdu.c | 103 ++--------------- fs/ksmbd/vfs.c | 251 +++++++++++++++++++----------------------- fs/ksmbd/vfs.h | 7 +- fs/ksmbd/vfs_cache.c | 5 +- fs/namei.c | 40 ++++++- include/linux/namei.h | 4 + 6 files changed, 164 insertions(+), 246 deletions(-) diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c index 3151ab7d7410..bcb98109bac9 100644 --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -5365,44 +5365,19 @@ int smb2_echo(struct ksmbd_work *work) static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp, - struct user_namespace *user_ns, struct smb2_file_rename_info *file_info, struct nls_table *local_nls) { struct ksmbd_share_config *share = fp->tcon->share_conf; - char *new_name = NULL, *abs_oldname = NULL, *old_name = NULL; - char *pathname = NULL; - struct path path; - bool file_present = true; - int rc; + char *new_name = NULL; + int rc, flags = 0; ksmbd_debug(SMB, "setting FILE_RENAME_INFO\n"); - pathname = kmalloc(PATH_MAX, GFP_KERNEL); - if (!pathname) - return -ENOMEM; - - abs_oldname = d_path(&fp->filp->f_path, pathname, PATH_MAX); - if (IS_ERR(abs_oldname)) { - rc = -EINVAL; - goto out; - } - old_name = strrchr(abs_oldname, '/'); - if (old_name && old_name[1] != '\0') { - old_name++; - } else { - ksmbd_debug(SMB, "can't get last component in path %s\n", - abs_oldname); - rc = -ENOENT; - goto out; - } - new_name = smb2_get_name(file_info->FileName, le32_to_cpu(file_info->FileNameLength), local_nls); - if (IS_ERR(new_name)) { - rc = PTR_ERR(new_name); - goto out; - } + if (IS_ERR(new_name)) + return PTR_ERR(new_name); if (strchr(new_name, ':')) { int s_type; @@ -5428,7 +5403,7 @@ static int smb2_rename(struct ksmbd_work *work, if (rc) goto out; - rc = ksmbd_vfs_setxattr(user_ns, + rc = ksmbd_vfs_setxattr(file_mnt_user_ns(fp->filp), fp->filp->f_path.dentry, xattr_stream_name, NULL, 0, 0); @@ -5443,47 +5418,18 @@ static int smb2_rename(struct ksmbd_work *work, } ksmbd_debug(SMB, "new name %s\n", new_name); - rc = ksmbd_vfs_kern_path(work, new_name, LOOKUP_NO_SYMLINKS, &path, 1); - if (rc) { - if (rc != -ENOENT) - goto out; - file_present = false; - } else { - path_put(&path); - } - if (ksmbd_share_veto_filename(share, new_name)) { rc = -ENOENT; ksmbd_debug(SMB, "Can't rename vetoed file: %s\n", new_name); goto out; } - if (file_info->ReplaceIfExists) { - if (file_present) { - rc = ksmbd_vfs_remove_file(work, new_name); - if (rc) { - if (rc != -ENOTEMPTY) - rc = -EINVAL; - ksmbd_debug(SMB, "cannot delete %s, rc %d\n", - new_name, rc); - goto out; - } - } - } else { - if (file_present && - strncmp(old_name, path.dentry->d_name.name, strlen(old_name))) { - rc = -EEXIST; - ksmbd_debug(SMB, - "cannot rename already existing file\n"); - goto out; - } - } + if (!file_info->ReplaceIfExists) + flags = RENAME_NOREPLACE; - rc = ksmbd_vfs_fp_rename(work, fp, new_name); + rc = ksmbd_vfs_rename(work, &fp->filp->f_path, new_name, flags); out: - kfree(pathname); - if (!IS_ERR(new_name)) - kfree(new_name); + kfree(new_name); return rc; } @@ -5731,12 +5677,6 @@ static int set_rename_info(struct ksmbd_work *work, struct ksmbd_file *fp, struct smb2_file_rename_info *rename_info, unsigned int buf_len) { - struct user_namespace *user_ns; - struct ksmbd_file *parent_fp; - struct dentry *parent; - struct dentry *dentry = fp->filp->f_path.dentry; - int ret; - if (!(fp->daccess & FILE_DELETE_LE)) { pr_err("no right to delete : 0x%x\n", fp->daccess); return -EACCES; @@ -5746,30 +5686,7 @@ static int set_rename_info(struct ksmbd_work *work, struct ksmbd_file *fp, le32_to_cpu(rename_info->FileNameLength)) return -EINVAL; - user_ns = file_mnt_user_ns(fp->filp); - if (ksmbd_stream_fd(fp)) - goto next; - - parent = dget_parent(dentry); - ret = ksmbd_vfs_lock_parent(user_ns, parent, dentry); - if (ret) { - dput(parent); - return ret; - } - - parent_fp = ksmbd_lookup_fd_inode(d_inode(parent)); - inode_unlock(d_inode(parent)); - dput(parent); - - if (parent_fp) { - if (parent_fp->daccess & FILE_DELETE_LE) { - pr_err("parent dir is opened with delete access\n"); - return -ESHARE; - } - } -next: - return smb2_rename(work, fp, user_ns, rename_info, - work->sess->conn->local_nls); + return smb2_rename(work, fp, rename_info, work->sess->conn->local_nls); } static int set_file_disposition_info(struct ksmbd_file *fp, diff --git a/fs/ksmbd/vfs.c b/fs/ksmbd/vfs.c index 487617f729ec..f703dbfe22c0 100644 --- a/fs/ksmbd/vfs.c +++ b/fs/ksmbd/vfs.c @@ -35,19 +35,6 @@ #include "mgmt/user_session.h" #include "mgmt/user_config.h" -static char *extract_last_component(char *path) -{ - char *p = strrchr(path, '/'); - - if (p && p[1] != '\0') { - *p = '\0'; - p++; - } else { - p = NULL; - } - return p; -} - static void ksmbd_vfs_inherit_owner(struct ksmbd_work *work, struct inode *parent_inode, struct inode *inode) @@ -72,11 +59,14 @@ int ksmbd_vfs_lock_parent(struct user_namespace *user_ns, struct dentry *parent, struct dentry *child) { struct dentry *dentry; + struct name_snapshot name; int ret = 0; inode_lock_nested(d_inode(parent), I_MUTEX_PARENT); - dentry = lookup_one(user_ns, child->d_name.name, parent, - child->d_name.len); + take_dentry_name_snapshot(&name, child); + dentry = lookup_one(user_ns, name.name.name, parent, + name.name.len); + release_dentry_name_snapshot(&name); if (IS_ERR(dentry)) { ret = PTR_ERR(dentry); goto out_err; @@ -689,149 +679,128 @@ int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname, return err; } -static int ksmbd_validate_entry_in_use(struct dentry *src_dent) +int ksmbd_vfs_rename(struct ksmbd_work *work, struct path *old_path, + char *newname, int flags) { - struct dentry *dst_dent; - - spin_lock(&src_dent->d_lock); - list_for_each_entry(dst_dent, &src_dent->d_subdirs, d_child) { - struct ksmbd_file *child_fp; + struct dentry *old_parent, *old_dentry, *new_dentry, *trap; + struct dentry *old_child = old_path->dentry; + struct path new_path; + struct qstr new_last; + struct renamedata rd; + struct filename *to; + struct ksmbd_share_config *share_conf = work->tcon->share_conf; + struct ksmbd_file *parent_fp; + struct name_snapshot name; + int new_type; + int err, lookup_flags = LOOKUP_NO_SYMLINKS; - if (d_really_is_negative(dst_dent)) - continue; + if (ksmbd_override_fsids(work)) + return -ENOMEM; - child_fp = ksmbd_lookup_fd_inode(d_inode(dst_dent)); - if (child_fp) { - spin_unlock(&src_dent->d_lock); - ksmbd_debug(VFS, "Forbid rename, sub file/dir is in use\n"); - return -EACCES; - } + to = getname_kernel(newname); + if (IS_ERR(to)) { + err = PTR_ERR(to); + goto revert_fsids; } - spin_unlock(&src_dent->d_lock); - - return 0; -} -static int __ksmbd_vfs_rename(struct ksmbd_work *work, - struct user_namespace *src_user_ns, - struct dentry *src_dent_parent, - struct dentry *src_dent, - struct user_namespace *dst_user_ns, - struct dentry *dst_dent_parent, - struct dentry *trap_dent, - char *dst_name) -{ - struct dentry *dst_dent; - int err; + old_parent = dget_parent(old_child); +retry: + err = vfs_path_parent_lookup(to, lookup_flags | LOOKUP_BENEATH, + &new_path, &new_last, &new_type, + &share_conf->vfs_path); + if (err) + goto out1; - if (!work->tcon->posix_extensions) { - err = ksmbd_validate_entry_in_use(src_dent); - if (err) - return err; + if (d_is_symlink(new_path.dentry)) { + err = -EACCES; + goto out2; } - if (d_really_is_negative(src_dent_parent)) - return -ENOENT; - if (d_really_is_negative(dst_dent_parent)) - return -ENOENT; - if (d_really_is_negative(src_dent)) - return -ENOENT; - if (src_dent == trap_dent) - return -EINVAL; + if (old_path->mnt != new_path.mnt) { + err = -EXDEV; + goto out2; + } - if (ksmbd_override_fsids(work)) - return -ENOMEM; + trap = lock_rename(old_parent, new_path.dentry); + take_dentry_name_snapshot(&name, old_child); + old_dentry = lookup_one(mnt_user_ns(old_path->mnt), name.name.name, + old_parent, name.name.len); + release_dentry_name_snapshot(&name); + if (IS_ERR(old_dentry)) { + err = PTR_ERR(old_dentry); + goto out3; + } - dst_dent = lookup_one(dst_user_ns, dst_name, dst_dent_parent, - strlen(dst_name)); - err = PTR_ERR(dst_dent); - if (IS_ERR(dst_dent)) { - pr_err("lookup failed %s [%d]\n", dst_name, err); - goto out; + if (old_dentry != old_child) { + err = -ESTALE; + dput(old_dentry); + goto out4; } - err = -ENOTEMPTY; - if (dst_dent != trap_dent && !d_really_is_positive(dst_dent)) { - struct renamedata rd = { - .old_mnt_userns = src_user_ns, - .old_dir = d_inode(src_dent_parent), - .old_dentry = src_dent, - .new_mnt_userns = dst_user_ns, - .new_dir = d_inode(dst_dent_parent), - .new_dentry = dst_dent, - }; - err = vfs_rename(&rd); + new_dentry = __lookup_hash(&new_last, new_path.dentry, + lookup_flags | LOOKUP_RENAME_TARGET); + if (IS_ERR(new_dentry)) { + err = PTR_ERR(new_dentry); + goto out4; } - if (err) - pr_err("vfs_rename failed err %d\n", err); - if (dst_dent) - dput(dst_dent); -out: - ksmbd_revert_fsids(work); - return err; -} -int ksmbd_vfs_fp_rename(struct ksmbd_work *work, struct ksmbd_file *fp, - char *newname) -{ - struct user_namespace *user_ns; - struct path dst_path; - struct dentry *src_dent_parent, *dst_dent_parent; - struct dentry *src_dent, *trap_dent, *src_child; - char *dst_name; - int err; + if (d_is_symlink(new_dentry)) { + err = -EACCES; + goto out5; + } - dst_name = extract_last_component(newname); - if (!dst_name) { - dst_name = newname; - newname = ""; + if ((flags & RENAME_NOREPLACE) && d_is_positive(new_dentry)) { + err = -EEXIST; + goto out5; } - src_dent_parent = dget_parent(fp->filp->f_path.dentry); - src_dent = fp->filp->f_path.dentry; + if (old_dentry == trap) { + err = -EINVAL; + goto out5; + } - err = ksmbd_vfs_kern_path(work, newname, - LOOKUP_NO_SYMLINKS | LOOKUP_DIRECTORY, - &dst_path, false); - if (err) { - ksmbd_debug(VFS, "Cannot get path for %s [%d]\n", newname, err); - goto out; + if (new_dentry == trap) { + err = -ENOTEMPTY; + goto out5; } - dst_dent_parent = dst_path.dentry; - trap_dent = lock_rename(src_dent_parent, dst_dent_parent); - dget(src_dent); - dget(dst_dent_parent); - user_ns = file_mnt_user_ns(fp->filp); - src_child = lookup_one(user_ns, src_dent->d_name.name, src_dent_parent, - src_dent->d_name.len); - if (IS_ERR(src_child)) { - err = PTR_ERR(src_child); - goto out_lock; + parent_fp = ksmbd_lookup_fd_inode(old_parent->d_inode); + if (parent_fp) { + if (parent_fp->daccess & FILE_DELETE_LE) { + pr_err("parent dir is opened with delete access\n"); + err = -ESHARE; + goto out5; + } } - if (src_child != src_dent) { - err = -ESTALE; - dput(src_child); - goto out_lock; - } - dput(src_child); - - err = __ksmbd_vfs_rename(work, - user_ns, - src_dent_parent, - src_dent, - mnt_user_ns(dst_path.mnt), - dst_dent_parent, - trap_dent, - dst_name); -out_lock: - dput(src_dent); - dput(dst_dent_parent); - unlock_rename(src_dent_parent, dst_dent_parent); - path_put(&dst_path); -out: - dput(src_dent_parent); + rd.old_mnt_userns = mnt_user_ns(old_path->mnt), + rd.old_dir = old_parent->d_inode, + rd.old_dentry = old_dentry, + rd.new_mnt_userns = mnt_user_ns(new_path.mnt), + rd.new_dir = new_path.dentry->d_inode, + rd.new_dentry = new_dentry, + rd.flags = flags, + err = vfs_rename(&rd); + if (err) + ksmbd_debug(VFS, "vfs_rename failed err %d\n", err); +out5: + dput(new_dentry); +out4: + dput(old_dentry); +out3: + unlock_rename(old_parent, new_path.dentry); +out2: + path_put(&new_path); + + if (retry_estale(err, lookup_flags)) { + lookup_flags |= LOOKUP_REVAL; + goto retry; + } +out1: + putname(to); + dput(old_parent); +revert_fsids: + ksmbd_revert_fsids(work); return err; } @@ -1080,14 +1049,16 @@ int ksmbd_vfs_remove_xattr(struct user_namespace *user_ns, return vfs_removexattr(user_ns, dentry, attr_name); } -int ksmbd_vfs_unlink(struct user_namespace *user_ns, - struct dentry *dir, struct dentry *dentry) +int ksmbd_vfs_unlink(struct file *filp) { int err = 0; + struct dentry *dir, *dentry = filp->f_path.dentry; + struct user_namespace *user_ns = file_mnt_user_ns(filp); + dir = dget_parent(dentry); err = ksmbd_vfs_lock_parent(user_ns, dir, dentry); if (err) - return err; + goto out; dget(dentry); if (S_ISDIR(d_inode(dentry)->i_mode)) @@ -1099,6 +1070,8 @@ int ksmbd_vfs_unlink(struct user_namespace *user_ns, inode_unlock(d_inode(dir)); if (err) ksmbd_debug(VFS, "failed to delete, err %d\n", err); +out: + dput(dir); return err; } diff --git a/fs/ksmbd/vfs.h b/fs/ksmbd/vfs.h index 8c37aaf936ab..5b8070774aab 100644 --- a/fs/ksmbd/vfs.h +++ b/fs/ksmbd/vfs.h @@ -86,8 +86,8 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name); int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname, const char *newname); int ksmbd_vfs_getattr(struct path *path, struct kstat *stat); -int ksmbd_vfs_fp_rename(struct ksmbd_work *work, struct ksmbd_file *fp, - char *newname); +int ksmbd_vfs_rename(struct ksmbd_work *work, struct path *old_path, + char *newname, int flags); int ksmbd_vfs_truncate(struct ksmbd_work *work, struct ksmbd_file *fp, loff_t size); struct srv_copychunk; @@ -129,8 +129,7 @@ struct file_allocated_range_buffer; int ksmbd_vfs_fqar_lseek(struct ksmbd_file *fp, loff_t start, loff_t length, struct file_allocated_range_buffer *ranges, unsigned int in_count, unsigned int *out_count); -int ksmbd_vfs_unlink(struct user_namespace *user_ns, - struct dentry *dir, struct dentry *dentry); +int ksmbd_vfs_unlink(struct file *filp); void *ksmbd_vfs_init_kstat(char **p, struct ksmbd_kstat *ksmbd_kstat); int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work, struct user_namespace *user_ns, diff --git a/fs/ksmbd/vfs_cache.c b/fs/ksmbd/vfs_cache.c index 0974d2e972b9..ffb534281836 100644 --- a/fs/ksmbd/vfs_cache.c +++ b/fs/ksmbd/vfs_cache.c @@ -243,7 +243,6 @@ void ksmbd_release_inode_hash(void) static void __ksmbd_inode_close(struct ksmbd_file *fp) { - struct dentry *dir, *dentry; struct ksmbd_inode *ci = fp->f_ci; int err; struct file *filp; @@ -262,11 +261,9 @@ static void __ksmbd_inode_close(struct ksmbd_file *fp) if (atomic_dec_and_test(&ci->m_count)) { write_lock(&ci->m_lock); if (ci->m_flags & (S_DEL_ON_CLS | S_DEL_PENDING)) { - dentry = filp->f_path.dentry; - dir = dentry->d_parent; ci->m_flags &= ~(S_DEL_ON_CLS | S_DEL_PENDING); write_unlock(&ci->m_lock); - ksmbd_vfs_unlink(file_mnt_user_ns(filp), dir, dentry); + ksmbd_vfs_unlink(filp); write_lock(&ci->m_lock); } write_unlock(&ci->m_lock); diff --git a/fs/namei.c b/fs/namei.c index 3f1829b3ab5b..e7d3832e9b5e 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -252,6 +252,7 @@ getname_kernel(const char * filename) return result; } +EXPORT_SYMBOL(getname_kernel); void putname(struct filename *name) { @@ -269,6 +270,7 @@ void putname(struct filename *name) } else __putname(name); } +EXPORT_SYMBOL(putname); /** * check_acl - perform ACL permission checking @@ -1587,8 +1589,8 @@ static struct dentry *lookup_dcache(const struct qstr *name, * when directory is guaranteed to have no in-lookup children * at all. */ -static struct dentry *__lookup_hash(const struct qstr *name, - struct dentry *base, unsigned int flags) +struct dentry *__lookup_hash(const struct qstr *name, struct dentry *base, + unsigned int flags) { struct dentry *dentry = lookup_dcache(name, base, flags); struct dentry *old; @@ -1612,6 +1614,7 @@ static struct dentry *__lookup_hash(const struct qstr *name, } return dentry; } +EXPORT_SYMBOL(__lookup_hash); static struct dentry *lookup_fast(struct nameidata *nd, struct inode **inode, @@ -2556,16 +2559,17 @@ static int path_parentat(struct nameidata *nd, unsigned flags, } /* Note: this does not consume "name" */ -static int filename_parentat(int dfd, struct filename *name, - unsigned int flags, struct path *parent, - struct qstr *last, int *type) +static int __filename_parentat(int dfd, struct filename *name, + unsigned int flags, struct path *parent, + struct qstr *last, int *type, + const struct path *root) { int retval; struct nameidata nd; if (IS_ERR(name)) return PTR_ERR(name); - set_nameidata(&nd, dfd, name, NULL); + set_nameidata(&nd, dfd, name, root); retval = path_parentat(&nd, flags | LOOKUP_RCU, parent); if (unlikely(retval == -ECHILD)) retval = path_parentat(&nd, flags, parent); @@ -2580,6 +2584,12 @@ static int filename_parentat(int dfd, struct filename *name, return retval; } +int filename_parentat(int dfd, struct filename *name, unsigned int flags, + struct path *parent, struct qstr *last, int *type) +{ + return __filename_parentat(dfd, name, flags, parent, last, type, NULL); +} + /* does lookup, returns the object with parent locked */ static struct dentry *__kern_path_locked(struct filename *name, struct path *path) { @@ -2623,6 +2633,24 @@ int kern_path(const char *name, unsigned int flags, struct path *path) } EXPORT_SYMBOL(kern_path); +/** + * vfs_path_parent_lookup - lookup a parent path relative to a dentry-vfsmount pair + * @filename: filename structure + * @flags: lookup flags + * @parent: pointer to struct path to fill + * @last: last component + * @type: type of the last component + * @root: pointer to struct path of the base directory + */ +int vfs_path_parent_lookup(struct filename *filename, unsigned int flags, + struct path *parent, struct qstr *last, int *type, + const struct path *root) +{ + return __filename_parentat(AT_FDCWD, filename, flags, parent, last, + type, root); +} +EXPORT_SYMBOL(vfs_path_parent_lookup); + /** * vfs_path_lookup - lookup a file path relative to a dentry-vfsmount pair * @dentry: pointer to dentry of the base directory diff --git a/include/linux/namei.h b/include/linux/namei.h index 4858c3cdf7c6..439b2a6767ae 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h @@ -57,12 +57,16 @@ static inline int user_path_at(int dfd, const char __user *name, unsigned flags, return user_path_at_empty(dfd, name, flags, path, NULL); } +struct dentry *__lookup_hash(const struct qstr *name, struct dentry *base, + unsigned int flags); extern int kern_path(const char *, unsigned, struct path *); extern struct dentry *kern_path_create(int, const char *, struct path *, unsigned int); extern struct dentry *user_path_create(int, const char __user *, struct path *, unsigned int); extern void done_path_create(struct path *, struct dentry *); extern struct dentry *kern_path_locked(const char *, struct path *); +int vfs_path_parent_lookup(struct filename *, unsigned int, struct path *,\ + struct qstr *, int *, const struct path *); int vfs_path_lookup(struct dentry *, struct vfsmount *, const char *, unsigned int, struct path *); From patchwork Sun Mar 6 01:10:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namjae Jeon X-Patchwork-Id: 12770518 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 86DC1C433F5 for ; Sun, 6 Mar 2022 01:11:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232287AbiCFBMA (ORCPT ); Sat, 5 Mar 2022 20:12:00 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37870 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232224AbiCFBL4 (ORCPT ); Sat, 5 Mar 2022 20:11:56 -0500 Received: from mail-pj1-f49.google.com (mail-pj1-f49.google.com [209.85.216.49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9C27D35DE4; Sat, 5 Mar 2022 17:11:05 -0800 (PST) Received: by mail-pj1-f49.google.com with SMTP id m11-20020a17090a7f8b00b001beef6143a8so11121154pjl.4; Sat, 05 Mar 2022 17:11:05 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=S5U0EkgWVSJ79epU5pa7kyBPr31R0QM605pzAOhpRvE=; b=kTp4MkiF21FEVA8DQwWVqrIp2hUDl7np9csm/QGkJpVowbAmer3IPzy4Q0KPe+txzX R13qX+1UgWERxkwm6wNfc4W0UbMtNcCnOVSovTK8ihSeCO2/q7chtAOR8cuKCTP/jDQ5 O0OgLxMbtn3MjjOUO/0wW3PPRjzVnykB40bnng1tEregiKudZVM8Ry9/C2qhp5GcLPSa fVhNa6GREEpnhtvjCVHshT4Ibthr7va1I7QYyNDgfc1EGhbHDPzMZPywmiDLvnsWjAhW G4P7sBGxRvuVbsL69L1+jaWmrmVRvW4n4yZ+zOf4wbDfbJSqS3PpdWR3tbvSpd/yjkyc BXBw== X-Gm-Message-State: AOAM530N2Qq0Vjgesn7V5JMAWmqNHHuO0XtnMFr7tOovDwh6Gl4P8jl+ s6EtlIpGHUxQJ1RAMdNiGrJtw0zXiO8= X-Google-Smtp-Source: ABdhPJzKs4hnz3OSVnhemV0Sxq2dorrUTqvCkl7hmq20U7wCqA2nmAG1VZQsx9IKM9jrwyidGEY63Q== X-Received: by 2002:a17:903:244a:b0:151:36cc:2f71 with SMTP id l10-20020a170903244a00b0015136cc2f71mr5751110pls.115.1646529064903; Sat, 05 Mar 2022 17:11:04 -0800 (PST) Received: from localhost.localdomain ([61.74.27.164]) by smtp.gmail.com with ESMTPSA id d2-20020a056a0024c200b004f6b6817549sm7668110pfv.173.2022.03.05.17.11.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 05 Mar 2022 17:11:04 -0800 (PST) From: Namjae Jeon To: linux-cifs@vger.kernel.org, linux-fsdevel@vger.kernel.org Cc: smfrench@gmail.com, hyc.lee@gmail.com, senozhatsky@chromium.org, Namjae Jeon , Al Viro Subject: [PATCH v2 4/4] ksmbd: increment reference count of parent fp Date: Sun, 6 Mar 2022 10:10:45 +0900 Message-Id: <20220306011045.13014-4-linkinjeon@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220306011045.13014-1-linkinjeon@kernel.org> References: <20220306011045.13014-1-linkinjeon@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Add missing increment reference count of parent fp in ksmbd_lookup_fd_inode(). Cc: Al Viro Signed-off-by: Namjae Jeon --- v2: - switch the order of 3/4 and 4/4 patch. fs/ksmbd/vfs.c | 2 ++ fs/ksmbd/vfs_cache.c | 1 + 2 files changed, 3 insertions(+) diff --git a/fs/ksmbd/vfs.c b/fs/ksmbd/vfs.c index f703dbfe22c0..0b92092f3e8a 100644 --- a/fs/ksmbd/vfs.c +++ b/fs/ksmbd/vfs.c @@ -769,8 +769,10 @@ int ksmbd_vfs_rename(struct ksmbd_work *work, struct path *old_path, if (parent_fp->daccess & FILE_DELETE_LE) { pr_err("parent dir is opened with delete access\n"); err = -ESHARE; + ksmbd_fd_put(work, parent_fp); goto out5; } + ksmbd_fd_put(work, parent_fp); } rd.old_mnt_userns = mnt_user_ns(old_path->mnt), diff --git a/fs/ksmbd/vfs_cache.c b/fs/ksmbd/vfs_cache.c index ffb534281836..df600eb04552 100644 --- a/fs/ksmbd/vfs_cache.c +++ b/fs/ksmbd/vfs_cache.c @@ -493,6 +493,7 @@ struct ksmbd_file *ksmbd_lookup_fd_inode(struct inode *inode) list_for_each_entry(lfp, &ci->m_fp_list, node) { if (inode == file_inode(lfp->filp)) { atomic_dec(&ci->m_count); + lfp = ksmbd_fp_get(lfp); read_unlock(&ci->m_lock); return lfp; }