From patchwork Sat Oct 12 08:55:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Pali_Roh=C3=A1r?= X-Patchwork-Id: 13834084 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E69C4D517; Sat, 12 Oct 2024 08:55:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728723329; cv=none; b=jEeXYubOuZBC1aZCG3JsZNHM5lAIPFBsAMN0soozCAD0j9CNHswf6yX9BrQ2GiHcQsyizPMdfqGsJ6vYtPqjfqIvFwXlJUrU5LBUbjiDax8ek+qttvL7O+gvnLqbSLAygjxJ8hI3fldsKiipkz6eE4NuN33idQ/v/AiOG2vESGg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728723329; c=relaxed/simple; bh=BEzzMn9tuq91tn/CyMsXH0kda1QwYiNB5hUQY0xol2c=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=m67r2pGUQEBL1A4KA9TQFK4QobT8peixjSMPZxZtjZC0s6+1rRl0V1N13W0RgJo5ecIH/SP2QCLOGBRu8dtb8Rkew+Owf1hngu6+lGhFnEDZXt4j9jSyLJGGfqvOAw5vBmnYLKOZIxdcqCuKhGgKxIVNHIaUVLqiVl4E2PFiXTc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=EtHJ+kvE; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="EtHJ+kvE" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2C7D9C4CEC6; Sat, 12 Oct 2024 08:55:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1728723327; bh=BEzzMn9tuq91tn/CyMsXH0kda1QwYiNB5hUQY0xol2c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EtHJ+kvE6bgvDdl9swGA9e7fgyy3rJg1gS1RXXVru+KgGpgRRmMCsBml6z6B6g3c9 /bhql2AmiaIDmcjr/3hKRC1ZKpmvsgVDRaABzthR3Ep0QPh7K/sHOFPG01mWbQC/9w wdF28j/SVveAEpCxeAILugc9MPAOfIvKqljU7d+b1Qo7LBvpzHGmtFEw3UA1GuhpFz 3SP1vlawY7ZNJcaRw8XAtF5ej0NOdum6qeVoXtTZ0MdbQRD/+4SiTNL5dfr8P7Cuze fhveKtAQAZPvPAq+uyrIBppkGx2O4igsxccXJpndPoNmGA8cujxKSzh71YrDr6A1u9 H8sISKXoVx0BQ== Received: by pali.im (Postfix) id 79BAA7BD; Sat, 12 Oct 2024 10:55:21 +0200 (CEST) From: =?utf-8?q?Pali_Roh=C3=A1r?= To: Steve French , Paulo Alcantara , Ronnie Sahlberg Cc: linux-cifs@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 1/7] cifs: Add mount option -o symlink= for choosing symlink create type Date: Sat, 12 Oct 2024 10:55:07 +0200 Message-Id: <20241012085507.633-1-pali@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20241012085252.560-1-pali@kernel.org> References: <20241012085252.560-1-pali@kernel.org> Precedence: bulk X-Mailing-List: linux-cifs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Currently Linux CIFS client creates a new symlink of the first flavor which is allowed by mount options, parsed in this order: -o (no)mfsymlinks, -o (no)sfu, -o (no)unix (+ its aliases) and -o reparse=[type]. Introduce a new mount option -o symlink= for explicitly choosing a symlink flavor. Possible options are: -o symlink=default - The default behavior, like before this change. -o symlink=none - Disallow creating a new symlinks -o symlink=native - Create as native SMB symlink reparse point -o symlink=unix - Create via SMB1 unix extension command -o symlink=mfsymlinks - Create as regular file of mfsymlinks format -o symlink=sfu - Create as regular system file of SFU format -o symlink=nfs - Create as NFS reparse point -o symlink=wsl - Create as WSL reparse point So for example specifying -o sfu,mfsymlinks,symlink=native will allow to parse symlinks also of SFU and mfsymlinks types (which are disabled by default unless mount option is explicitly specified), but new symlinks will be created under native SMB type (which parsing is always enabled). Signed-off-by: Pali Rohár --- fs/smb/client/cifsfs.c | 2 ++ fs/smb/client/cifsglob.h | 33 ++++++++++++++++++ fs/smb/client/connect.c | 2 ++ fs/smb/client/fs_context.c | 71 ++++++++++++++++++++++++++++++++++++++ fs/smb/client/fs_context.h | 16 +++++++++ fs/smb/client/link.c | 60 ++++++++++++++++++++++++-------- fs/smb/client/reparse.c | 52 ++++++++++++++++++++++------ fs/smb/client/reparse.h | 2 ++ 8 files changed, 214 insertions(+), 24 deletions(-) diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c index 000e1ef3beea..39ec67d9808e 100644 --- a/fs/smb/client/cifsfs.c +++ b/fs/smb/client/cifsfs.c @@ -689,6 +689,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root) cifs_sb->ctx->backupgid)); seq_show_option(s, "reparse", cifs_reparse_type_str(cifs_sb->ctx->reparse_type)); + seq_show_option(s, "symlink", + cifs_symlink_type_str(get_cifs_symlink_type(cifs_sb))); seq_printf(s, ",rsize=%u", cifs_sb->ctx->rsize); seq_printf(s, ",wsize=%u", cifs_sb->ctx->wsize); diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index d5446d652755..f419d20f6c38 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -171,6 +171,39 @@ static inline const char *cifs_reparse_type_str(enum cifs_reparse_type type) } } +enum cifs_symlink_type { + CIFS_SYMLINK_TYPE_DEFAULT, + CIFS_SYMLINK_TYPE_NONE, + CIFS_SYMLINK_TYPE_NATIVE, + CIFS_SYMLINK_TYPE_UNIX, + CIFS_SYMLINK_TYPE_MFSYMLINKS, + CIFS_SYMLINK_TYPE_SFU, + CIFS_SYMLINK_TYPE_NFS, + CIFS_SYMLINK_TYPE_WSL, +}; + +static inline const char *cifs_symlink_type_str(enum cifs_symlink_type type) +{ + switch (type) { + case CIFS_SYMLINK_TYPE_NONE: + return "none"; + case CIFS_SYMLINK_TYPE_NATIVE: + return "native"; + case CIFS_SYMLINK_TYPE_UNIX: + return "unix"; + case CIFS_SYMLINK_TYPE_MFSYMLINKS: + return "mfsymlinks"; + case CIFS_SYMLINK_TYPE_SFU: + return "sfu"; + case CIFS_SYMLINK_TYPE_NFS: + return "nfs"; + case CIFS_SYMLINK_TYPE_WSL: + return "wsl"; + default: + return "unknown"; + } +} + struct session_key { unsigned int len; char *response; diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c index adf8758847f6..bc5b5100ac09 100644 --- a/fs/smb/client/connect.c +++ b/fs/smb/client/connect.c @@ -2831,6 +2831,8 @@ compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data) return 0; if (old->ctx->reparse_type != new->ctx->reparse_type) return 0; + if (old->ctx->symlink_type != new->ctx->symlink_type) + return 0; return 1; } diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c index b2a8581c21f7..6bd4a5e61342 100644 --- a/fs/smb/client/fs_context.c +++ b/fs/smb/client/fs_context.c @@ -178,6 +178,7 @@ const struct fs_parameter_spec smb3_fs_parameters[] = { fsparam_string("sec", Opt_sec), fsparam_string("cache", Opt_cache), fsparam_string("reparse", Opt_reparse), + fsparam_string("symlink", Opt_symlink), fsparam_string("symlinkroot", Opt_symlinkroot), /* Arguments that should be ignored */ @@ -330,6 +331,55 @@ static int parse_reparse_flavor(struct fs_context *fc, char *value, return 0; } +static const match_table_t symlink_flavor_tokens = { + { Opt_symlink_default, "default" }, + { Opt_symlink_none, "none" }, + { Opt_symlink_native, "native" }, + { Opt_symlink_unix, "unix" }, + { Opt_symlink_mfsymlinks, "mfsymlinks" }, + { Opt_symlink_sfu, "sfu" }, + { Opt_symlink_nfs, "nfs" }, + { Opt_symlink_wsl, "wsl" }, + { Opt_symlink_err, NULL }, +}; + +static int parse_symlink_flavor(struct fs_context *fc, char *value, + struct smb3_fs_context *ctx) +{ + substring_t args[MAX_OPT_ARGS]; + + switch (match_token(value, symlink_flavor_tokens, args)) { + case Opt_symlink_default: + ctx->symlink_type = CIFS_SYMLINK_TYPE_DEFAULT; + break; + case Opt_symlink_none: + ctx->symlink_type = CIFS_SYMLINK_TYPE_NONE; + break; + case Opt_symlink_native: + ctx->symlink_type = CIFS_SYMLINK_TYPE_NATIVE; + break; + case Opt_symlink_unix: + ctx->symlink_type = CIFS_SYMLINK_TYPE_UNIX; + break; + case Opt_symlink_mfsymlinks: + ctx->symlink_type = CIFS_SYMLINK_TYPE_MFSYMLINKS; + break; + case Opt_symlink_sfu: + ctx->symlink_type = CIFS_SYMLINK_TYPE_SFU; + break; + case Opt_symlink_nfs: + ctx->symlink_type = CIFS_SYMLINK_TYPE_NFS; + break; + case Opt_symlink_wsl: + ctx->symlink_type = CIFS_SYMLINK_TYPE_WSL; + break; + default: + cifs_errorf(fc, "bad symlink= option: %s\n", value); + return 1; + } + return 0; +} + #define DUP_CTX_STR(field) \ do { \ if (ctx->field) { \ @@ -1620,6 +1670,10 @@ static int smb3_fs_context_parse_param(struct fs_context *fc, if (parse_reparse_flavor(fc, param->string, ctx)) goto cifs_parse_mount_err; break; + case Opt_symlink: + if (parse_symlink_flavor(fc, param->string, ctx)) + goto cifs_parse_mount_err; + break; case Opt_symlinkroot: if (param->string[0] != '/') { cifs_errorf(fc, "symlinkroot mount options must be absolute path\n"); @@ -1650,6 +1704,22 @@ static int smb3_fs_context_parse_param(struct fs_context *fc, return -EINVAL; } +enum cifs_symlink_type get_cifs_symlink_type(struct cifs_sb_info *cifs_sb) +{ + if (cifs_sb->ctx->symlink_type == CIFS_SYMLINK_TYPE_DEFAULT) { + if (cifs_sb->ctx->mfsymlinks) + return CIFS_SYMLINK_TYPE_MFSYMLINKS; + else if (cifs_sb->ctx->sfu_emul) + return CIFS_SYMLINK_TYPE_SFU; + else if (cifs_sb->ctx->linux_ext && !cifs_sb->ctx->no_linux_ext) + return CIFS_SYMLINK_TYPE_UNIX; + else + return CIFS_SYMLINK_TYPE_NATIVE; + } else { + return cifs_sb->ctx->symlink_type; + } +} + int smb3_init_fs_context(struct fs_context *fc) { struct smb3_fs_context *ctx; @@ -1726,6 +1796,7 @@ int smb3_init_fs_context(struct fs_context *fc) ctx->retrans = 1; ctx->reparse_type = CIFS_REPARSE_TYPE_DEFAULT; + ctx->symlink_type = CIFS_SYMLINK_TYPE_DEFAULT; /* * short int override_uid = -1; diff --git a/fs/smb/client/fs_context.h b/fs/smb/client/fs_context.h index 94db5fdce621..3bcf20495fea 100644 --- a/fs/smb/client/fs_context.h +++ b/fs/smb/client/fs_context.h @@ -48,6 +48,18 @@ enum cifs_reparse_parm { Opt_reparse_err }; +enum cifs_symlink_parm { + Opt_symlink_default, + Opt_symlink_none, + Opt_symlink_native, + Opt_symlink_unix, + Opt_symlink_mfsymlinks, + Opt_symlink_sfu, + Opt_symlink_nfs, + Opt_symlink_wsl, + Opt_symlink_err +}; + enum cifs_sec_param { Opt_sec_krb5, Opt_sec_krb5i, @@ -157,6 +169,7 @@ enum cifs_param { Opt_sec, Opt_cache, Opt_reparse, + Opt_symlink, Opt_symlinkroot, /* Mount options to be ignored */ @@ -285,12 +298,15 @@ struct smb3_fs_context { struct cifs_ses *dfs_root_ses; bool dfs_automount:1; /* set for dfs automount only */ enum cifs_reparse_type reparse_type; + enum cifs_symlink_type symlink_type; bool dfs_conn:1; /* set for dfs mounts */ char *symlinkroot; /* top level directory for native SMB symlinks in absolute format */ }; extern const struct fs_parameter_spec smb3_fs_parameters[]; +extern enum cifs_symlink_type get_cifs_symlink_type(struct cifs_sb_info *cifs_sb); + extern int smb3_init_fs_context(struct fs_context *fc); extern void smb3_cleanup_fs_context_contents(struct smb3_fs_context *ctx); extern void smb3_cleanup_fs_context(struct smb3_fs_context *ctx); diff --git a/fs/smb/client/link.c b/fs/smb/client/link.c index 47ddeb7fa111..6e6c09cc5ce7 100644 --- a/fs/smb/client/link.c +++ b/fs/smb/client/link.c @@ -18,6 +18,7 @@ #include "cifs_unicode.h" #include "smb2proto.h" #include "cifs_ioctl.h" +#include "fs_context.h" /* * M-F Symlink Functions - Begin @@ -604,22 +605,53 @@ cifs_symlink(struct mnt_idmap *idmap, struct inode *inode, cifs_dbg(FYI, "symname is %s\n", symname); /* BB what if DFS and this volume is on different share? BB */ - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) { - rc = create_mf_symlink(xid, pTcon, cifs_sb, full_path, symname); - } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { - rc = __cifs_sfu_make_node(xid, inode, direntry, pTcon, - full_path, S_IFLNK, 0, symname); + rc = -EOPNOTSUPP; + switch (get_cifs_symlink_type(cifs_sb)) { + case CIFS_SYMLINK_TYPE_DEFAULT: + /* should not happen, get_cifs_symlink_type() resolves the default */ + break; + + case CIFS_SYMLINK_TYPE_NONE: + break; + + case CIFS_SYMLINK_TYPE_UNIX: #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY - } else if (pTcon->unix_ext) { - rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname, - cifs_sb->local_nls, - cifs_remap(cifs_sb)); + if (pTcon->unix_ext) { + rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, + symname, + cifs_sb->local_nls, + cifs_remap(cifs_sb)); + } #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ - } else if (server->ops->create_reparse_symlink) { - rc = server->ops->create_reparse_symlink(xid, inode, direntry, - pTcon, full_path, - symname); - goto symlink_exit; + break; + + case CIFS_SYMLINK_TYPE_MFSYMLINKS: + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) { + rc = create_mf_symlink(xid, pTcon, cifs_sb, + full_path, symname); + } + break; + + case CIFS_SYMLINK_TYPE_SFU: + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { + rc = __cifs_sfu_make_node(xid, inode, direntry, pTcon, + full_path, S_IFLNK, + 0, symname); + } + break; + + case CIFS_SYMLINK_TYPE_NATIVE: + case CIFS_SYMLINK_TYPE_NFS: + case CIFS_SYMLINK_TYPE_WSL: + if (server->ops->create_reparse_symlink) { + rc = server->ops->create_reparse_symlink(xid, inode, + direntry, + pTcon, + full_path, + symname); + goto symlink_exit; + } + break; } if (rc == 0) { diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c index 99ef9bc88afc..d950c60323e8 100644 --- a/fs/smb/client/reparse.c +++ b/fs/smb/client/reparse.c @@ -14,6 +14,20 @@ #include "fs_context.h" #include "reparse.h" +static int mknod_nfs(unsigned int xid, struct inode *inode, + struct dentry *dentry, struct cifs_tcon *tcon, + const char *full_path, umode_t mode, dev_t dev, + const char *symname); + +static int mknod_wsl(unsigned int xid, struct inode *inode, + struct dentry *dentry, struct cifs_tcon *tcon, + const char *full_path, umode_t mode, dev_t dev, + const char *symname); + +static int create_native_symlink(const unsigned int xid, struct inode *inode, + struct dentry *dentry, struct cifs_tcon *tcon, + const char *full_path, const char *symname); + static int detect_directory_symlink_target(struct cifs_sb_info *cifs_sb, const unsigned int xid, const char *full_path, @@ -23,6 +37,22 @@ static int detect_directory_symlink_target(struct cifs_sb_info *cifs_sb, int smb2_create_reparse_symlink(const unsigned int xid, struct inode *inode, struct dentry *dentry, struct cifs_tcon *tcon, const char *full_path, const char *symname) +{ + switch (get_cifs_symlink_type(CIFS_SB(inode->i_sb))) { + case CIFS_SYMLINK_TYPE_NATIVE: + return create_native_symlink(xid, inode, dentry, tcon, full_path, symname); + case CIFS_SYMLINK_TYPE_NFS: + return mknod_nfs(xid, inode, dentry, tcon, full_path, S_IFLNK, 0, symname); + case CIFS_SYMLINK_TYPE_WSL: + return mknod_wsl(xid, inode, dentry, tcon, full_path, S_IFLNK, 0, symname); + default: + return -EOPNOTSUPP; + } +} + +static int create_native_symlink(const unsigned int xid, struct inode *inode, + struct dentry *dentry, struct cifs_tcon *tcon, + const char *full_path, const char *symname) { struct reparse_symlink_data_buffer *buf = NULL; struct cifs_open_info_data data = {}; @@ -363,6 +393,7 @@ static int nfs_set_reparse_buf(struct reparse_posix_data *buf, case NFS_SPECFILE_SOCK: dlen = 0; break; + case NFS_SPECFILE_LNK: /* TODO: add support for NFS symlinks */ default: return -EOPNOTSUPP; } @@ -381,7 +412,8 @@ static int nfs_set_reparse_buf(struct reparse_posix_data *buf, static int mknod_nfs(unsigned int xid, struct inode *inode, struct dentry *dentry, struct cifs_tcon *tcon, - const char *full_path, umode_t mode, dev_t dev) + const char *full_path, umode_t mode, dev_t dev, + const char *symname) { struct cifs_open_info_data data; struct reparse_posix_data *p; @@ -421,6 +453,7 @@ static int wsl_set_reparse_buf(struct reparse_data_buffer *buf, case IO_REPARSE_TAG_LX_FIFO: case IO_REPARSE_TAG_AF_UNIX: break; + case IO_REPARSE_TAG_LX_SYMLINK: /* TODO: add support for WSL symlinks */ default: return -EOPNOTSUPP; } @@ -518,7 +551,8 @@ static int wsl_set_xattrs(struct inode *inode, umode_t _mode, static int mknod_wsl(unsigned int xid, struct inode *inode, struct dentry *dentry, struct cifs_tcon *tcon, - const char *full_path, umode_t mode, dev_t dev) + const char *full_path, umode_t mode, dev_t dev, + const char *symname) { struct cifs_open_info_data data; struct reparse_data_buffer buf; @@ -563,17 +597,15 @@ int smb2_mknod_reparse(unsigned int xid, struct inode *inode, const char *full_path, umode_t mode, dev_t dev) { struct smb3_fs_context *ctx = CIFS_SB(inode->i_sb)->ctx; - int rc = -EOPNOTSUPP; switch (ctx->reparse_type) { case CIFS_REPARSE_TYPE_NFS: - rc = mknod_nfs(xid, inode, dentry, tcon, full_path, mode, dev); - break; + return mknod_nfs(xid, inode, dentry, tcon, full_path, mode, dev, NULL); case CIFS_REPARSE_TYPE_WSL: - rc = mknod_wsl(xid, inode, dentry, tcon, full_path, mode, dev); - break; + return mknod_wsl(xid, inode, dentry, tcon, full_path, mode, dev, NULL); + default: + return -EOPNOTSUPP; } - return rc; } /* See MS-FSCC 2.1.2.6 for the 'NFS' style reparse tags */ @@ -848,7 +880,7 @@ int smb2_parse_native_symlink(char **target, const char *buf, unsigned int len, return rc; } -static int parse_reparse_symlink(struct reparse_symlink_data_buffer *sym, +static int parse_reparse_native_symlink(struct reparse_symlink_data_buffer *sym, u32 plen, bool unicode, struct cifs_sb_info *cifs_sb, const char *full_path, @@ -936,7 +968,7 @@ int parse_reparse_point(struct reparse_data_buffer *buf, return parse_reparse_posix((struct reparse_posix_data *)buf, cifs_sb, data); case IO_REPARSE_TAG_SYMLINK: - return parse_reparse_symlink( + return parse_reparse_native_symlink( (struct reparse_symlink_data_buffer *)buf, plen, unicode, cifs_sb, full_path, data); case IO_REPARSE_TAG_LX_SYMLINK: diff --git a/fs/smb/client/reparse.h b/fs/smb/client/reparse.h index 81b6979bb40b..08579af9b9d7 100644 --- a/fs/smb/client/reparse.h +++ b/fs/smb/client/reparse.h @@ -48,6 +48,7 @@ static inline kgid_t wsl_make_kgid(struct cifs_sb_info *cifs_sb, static inline u64 reparse_mode_nfs_type(mode_t mode) { switch (mode & S_IFMT) { + case S_IFLNK: return NFS_SPECFILE_LNK; case S_IFBLK: return NFS_SPECFILE_BLK; case S_IFCHR: return NFS_SPECFILE_CHR; case S_IFIFO: return NFS_SPECFILE_FIFO; @@ -59,6 +60,7 @@ static inline u64 reparse_mode_nfs_type(mode_t mode) static inline u32 reparse_mode_wsl_tag(mode_t mode) { switch (mode & S_IFMT) { + case S_IFLNK: return IO_REPARSE_TAG_LX_SYMLINK; case S_IFBLK: return IO_REPARSE_TAG_LX_BLK; case S_IFCHR: return IO_REPARSE_TAG_LX_CHR; case S_IFIFO: return IO_REPARSE_TAG_LX_FIFO; From patchwork Sat Oct 12 08:55:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Pali_Roh=C3=A1r?= X-Patchwork-Id: 13834085 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A7B7D14A092; Sat, 12 Oct 2024 08:55:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728723345; cv=none; b=ESRv40BX2bvBTihEtGN63C2RZY3JyPRanADlkjEqPVhQgjYoOhJd99jER5IbKpg5xeRgpphgbddfshVgF428qQ+nAe09uu/gsV85Q+mXnMc6f9xSj1+RUbC6rpUdMiBXSpwG1MwADfTd8j4uSSYK5hIbAsi93NqLYTgDkHxxj6I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728723345; c=relaxed/simple; bh=2leM15kk/Vs6N9tTsC8o3+vg/CPabJBZtZdvUeCLCuA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=piUyexr7TPoc5ppHiKABo3pwsXgId4Oh5l3xCXmPk/x04heg+4P6m0ZRaFSLqsftYsNOdeHkFe5UMpqtp0WPCzEy9djv9nsTPG2J1mKTFufDWcJ32LplsT+xV6RsKz4LoRfsp4pNf/9HCVDlVETno7W7Aeir46U2IhPZkVeCOfI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QTbjGVTx; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="QTbjGVTx" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 139BBC4CEC6; Sat, 12 Oct 2024 08:55:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1728723345; bh=2leM15kk/Vs6N9tTsC8o3+vg/CPabJBZtZdvUeCLCuA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QTbjGVTxzCa7mNCouu5xO8ACM6yH+PBNswt373y9vZylfvFZhs2c+nrRFsuZOmfIO lhbzVho0NY+Xz7EgFEF51Oz4udurHrIOz1Zv+akkTuTI6ccn987wdPYhxw1sLcbFB5 nPMdxPYaLcYdgZiMkYJStbqyCNZqeqN09R8EXELH43GSeHHcBrTdcxUZnwcEHBq884 LIoXlqd0Rgb6jQfV2x+QVVgm0puo7Yct2XtU/Ec6RhwfH4OWV3u0BWnUmB+NR8J2y3 ahT9ljFP69zorgcOlasDNnSdiAXxUVARV+TIL8jF4tRoWzkhb4Tklf7rVPMHfTQixF JDovbdTkczSPw== Received: by pali.im (Postfix) id 4D1F07BD; Sat, 12 Oct 2024 10:55:39 +0200 (CEST) From: =?utf-8?q?Pali_Roh=C3=A1r?= To: Steve French , Paulo Alcantara , Ronnie Sahlberg Cc: linux-cifs@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 2/7] cifs: Add mount option -o reparse=none Date: Sat, 12 Oct 2024 10:55:37 +0200 Message-Id: <20241012085537.652-1-pali@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20241012085252.560-1-pali@kernel.org> References: <20241012085252.560-1-pali@kernel.org> Precedence: bulk X-Mailing-List: linux-cifs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This new mount option allows to completely disable creating new reparse points. When -o sfu or -o mfsymlinks or -o symlink= is not specified then creating any special file (fifo, socket, symlink, block and char) will fail with -EOPNOTSUPP error. Signed-off-by: Pali Rohár --- fs/smb/client/cifsglob.h | 3 +++ fs/smb/client/fs_context.c | 8 +++++++- fs/smb/client/fs_context.h | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index f419d20f6c38..dcee43889358 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -154,6 +154,7 @@ enum securityEnum { }; enum cifs_reparse_type { + CIFS_REPARSE_TYPE_NONE, CIFS_REPARSE_TYPE_NFS, CIFS_REPARSE_TYPE_WSL, CIFS_REPARSE_TYPE_DEFAULT = CIFS_REPARSE_TYPE_NFS, @@ -162,6 +163,8 @@ enum cifs_reparse_type { static inline const char *cifs_reparse_type_str(enum cifs_reparse_type type) { switch (type) { + case CIFS_REPARSE_TYPE_NONE: + return "none"; case CIFS_REPARSE_TYPE_NFS: return "nfs"; case CIFS_REPARSE_TYPE_WSL: diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c index 6bd4a5e61342..d68db6ac5f73 100644 --- a/fs/smb/client/fs_context.c +++ b/fs/smb/client/fs_context.c @@ -304,6 +304,7 @@ cifs_parse_cache_flavor(struct fs_context *fc, char *value, struct smb3_fs_conte static const match_table_t reparse_flavor_tokens = { { Opt_reparse_default, "default" }, + { Opt_reparse_none, "none" }, { Opt_reparse_nfs, "nfs" }, { Opt_reparse_wsl, "wsl" }, { Opt_reparse_err, NULL }, @@ -318,6 +319,9 @@ static int parse_reparse_flavor(struct fs_context *fc, char *value, case Opt_reparse_default: ctx->reparse_type = CIFS_REPARSE_TYPE_DEFAULT; break; + case Opt_reparse_none: + ctx->reparse_type = CIFS_REPARSE_TYPE_NONE; + break; case Opt_reparse_nfs: ctx->reparse_type = CIFS_REPARSE_TYPE_NFS; break; @@ -1713,8 +1717,10 @@ enum cifs_symlink_type get_cifs_symlink_type(struct cifs_sb_info *cifs_sb) return CIFS_SYMLINK_TYPE_SFU; else if (cifs_sb->ctx->linux_ext && !cifs_sb->ctx->no_linux_ext) return CIFS_SYMLINK_TYPE_UNIX; - else + else if (cifs_sb->ctx->reparse_type != CIFS_REPARSE_TYPE_NONE) return CIFS_SYMLINK_TYPE_NATIVE; + else + return CIFS_SYMLINK_TYPE_NONE; } else { return cifs_sb->ctx->symlink_type; } diff --git a/fs/smb/client/fs_context.h b/fs/smb/client/fs_context.h index 3bcf20495fea..5f306f581fd1 100644 --- a/fs/smb/client/fs_context.h +++ b/fs/smb/client/fs_context.h @@ -43,6 +43,7 @@ enum { enum cifs_reparse_parm { Opt_reparse_default, + Opt_reparse_none, Opt_reparse_nfs, Opt_reparse_wsl, Opt_reparse_err From patchwork Sat Oct 12 08:55:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Pali_Roh=C3=A1r?= X-Patchwork-Id: 13834086 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D6AD1D517; Sat, 12 Oct 2024 08:55:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728723356; cv=none; b=YsXNsoXyLImBsq3pk5RIo8HwlDwPvmy4IUFKi75yGSHuJtFKsQxzWdZ2dj5U1jdP492CrPcq/OIgpiDFvp+VyiGIJmBRgE2a2AJkxqzth9bzq+A4MuvpX3cbR34phkQZU4wE3UQgK0vPBTLxWY5dI6DJE+ENo3bvGdQoNUYcGRk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728723356; c=relaxed/simple; bh=aXcWnBwn8eWzEpq2xCZrD9ltkMngFQdpO2DxXG4OBig=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=BZsA0Q0dMSaLl+g9VJvzMU8crbBPATBxegiT7tR+ZN79fPfjJJ4ybYk3P3M/llhQt6jtH7LSNB1008XDm6dfqrPkErLuYeWmIdM5jPJZEU2HkpZBo8SqdHAzSA5YD/EeG7onERKNzEZ3fvCtqc53dl1IGkLs2Ux+RHoB6GJFhz0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PXFFlkWG; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="PXFFlkWG" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 28D9AC4CEC6; Sat, 12 Oct 2024 08:55:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1728723356; bh=aXcWnBwn8eWzEpq2xCZrD9ltkMngFQdpO2DxXG4OBig=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PXFFlkWG2xALIxw6MpT+bonBCEp14z0bIenks0ExMq0uJmKp6CkgcMs0YTQ4mhvVq Av0rY+rOJ9YCC7cosx/ul8OhuFcnYiZR9CzsSXF244j/ux+fYFjk07RTLSiLUIJYiN W51TPLNda/X9CR1A7eljOBVVGoPmu3/LVEtIeG4d80fnSVl1nZpfwS0rlJHmADcptR wGO4l72XAZgmUngmqaAn8DZACdir3rP6juSWtNPTz96eOHZLp10uRvnFs0BaYimdgL RgimmlIfzRXUU/5cC8G7GuDZfL88qAzGs69EgWCH6Xy24k+8sDoN8wAl7KIIRwremZ 6V7p9orQy2E5w== Received: by pali.im (Postfix) id E8F647BD; Sat, 12 Oct 2024 10:55:50 +0200 (CEST) From: =?utf-8?q?Pali_Roh=C3=A1r?= To: Steve French , Paulo Alcantara , Ronnie Sahlberg Cc: linux-cifs@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 3/7] cifs: Add support for creating native Windows sockets Date: Sat, 12 Oct 2024 10:55:49 +0200 Message-Id: <20241012085549.670-1-pali@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20241012085252.560-1-pali@kernel.org> References: <20241012085252.560-1-pali@kernel.org> Precedence: bulk X-Mailing-List: linux-cifs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Native Windows sockets created by WinSock on Windows 10 April 2018 Update (version 1803) or Windows Server 2019 (version 1809) or later versions is reparse point with IO_REPARSE_TAG_AF_UNIX tag, with empty reparse point data buffer and without any EAs. Create AF_UNIX sockets in this native format if -o nonativesocket was not specified. This change makes AF_UNIX sockets created by Linux CIFS client compatible with AF_UNIX sockets created by Windows applications on NTFS volumes. Signed-off-by: Pali Rohár --- fs/smb/client/cifsfs.c | 2 ++ fs/smb/client/connect.c | 2 ++ fs/smb/client/fs_context.c | 5 +++++ fs/smb/client/fs_context.h | 2 ++ fs/smb/client/reparse.c | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 43 insertions(+) diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c index 39ec67d9808e..eb279d5c6bd3 100644 --- a/fs/smb/client/cifsfs.c +++ b/fs/smb/client/cifsfs.c @@ -689,6 +689,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root) cifs_sb->ctx->backupgid)); seq_show_option(s, "reparse", cifs_reparse_type_str(cifs_sb->ctx->reparse_type)); + if (cifs_sb->ctx->nonativesocket) + seq_puts(s, ",nonativesocket"); seq_show_option(s, "symlink", cifs_symlink_type_str(get_cifs_symlink_type(cifs_sb))); diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c index bc5b5100ac09..3db39f2ef5a8 100644 --- a/fs/smb/client/connect.c +++ b/fs/smb/client/connect.c @@ -2831,6 +2831,8 @@ compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data) return 0; if (old->ctx->reparse_type != new->ctx->reparse_type) return 0; + if (old->ctx->nonativesocket != new->ctx->nonativesocket) + return 0; if (old->ctx->symlink_type != new->ctx->symlink_type) return 0; diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c index d68db6ac5f73..7f21630885cb 100644 --- a/fs/smb/client/fs_context.c +++ b/fs/smb/client/fs_context.c @@ -178,6 +178,7 @@ const struct fs_parameter_spec smb3_fs_parameters[] = { fsparam_string("sec", Opt_sec), fsparam_string("cache", Opt_cache), fsparam_string("reparse", Opt_reparse), + fsparam_string("nativesocket", Opt_nativesocket), fsparam_string("symlink", Opt_symlink), fsparam_string("symlinkroot", Opt_symlinkroot), @@ -1674,6 +1675,9 @@ static int smb3_fs_context_parse_param(struct fs_context *fc, if (parse_reparse_flavor(fc, param->string, ctx)) goto cifs_parse_mount_err; break; + case Opt_nativesocket: + ctx->nonativesocket = result.negated; + break; case Opt_symlink: if (parse_symlink_flavor(fc, param->string, ctx)) goto cifs_parse_mount_err; @@ -1803,6 +1807,7 @@ int smb3_init_fs_context(struct fs_context *fc) ctx->retrans = 1; ctx->reparse_type = CIFS_REPARSE_TYPE_DEFAULT; ctx->symlink_type = CIFS_SYMLINK_TYPE_DEFAULT; + ctx->nonativesocket = 0; /* * short int override_uid = -1; diff --git a/fs/smb/client/fs_context.h b/fs/smb/client/fs_context.h index 5f306f581fd1..18d39d457145 100644 --- a/fs/smb/client/fs_context.h +++ b/fs/smb/client/fs_context.h @@ -170,6 +170,7 @@ enum cifs_param { Opt_sec, Opt_cache, Opt_reparse, + Opt_nativesocket, Opt_symlink, Opt_symlinkroot, @@ -300,6 +301,7 @@ struct smb3_fs_context { bool dfs_automount:1; /* set for dfs automount only */ enum cifs_reparse_type reparse_type; enum cifs_symlink_type symlink_type; + bool nonativesocket:1; bool dfs_conn:1; /* set for dfs mounts */ char *symlinkroot; /* top level directory for native SMB symlinks in absolute format */ }; diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c index d950c60323e8..57320a4c4d79 100644 --- a/fs/smb/client/reparse.c +++ b/fs/smb/client/reparse.c @@ -375,6 +375,35 @@ static int detect_directory_symlink_target(struct cifs_sb_info *cifs_sb, return 0; } +static int create_native_socket(const unsigned int xid, struct inode *inode, + struct dentry *dentry, struct cifs_tcon *tcon, + const char *full_path) +{ + struct cifs_open_info_data data = { + .reparse_point = true, + .reparse = { .tag = IO_REPARSE_TAG_AF_UNIX, }, + }; + struct reparse_data_buffer buf = { + .ReparseTag = cpu_to_le32(IO_REPARSE_TAG_AF_UNIX), + .ReparseDataLength = cpu_to_le16(0), + }; + struct kvec iov = { + .iov_base = &buf, + .iov_len = sizeof(buf), + }; + struct inode *new; + int rc = 0; + + new = smb2_get_reparse_inode(&data, inode->i_sb, xid, + tcon, full_path, false, &iov, NULL); + if (!IS_ERR(new)) + d_instantiate(dentry, new); + else + rc = PTR_ERR(new); + cifs_free_open_info(&data); + return rc; +} + static int nfs_set_reparse_buf(struct reparse_posix_data *buf, mode_t mode, dev_t dev, struct kvec *iov) @@ -598,6 +627,9 @@ int smb2_mknod_reparse(unsigned int xid, struct inode *inode, { struct smb3_fs_context *ctx = CIFS_SB(inode->i_sb)->ctx; + if (S_ISSOCK(mode) && !ctx->nonativesocket && ctx->reparse_type != CIFS_REPARSE_TYPE_NONE) + return create_native_socket(xid, inode, dentry, tcon, full_path); + switch (ctx->reparse_type) { case CIFS_REPARSE_TYPE_NFS: return mknod_nfs(xid, inode, dentry, tcon, full_path, mode, dev, NULL); From patchwork Sat Oct 12 08:56:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Pali_Roh=C3=A1r?= X-Patchwork-Id: 13834087 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 11C18145B0F; Sat, 12 Oct 2024 08:56:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728723369; cv=none; b=thxLh0XFHLFyzE5u6vHqnUMECl9Dk1yvH3RZp3Vyoc6de9xwWg4ATRmMqi3JcX4Lw1jHDWOvRM8ZG4/1JTqM/duEwq8OSQ92Baf6iufD5Rt/Xh4YYB7b79R4CJSe4JHlsafGKryHVkc8Q//grindgkOe2tuL2NjfsEBjg3+ghRg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728723369; c=relaxed/simple; bh=vATFG8shnKFunaoRDxD/P8NZHqYAHDJ9fb/RllpA1AM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=pA/9Ha4KEgmnyXDZ7VsiLUta5oxv8qPd24wPSe42qUhGBLMBPb2w9ZRvYV9WkOXOPjpyCi7j8eRJvvcNqsdiAgRwX9vqK3km2cien5DAouSxRnzXz6Xjdkejq+/eSPZL913ylNKML1MWWknBmF3Bw1CkXrG+VCnvCyx0V/Py9+w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=XGM7KrL4; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="XGM7KrL4" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 91E2BC4CEC6; Sat, 12 Oct 2024 08:56:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1728723368; bh=vATFG8shnKFunaoRDxD/P8NZHqYAHDJ9fb/RllpA1AM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XGM7KrL4N5/OP7emMj86K2M/s1JgawQo7tZrreEC8AnsusjkN7fKEKtEbBjy+L6Px MmfLM2+1v/fmuFd1ulfeJw6ws8RdwQDdiblm8liSrfPlT6KH4eYaMXSrZjCCtSt67P cB3NVxV/V/aI8P9Se2uXVFvUZiQYxjVMdmHEIFqrU/xiZlZ+HP1ZAFfqfRHEkARfOP gTnSc08UJ7ZYcydAkj4ajgVtBMAYGzkRRbX1O3KQXnBhalDheAVyjXhsgqiVn/qpwN BaEWJ8w4bDgZc3DX7fF/3RSSd9NVkdext6MnSmqj47b1rHrsdDQtuwzffcGn46Tfb6 BNJC36DxUurqw== Received: by pali.im (Postfix) id 0AA2F7BD; Sat, 12 Oct 2024 10:56:03 +0200 (CEST) From: =?utf-8?q?Pali_Roh=C3=A1r?= To: Steve French , Paulo Alcantara , Ronnie Sahlberg Cc: linux-cifs@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 4/7] cifs: Add support for creating NFS-style symlinks Date: Sat, 12 Oct 2024 10:56:01 +0200 Message-Id: <20241012085601.694-1-pali@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20241012085252.560-1-pali@kernel.org> References: <20241012085252.560-1-pali@kernel.org> Precedence: bulk X-Mailing-List: linux-cifs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 CIFS client is currently able to parse NFS-style symlinks, but is not able to create them. This functionality is useful when the mounted SMB share is used also by Windows NFS server (on Windows Server 2012 or new). It allows interop of symlinks between SMB share mounted by Linux CIFS client and same export from Windows NFS server mounted by some NFS client. New symlinks would be created in NFS-style only in case the mount option -o reparse=nfs is specified, which is not by default. So default CIFS mounts are not affected by this change. Signed-off-by: Pali Rohár --- fs/smb/client/reparse.c | 47 ++++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c index 57320a4c4d79..cd12704cae0c 100644 --- a/fs/smb/client/reparse.c +++ b/fs/smb/client/reparse.c @@ -406,6 +406,8 @@ static int create_native_socket(const unsigned int xid, struct inode *inode, static int nfs_set_reparse_buf(struct reparse_posix_data *buf, mode_t mode, dev_t dev, + __le16 *symname_utf16, + int symname_utf16_len, struct kvec *iov) { u64 type; @@ -416,13 +418,18 @@ static int nfs_set_reparse_buf(struct reparse_posix_data *buf, switch ((type = reparse_mode_nfs_type(mode))) { case NFS_SPECFILE_BLK: case NFS_SPECFILE_CHR: - dlen = sizeof(__le64); + dlen = 2 * sizeof(__le32); + ((__le32 *)buf->DataBuffer)[0] = MAJOR(dev); + ((__le32 *)buf->DataBuffer)[1] = MINOR(dev); + break; + case NFS_SPECFILE_LNK: + dlen = symname_utf16_len; + memcpy(buf->DataBuffer, symname_utf16, symname_utf16_len); break; case NFS_SPECFILE_FIFO: case NFS_SPECFILE_SOCK: dlen = 0; break; - case NFS_SPECFILE_LNK: /* TODO: add support for NFS symlinks */ default: return -EOPNOTSUPP; } @@ -432,8 +439,6 @@ static int nfs_set_reparse_buf(struct reparse_posix_data *buf, buf->InodeType = cpu_to_le64(type); buf->ReparseDataLength = cpu_to_le16(len + dlen - sizeof(struct reparse_data_buffer)); - *(__le64 *)buf->DataBuffer = cpu_to_le64(((u64)MINOR(dev) << 32) | - MAJOR(dev)); iov->iov_base = buf; iov->iov_len = len + dlen; return 0; @@ -444,21 +449,42 @@ static int mknod_nfs(unsigned int xid, struct inode *inode, const char *full_path, umode_t mode, dev_t dev, const char *symname) { + struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifs_open_info_data data; - struct reparse_posix_data *p; + struct reparse_posix_data *p = NULL; + __le16 *symname_utf16 = NULL; + int symname_utf16_len = 0; struct inode *new; struct kvec iov; __u8 buf[sizeof(*p) + sizeof(__le64)]; int rc; - p = (struct reparse_posix_data *)buf; - rc = nfs_set_reparse_buf(p, mode, dev, &iov); + if (S_ISLNK(mode)) { + symname_utf16 = cifs_strndup_to_utf16(symname, strlen(symname), + &symname_utf16_len, + cifs_sb->local_nls, + NO_MAP_UNI_RSVD); + if (!symname_utf16) { + rc = -ENOMEM; + goto out; + } + symname_utf16_len -= 2; /* symlink is without trailing wide-nul */ + p = kzalloc(sizeof(*p) + symname_utf16_len, GFP_KERNEL); + if (!p) { + rc = -ENOMEM; + goto out; + } + } else { + p = (struct reparse_posix_data *)buf; + } + rc = nfs_set_reparse_buf(p, mode, dev, symname_utf16, symname_utf16_len, &iov); if (rc) - return rc; + goto out; data = (struct cifs_open_info_data) { .reparse_point = true, .reparse = { .tag = IO_REPARSE_TAG_NFS, .posix = p, }, + .symlink_target = kstrdup(symname, GFP_KERNEL), }; new = smb2_get_reparse_inode(&data, inode->i_sb, xid, @@ -468,6 +494,11 @@ static int mknod_nfs(unsigned int xid, struct inode *inode, else rc = PTR_ERR(new); cifs_free_open_info(&data); +out: + if (S_ISLNK(mode)) { + kfree(symname_utf16); + kfree(p); + } return rc; } From patchwork Sat Oct 12 08:56:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Pali_Roh=C3=A1r?= X-Patchwork-Id: 13834088 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1C953145B0F; Sat, 12 Oct 2024 08:56:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728723375; cv=none; b=de+MPy0Hvm3xIqDa9ew4OYA1/a+oc6EtTrC8mEBGqHzm75VE8pqgefPELD9dYB8MZxRmWL0I2Rae21VG5p6Hw0v3egPfhxp8i4xAnkFHM0ulTGNQIzTTE8OwUQMmXFrlkZyJllbxr9HCszZUELipXuDBrnThlsFzW6gVsr9GPKA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728723375; c=relaxed/simple; bh=4Mvi152HGg7NjVSCBeQbBdl7JzN17DrdnTby1FxDoXA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=jK7p3FiL4MtmckAlH+1nx6qXuxBsrWd/jP3oSyF1GYrm9T8pJhgiTvha/xLe4J9yk2rh4QwjutcpHnpYU2yiDNzMWrPym9Jidg5FxG8thY4eQyiOXXkO+ebC/ZZynKDzP6FigZbQTqUHIU/QFax1QoZP7tamwoeZ8oDFTRnU+tU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=oedPwe3N; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="oedPwe3N" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 70F18C4CEC6; Sat, 12 Oct 2024 08:56:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1728723374; bh=4Mvi152HGg7NjVSCBeQbBdl7JzN17DrdnTby1FxDoXA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oedPwe3NbnLszqO/KBqHdCveHn+FqCn3Aj8HlPuRxTiK43HgQTshHi/aA0CtnuKRB XUjKfTIgzycBC1PyrsEE1HdXvL9zFS6+mGEDM96mc6G1OIBpxDrDtRV9FhVbHLzaJq C0e13BfuOgzVHm4r6QfbqgcUF6slnQ7hqAjCYsuYuRiVNte3liwj1m2d5YJFz9o2wq gw7CJduUcv8W/09rFBdn1R0ejBuf4/3aKbYR5zzOy3yjCDAVm8T1x/EAoihH1GGz1D oKlGD986jO/o4ptOsAnwWdq1MzFAOM8wYQPlCTFX1vpePZ8tPhoO83gyDom9tMcBXa PI+0HUMzmzATQ== Received: by pali.im (Postfix) id 2ABD97BD; Sat, 12 Oct 2024 10:56:09 +0200 (CEST) From: =?utf-8?q?Pali_Roh=C3=A1r?= To: Steve French , Paulo Alcantara , Ronnie Sahlberg Cc: linux-cifs@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 5/7] cifs: Improve guard for excluding $LXDEV xattr Date: Sat, 12 Oct 2024 10:56:08 +0200 Message-Id: <20241012085608.712-1-pali@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20241012085252.560-1-pali@kernel.org> References: <20241012085252.560-1-pali@kernel.org> Precedence: bulk X-Mailing-List: linux-cifs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 $LXDEV xattr is for storing block/char device's major and minor number. Change guard which excludes storing $LXDEV xattr to explicitly filter everything except block and char device. Current guard is opposite, which is currently correct but is less-safe. This change is required for adding support for creating WSL-style symlinks as symlinks also do not use device's major and minor numbers. Signed-off-by: Pali Rohár --- fs/smb/client/reparse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c index cd12704cae0c..50048dccc5ff 100644 --- a/fs/smb/client/reparse.c +++ b/fs/smb/client/reparse.c @@ -574,8 +574,8 @@ static int wsl_set_xattrs(struct inode *inode, umode_t _mode, memset(iov, 0, sizeof(*iov)); - /* Exclude $LXDEV xattr for sockets and fifos */ - if (S_ISSOCK(_mode) || S_ISFIFO(_mode)) + /* Exclude $LXDEV xattr for non-device files */ + if (!S_ISBLK(_mode) && !S_ISCHR(_mode)) num_xattrs = ARRAY_SIZE(xattrs) - 1; else num_xattrs = ARRAY_SIZE(xattrs); From patchwork Sat Oct 12 08:56:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Pali_Roh=C3=A1r?= X-Patchwork-Id: 13834089 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 122EC149C69; Sat, 12 Oct 2024 08:56:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728723381; cv=none; b=TWEEo6QcfofuEPYD49pUVqVh6M1rKhyM32JB3r4xTPUmkkwybdEecvPp1Hz+oMV1lOpkVo0jIOFxy/b7a2Dlw/QEslH8JAMafAcIqPelB6iV9RRFO6Yp10gAgVY5X4zsQR/cAzWbhqzNv7or3oTvD1Z1RRTtem/I0IY2PyYFtMI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728723381; c=relaxed/simple; bh=em0gXp35HaVAaQ5LVBaRb2iZikUKqU0WzDSVDtj5r0w=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=grj+SGOFRJmFsOv/73U0ihspFwycuMlQwr2Hhq8Mx5BsxbJvPTI3Ll1LupMZW49zmR7RjeTod2ELz9Of9wnKvZWmin8pRb3TYjRtGiRcIS6yaft+NR+h6os5eFtH1z5YQ4nJ5j22YfJCyavOWTogcdi1Ks4TndunlqbrZvW5xbQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=r6js35hf; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="r6js35hf" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7F032C4CEC6; Sat, 12 Oct 2024 08:56:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1728723380; bh=em0gXp35HaVAaQ5LVBaRb2iZikUKqU0WzDSVDtj5r0w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=r6js35hfTsCYBPvH0/JrwvBeU9mtHx7g+vztDxzxMmgalElDLnuA8SIIy3rEysGjY qPPrpmUX0pCTvkMaagKzsOoXUea1I+ByZ0rm/6JZq0/lC0+XiPvcGyGSBzm9IpwZhG qHvl7ZBmUzQX0RpKEQvc2w2k9M9aJ7ArTBan2p/E/rAnoeijuNu40ThN1dX/FM6O4+ TIRelGL66dyPX5FWiohaOtogIB4Mjl6s2FtXKwwdD4P/RurkzukCOeJzmgc2ITre51 WrYz6NtXksX6Uwkxp4BwPpzV6EzksEUW3q3pFMUc286vjH4s+90ujlzG5PAeF/VtiP 6tS5pbttJD3gw== Received: by pali.im (Postfix) id 3E4E57BD; Sat, 12 Oct 2024 10:56:15 +0200 (CEST) From: =?utf-8?q?Pali_Roh=C3=A1r?= To: Steve French , Paulo Alcantara , Ronnie Sahlberg Cc: linux-cifs@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 6/7] cifs: Add support for creating WSL-style symlinks Date: Sat, 12 Oct 2024 10:56:13 +0200 Message-Id: <20241012085613.729-1-pali@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20241012085252.560-1-pali@kernel.org> References: <20241012085252.560-1-pali@kernel.org> Precedence: bulk X-Mailing-List: linux-cifs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This change implements support for creating new symlink in WSL-style by Linux cifs client when -o reparse=wsl mount option is specified. WSL-style symlink uses reparse point with tag IO_REPARSE_TAG_LX_SYMLINK and symlink target location is stored in reparse buffer in UTF-8 encoding prefixed by 32-bit flags. Flags bits are unknown, but it was observed that WSL always sets flags to value 0x02000000. Do same in Linux cifs client. New symlinks would be created in WSL-style only in case the mount option -o reparse=wsl is specified, which is not by default. So default CIFS mounts are not affected by this change. Signed-off-by: Pali Rohár --- fs/smb/client/reparse.c | 65 +++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 12 deletions(-) diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c index 50048dccc5ff..b9a50eb03522 100644 --- a/fs/smb/client/reparse.c +++ b/fs/smb/client/reparse.c @@ -502,9 +502,17 @@ static int mknod_nfs(unsigned int xid, struct inode *inode, return rc; } -static int wsl_set_reparse_buf(struct reparse_data_buffer *buf, - mode_t mode, struct kvec *iov) +static int wsl_set_reparse_buf(struct reparse_data_buffer **buf, + mode_t mode, const char *symname, + struct cifs_sb_info *cifs_sb, + struct kvec *iov) { + struct reparse_wsl_symlink_data_buffer *symlink_buf; + __le16 *symname_utf16; + int symname_utf16_len; + int symname_utf8_maxlen; + int symname_utf8_len; + size_t buf_len; u32 tag; switch ((tag = reparse_mode_wsl_tag(mode))) { @@ -512,17 +520,45 @@ static int wsl_set_reparse_buf(struct reparse_data_buffer *buf, case IO_REPARSE_TAG_LX_CHR: case IO_REPARSE_TAG_LX_FIFO: case IO_REPARSE_TAG_AF_UNIX: + buf_len = sizeof(struct reparse_data_buffer); + *buf = kzalloc(buf_len, GFP_KERNEL); + if (!*buf) + return -ENOMEM; + break; + case IO_REPARSE_TAG_LX_SYMLINK: + symname_utf16 = cifs_strndup_to_utf16(symname, strlen(symname), + &symname_utf16_len, + cifs_sb->local_nls, + NO_MAP_UNI_RSVD); + if (!symname_utf16) + return -ENOMEM; + symname_utf8_maxlen = symname_utf16_len/2*3; + symlink_buf = kzalloc(sizeof(struct reparse_wsl_symlink_data_buffer) + + symname_utf8_maxlen, GFP_KERNEL); + if (!symlink_buf) { + kfree(symname_utf16); + return -ENOMEM; + } + /* Flag 0x02000000 is unknown, but all wsl symlinks have this value */ + symlink_buf->Flags = cpu_to_le32(0x02000000); + /* PathBuffer is in UTF-8 but without trailing null-term byte */ + symname_utf8_len = utf16s_to_utf8s(symname_utf16, symname_utf16_len/2, + UTF16_LITTLE_ENDIAN, + symlink_buf->PathBuffer, + symname_utf8_maxlen); + *buf = (struct reparse_data_buffer *)symlink_buf; + buf_len = sizeof(struct reparse_wsl_symlink_data_buffer) + symname_utf8_len; + kfree(symname_utf16); break; - case IO_REPARSE_TAG_LX_SYMLINK: /* TODO: add support for WSL symlinks */ default: return -EOPNOTSUPP; } - buf->ReparseTag = cpu_to_le32(tag); - buf->Reserved = 0; - buf->ReparseDataLength = 0; - iov->iov_base = buf; - iov->iov_len = sizeof(*buf); + (*buf)->ReparseTag = cpu_to_le32(tag); + (*buf)->Reserved = 0; + (*buf)->ReparseDataLength = cpu_to_le16(buf_len - sizeof(struct reparse_data_buffer)); + iov->iov_base = *buf; + iov->iov_len = buf_len; return 0; } @@ -614,25 +650,29 @@ static int mknod_wsl(unsigned int xid, struct inode *inode, const char *full_path, umode_t mode, dev_t dev, const char *symname) { + struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifs_open_info_data data; - struct reparse_data_buffer buf; + struct reparse_data_buffer *buf; struct smb2_create_ea_ctx *cc; struct inode *new; unsigned int len; struct kvec reparse_iov, xattr_iov; int rc; - rc = wsl_set_reparse_buf(&buf, mode, &reparse_iov); + rc = wsl_set_reparse_buf(&buf, mode, symname, cifs_sb, &reparse_iov); if (rc) return rc; rc = wsl_set_xattrs(inode, mode, dev, &xattr_iov); - if (rc) + if (rc) { + kfree(buf); return rc; + } data = (struct cifs_open_info_data) { .reparse_point = true, - .reparse = { .tag = le32_to_cpu(buf.ReparseTag), .buf = &buf, }, + .reparse = { .tag = le32_to_cpu(buf->ReparseTag), .buf = buf, }, + .symlink_target = kstrdup(symname, GFP_KERNEL), }; cc = xattr_iov.iov_base; @@ -649,6 +689,7 @@ static int mknod_wsl(unsigned int xid, struct inode *inode, rc = PTR_ERR(new); cifs_free_open_info(&data); kfree(xattr_iov.iov_base); + kfree(buf); return rc; } From patchwork Sat Oct 12 08:56:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Pali_Roh=C3=A1r?= X-Patchwork-Id: 13834090 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E0B4114A617; Sat, 12 Oct 2024 08:56:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728723391; cv=none; b=huS12W4v4Lbjo3C7SS2ZduUOP2p6ZWADMgRtMaaePAV+UVgdgtdekmFFatHVVmsEWfsD+hSHolWV1uzfZOe8iaIGKc0uaaX3RwJGobXYiUOorOUbpAsDjDWw2hD97cJNZpd28fh9KNIqN5n4/9/IInrpQcUwIY4nDxVaPebkPus= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728723391; c=relaxed/simple; bh=5x2dHJDCTdrmv146GBva78X3KSge+LDUkh4+nctDo0Q=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=LCwfLLX2LkLn+ZPUERt0mOfLzowTK6ippaQ6W1h1c0In99hQoORM2RmD9EiNJsahwlRSXoieJ14TeLx2V7+Ub1f553FM0mnRvUdlIFEYEfva6AUnLprL2CQxJ8rtB8jztD/Jm17ni8MuJsdw+cVBvqrgzuLXpZ00zD9Hpz/40xs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=HjMktIA7; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="HjMktIA7" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 27236C4CEC6; Sat, 12 Oct 2024 08:56:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1728723390; bh=5x2dHJDCTdrmv146GBva78X3KSge+LDUkh4+nctDo0Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HjMktIA78XloQkt0u19d3dvlfoNH1eImriPs+d8Hcym7jHjCN+wtaiJ9TgMQPndMo nxzSbow2Dww+B+2SYQCvPYkBxRb0rhtfR5SCJcLc18GFcmrRPbfXdZuudGDm7/tcJl pVM/PI3qNHVVRoCVHlttn9qHlkffMVGG95aN/gzilkAdaB1qNNdhpYIhC/3ZkJ9PfC x6Ion2o3XjT2l70t8EHWPfmFBxxuumjrcuNZ6M86EwPTwtTO1nJNrgiT1BITiYXwSs lxwiC1RuZldmLoAIqBcXE/xvjFxO77oUfsFptTDsTY2z4Qr3cRpvWFbFN+iVuBD5lO D9mHmoNRwpuug== Received: by pali.im (Postfix) id 52CAC7BD; Sat, 12 Oct 2024 10:56:21 +0200 (CEST) From: =?utf-8?q?Pali_Roh=C3=A1r?= To: Steve French , Paulo Alcantara , Ronnie Sahlberg Cc: linux-cifs@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 7/7] cifs: Validate content of WSL reparse point buffers Date: Sat, 12 Oct 2024 10:56:20 +0200 Message-Id: <20241012085620.746-1-pali@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20241012085252.560-1-pali@kernel.org> References: <20241012085252.560-1-pali@kernel.org> Precedence: bulk X-Mailing-List: linux-cifs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 WSL socket, fifo, char and block devices have empty reparse buffer. Validate the length of the reparse buffer. Signed-off-by: Pali Rohár --- fs/smb/client/reparse.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c index b9a50eb03522..3de91331c96c 100644 --- a/fs/smb/client/reparse.c +++ b/fs/smb/client/reparse.c @@ -1083,6 +1083,11 @@ int parse_reparse_point(struct reparse_data_buffer *buf, case IO_REPARSE_TAG_LX_FIFO: case IO_REPARSE_TAG_LX_CHR: case IO_REPARSE_TAG_LX_BLK: + if (le16_to_cpu(buf->ReparseDataLength) != 0) { + cifs_dbg(VFS, "srv returned malformed buffer for reparse point: 0x%08x\n", + le32_to_cpu(buf->ReparseTag)); + return -EIO; + } break; default: cifs_tcon_dbg(VFS | ONCE, "unhandled reparse tag: 0x%08x\n",