From fc111fb9a6da6baddf23930811210650824b8a88 Mon Sep 17 00:00:00 2001 From: Steve French Date: Wed, 8 Sep 2021 23:06:24 -0500 Subject: [PATCH 1/4] cifs: update FSCTL definitions Add some missing defines used by ksmbd to the client version of smbfsctl.h, and add a missing newer define mentioned in the protocol definitions (MS-FSCC). This will also make it easier to move to common code. Reviewed-by: Ronnie Sahlberg Signed-off-by: Steve French --- fs/cifs/smbfsctl.h | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/fs/cifs/smbfsctl.h b/fs/cifs/smbfsctl.h index d0fc42061f49..d01e8c9d7a31 100644 --- a/fs/cifs/smbfsctl.h +++ b/fs/cifs/smbfsctl.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: LGPL-2.1 */ +/* SPDX-License-Identifier: LGPL-2.1+ */ /* * fs/cifs/smbfsctl.h: SMB, CIFS, SMB2 FSCTL definitions * @@ -19,11 +19,14 @@ * could be invoked from tools via a specialized hook into the VFS rather * than via the standard vfs entry points * - * See MS-SMB2 Section 2.2.31 (last checked June 2013, all of that list are + * See MS-SMB2 Section 2.2.31 (last checked September 2021, all of that list are * below). Additional detail on less common ones can be found in MS-FSCC * section 2.3. */ +#ifndef __SMBFSCTL_H +#define __SMBFSCTL_H + /* * FSCTL values are 32 bits and are constructed as * @@ -91,6 +94,7 @@ #define FSCTL_SET_ZERO_ON_DEALLOC 0x00090194 /* BB add struct */ #define FSCTL_SET_SHORT_NAME_BEHAVIOR 0x000901B4 /* BB add struct */ #define FSCTL_GET_INTEGRITY_INFORMATION 0x0009027C +#define FSCTL_GET_REFS_VOLUME_DATA 0x000902D8 /* See MS-FSCC 2.3.24 */ #define FSCTL_GET_RETRIEVAL_POINTERS_AND_REFCOUNT 0x000903d3 #define FSCTL_GET_RETRIEVAL_POINTER_COUNT 0x0009042b #define FSCTL_QUERY_ALLOCATED_RANGES 0x000940CF @@ -146,7 +150,13 @@ #define IO_REPARSE_TAG_LX_CHR 0x80000025 #define IO_REPARSE_TAG_LX_BLK 0x80000026 +#define IO_REPARSE_TAG_LX_SYMLINK_LE cpu_to_le32(0xA000001D) +#define IO_REPARSE_TAG_AF_UNIX_LE cpu_to_le32(0x80000023) +#define IO_REPARSE_TAG_LX_FIFO_LE cpu_to_le32(0x80000024) +#define IO_REPARSE_TAG_LX_CHR_LE cpu_to_le32(0x80000025) +#define IO_REPARSE_TAG_LX_BLK_LE cpu_to_le32(0x80000026) + /* fsctl flags */ /* If Flags is set to this value, the request is an FSCTL not ioctl request */ #define SMB2_0_IOCTL_IS_FSCTL 0x00000001 - +#endif /* __SMBFSCTL_H */ From 23e91d8b7c5ae2bbd3a4582ec12c6a0cfcb19e85 Mon Sep 17 00:00:00 2001 From: Steve French Date: Wed, 8 Sep 2021 23:59:26 -0500 Subject: [PATCH 2/4] cifs: rename cifs_common to smbfs_common As we move to common code between client and server, we have been asked to make the names less confusing, and refer less to "cifs" and more to words which include "smb" instead to e.g. "smbfs" for the client (we already have "ksmbd" for the kernel server, and "smbd" for the user space Samba daemon). So to be more consistent in the naming of common code between client and server and reduce the risk of merge conflicts as more common code is added - rename "cifs_common" to "smbfs_common" (in future releases we also will rename the fs/cifs directory to fs/smbfs) Reviewed-by: Ronnie Sahlberg Signed-off-by: Steve French --- fs/Kconfig | 2 +- fs/Makefile | 2 +- fs/cifs/cifsencrypt.c | 2 +- fs/cifs/smbencrypt.c | 2 +- fs/{cifs_common => smbfs_common}/Makefile | 4 ++-- fs/{cifs_common => smbfs_common}/arc4.h | 0 fs/{cifs_common => smbfs_common}/cifs_arc4.c | 8 ++++---- fs/{cifs_common => smbfs_common}/cifs_md4.c | 0 fs/{cifs_common => smbfs_common}/md4.h | 0 9 files changed, 10 insertions(+), 10 deletions(-) rename fs/{cifs_common => smbfs_common}/Makefile (59%) rename fs/{cifs_common => smbfs_common}/arc4.h (100%) rename fs/{cifs_common => smbfs_common}/cifs_arc4.c (91%) rename fs/{cifs_common => smbfs_common}/cifs_md4.c (100%) rename fs/{cifs_common => smbfs_common}/md4.h (100%) diff --git a/fs/Kconfig b/fs/Kconfig index b11bd4b387e1..e7940882cbe8 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -352,7 +352,7 @@ source "fs/ceph/Kconfig" source "fs/cifs/Kconfig" source "fs/ksmbd/Kconfig" -config CIFS_COMMON +config SMBFS_COMMON tristate default y if CIFS=y default m if CIFS=m diff --git a/fs/Makefile b/fs/Makefile index 354e2ba3ee67..1f18802f43a4 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -96,7 +96,7 @@ obj-$(CONFIG_LOCKD) += lockd/ obj-$(CONFIG_NLS) += nls/ obj-$(CONFIG_UNICODE) += unicode/ obj-$(CONFIG_SYSV_FS) += sysv/ -obj-$(CONFIG_CIFS_COMMON) += cifs_common/ +obj-$(CONFIG_SMBFS_COMMON) += smbfs_common/ obj-$(CONFIG_CIFS) += cifs/ obj-$(CONFIG_SMB_SERVER) += ksmbd/ obj-$(CONFIG_HPFS_FS) += hpfs/ diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index 6679e07e533e..2e6f40344037 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c @@ -22,7 +22,7 @@ #include #include #include -#include "../cifs_common/arc4.h" +#include "../smbfs_common/arc4.h" #include int __cifs_calc_signature(struct smb_rqst *rqst, diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c index 10047cc55286..4a0487753869 100644 --- a/fs/cifs/smbencrypt.c +++ b/fs/cifs/smbencrypt.c @@ -24,7 +24,7 @@ #include "cifsglob.h" #include "cifs_debug.h" #include "cifsproto.h" -#include "../cifs_common/md4.h" +#include "../smbfs_common/md4.h" #ifndef false #define false 0 diff --git a/fs/cifs_common/Makefile b/fs/smbfs_common/Makefile similarity index 59% rename from fs/cifs_common/Makefile rename to fs/smbfs_common/Makefile index 6fedd2f88a25..cafc61a3bfc3 100644 --- a/fs/cifs_common/Makefile +++ b/fs/smbfs_common/Makefile @@ -3,5 +3,5 @@ # Makefile for Linux filesystem routines that are shared by client and server. # -obj-$(CONFIG_CIFS_COMMON) += cifs_arc4.o -obj-$(CONFIG_CIFS_COMMON) += cifs_md4.o +obj-$(CONFIG_SMBFS_COMMON) += cifs_arc4.o +obj-$(CONFIG_SMBFS_COMMON) += cifs_md4.o diff --git a/fs/cifs_common/arc4.h b/fs/smbfs_common/arc4.h similarity index 100% rename from fs/cifs_common/arc4.h rename to fs/smbfs_common/arc4.h diff --git a/fs/cifs_common/cifs_arc4.c b/fs/smbfs_common/cifs_arc4.c similarity index 91% rename from fs/cifs_common/cifs_arc4.c rename to fs/smbfs_common/cifs_arc4.c index b964cc682944..85ba15a60b13 100644 --- a/fs/cifs_common/cifs_arc4.c +++ b/fs/smbfs_common/cifs_arc4.c @@ -74,14 +74,14 @@ void cifs_arc4_crypt(struct arc4_ctx *ctx, u8 *out, const u8 *in, unsigned int l EXPORT_SYMBOL_GPL(cifs_arc4_crypt); static int __init -init_cifs_common(void) +init_smbfs_common(void) { return 0; } static void __init -exit_cifs_common(void) +exit_smbfs_common(void) { } -module_init(init_cifs_common) -module_exit(exit_cifs_common) +module_init(init_smbfs_common) +module_exit(exit_smbfs_common) diff --git a/fs/cifs_common/cifs_md4.c b/fs/smbfs_common/cifs_md4.c similarity index 100% rename from fs/cifs_common/cifs_md4.c rename to fs/smbfs_common/cifs_md4.c diff --git a/fs/cifs_common/md4.h b/fs/smbfs_common/md4.h similarity index 100% rename from fs/cifs_common/md4.h rename to fs/smbfs_common/md4.h From 8d014f5fe98142b79dfa3bcd0d9483a5165f3570 Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 9 Sep 2021 00:09:20 -0500 Subject: [PATCH 3/4] cifs: move SMB FSCTL definitions to common code The FSCTL definitions are in smbfsctl.h which should be shared by client and server. Move the updated version of smbfsctl.h into smbfs_common and have the client code use it (subsequent patch will change the server to use this common version of the header). Reviewed-by: Ronnie Sahlberg Signed-off-by: Steve French --- fs/cifs/cifspdu.h | 2 +- fs/{cifs => smbfs_common}/smbfsctl.h | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename fs/{cifs => smbfs_common}/smbfsctl.h (100%) diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index dc920e206336..98e8e5aa0613 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -12,7 +12,7 @@ #include #include -#include "smbfsctl.h" +#include "../smbfs_common/smbfsctl.h" #define CIFS_PROT 0 #define POSIX_PROT (CIFS_PROT+1) diff --git a/fs/cifs/smbfsctl.h b/fs/smbfs_common/smbfsctl.h similarity index 100% rename from fs/cifs/smbfsctl.h rename to fs/smbfs_common/smbfsctl.h From 9351590f51cdda49d0265932a37f099950998504 Mon Sep 17 00:00:00 2001 From: Enzo Matsumiya Date: Thu, 9 Sep 2021 18:46:45 -0300 Subject: [PATCH 4/4] cifs: properly invalidate cached root handle when closing it Cached root file was not being completely invalidated sometimes. Reproducing: - With a DFS share with 2 targets, one disabled and one enabled - start some I/O on the mount # while true; do ls /mnt/dfs; done - at the same time, disable the enabled target and enable the disabled one - wait for DFS cache to expire - on reconnect, the previous cached root handle should be invalid, but open_cached_dir_by_dentry() will still try to use it, but throws a use-after-free warning (kref_get()) Make smb2_close_cached_fid() invalidate all fields every time, but only send an SMB2_close() when the entry is still valid. Signed-off-by: Enzo Matsumiya Reviewed-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French --- fs/cifs/smb2ops.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index ddc0e8f97872..bda606dc72b1 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -689,13 +689,19 @@ smb2_close_cached_fid(struct kref *ref) cifs_dbg(FYI, "clear cached root file handle\n"); SMB2_close(0, cfid->tcon, cfid->fid->persistent_fid, cfid->fid->volatile_fid); - cfid->is_valid = false; - cfid->file_all_info_is_valid = false; - cfid->has_lease = false; - if (cfid->dentry) { - dput(cfid->dentry); - cfid->dentry = NULL; - } + } + + /* + * We only check validity above to send SMB2_close, + * but we still need to invalidate these entries + * when this function is called + */ + cfid->is_valid = false; + cfid->file_all_info_is_valid = false; + cfid->has_lease = false; + if (cfid->dentry) { + dput(cfid->dentry); + cfid->dentry = NULL; } }