From patchwork Fri Dec 15 20:29:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve French X-Patchwork-Id: 1876770 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=WeJdqwY1; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2604:1380:40f1:3f00::1; helo=sy.mirrors.kernel.org; envelope-from=linux-cifs+bounces-482-incoming=patchwork.ozlabs.org@vger.kernel.org; receiver=patchwork.ozlabs.org) Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org [IPv6:2604:1380:40f1:3f00::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4SsLSd2b81z23p3 for ; Sat, 16 Dec 2023 07:30:25 +1100 (AEDT) Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id E71BDB2306D for ; Fri, 15 Dec 2023 20:30:24 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id DC70643170; Fri, 15 Dec 2023 20:30:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="WeJdqwY1" X-Original-To: linux-cifs@vger.kernel.org Received: from mail-lf1-f47.google.com (mail-lf1-f47.google.com [209.85.167.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F19B946531 for ; Fri, 15 Dec 2023 20:30:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-lf1-f47.google.com with SMTP id 2adb3069b0e04-50e18689828so1223717e87.2 for ; Fri, 15 Dec 2023 12:30:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702672209; x=1703277009; darn=vger.kernel.org; h=cc:to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=Zfvato7xeFiiRvNUXWN/ZG7YE0odu4fB/nCSNlJWxNU=; b=WeJdqwY15Gu+UT2ToJm4tySufcYPkjS5Uk+fMEInRCTzmxylNGzJSrsqd30cokCkOh pAaKkfnF3czHUi2h3x/CuTfTpSlUx18pfURuCInnxUA+N+uzRhvcoUaAgZpmb9yOLiK1 MzyqOHt0Cv2farzUD12gJyNzHC1nXSFzdMjh99DNAc963UwSu1MqktkWqkXexLB5bTVJ mmM6GYWsmbluEugX5ivWHmAQCyoPXcIACd6y3kWWpehSECWMGnk9hGWJlP40VmrNWnra zqEzh7NM2cqgba/M0UwdE8EzS2FLqb3iQj0qP0xw77SnYUMt6ly7mrSzh/KzZNTOZknP aGSA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702672209; x=1703277009; h=cc:to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=Zfvato7xeFiiRvNUXWN/ZG7YE0odu4fB/nCSNlJWxNU=; b=v7hZg4QcJTOL3s27jZPfynMomj+KSLNuBCHn8fz3vTJ8pUAuSjUAB3RsRPC2afGpWo pFxopp5VF6TnNHth4tUSVbzwltSp6lJ5FJFhxN0hvu39ggJLuUAqCQLKWvhi+dyGSjPA 3xy+1fj0s5md9eJzhxA204g7Itbnk50r4p5gwW0woH/GKv4rFx51q1oP338lskp7IqTy nvKEIXiDKMxq++37VlMrXsxnbSOfeujO1fLussFpTyYPGb2h+2iGR85jPHz4SxklWGkM zHTXQoqetmubzh7cQ80acCLkvMvrcllfJNGeUgwT7HpyJ8K3g7iI7WQHgaRWvW7fi9x0 OJuA== X-Gm-Message-State: AOJu0Yx8ht/va87wLnk/weJik/tbkc57Sjo4fG17DXLUqjGOmJAHq2jE i7BaKp1fIWvsoOUE4xuvK/TFryQzS7/AAfRVuQ1Fw1jl5GQ= X-Google-Smtp-Source: AGHT+IGHgwJreU2XRtnoCdfsc0O3YKof+YjKoGUiKOeeFVWzOKnR443ZMEoJBIe1BvaeFbzgaHWt0WiyeCM0fAC82As= X-Received: by 2002:a05:6512:108d:b0:50b:d4c7:193c with SMTP id j13-20020a056512108d00b0050bd4c7193cmr7394365lfg.24.1702672208342; Fri, 15 Dec 2023 12:30:08 -0800 (PST) Precedence: bulk X-Mailing-List: linux-cifs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Steve French Date: Fri, 15 Dec 2023 14:29:56 -0600 Message-ID: Subject: [PATCHv2] smb3: allow files to be created with backslash in name To: CIFS , Paulo Alcantara Cc: samba-technical , Xiaoli Feng Updated patch (rebased to current for-next-next) Backslash is reserved in Windows (and SMB2/SMB3 by default) but allowed in POSIX so must be remapped when POSIX extensions are not enabled. The default mapping for SMB3 mounts ("SFM") allows mapping backslash (ie 0x5C in UTF8) to 0xF026 in UCS-2 (using the Unicode remapping range reserved for these characters), but this was not mapped by cifs.ko (unlike asterisk, greater than, question mark etc). This patch fixes that to allow creating files and directories with backslash in the file or directory name. Before this patch: touch "/mnt2/filewith\slash" would return touch: setting times of '/mnt2/filewith\slash': Invalid argument With the patch touch and mkdir with the backslash in the name works. This problem was found while debugging xfstest generic/453 https://bugzilla.kernel.org/show_bug.cgi?id=210961 Reported-by: Xiaoli Feng Closes: https://bugzilla.kernel.org/show_bug.cgi?id=210961 Signed-off-by: Steve French @Paulo Alcantara any thoughts if additional changes needed for DFS or prefixpaths? From ab1e7cf272e913d537b9600453bc8e5ccb26ee6d Mon Sep 17 00:00:00 2001 From: Steve French Date: Fri, 15 Dec 2023 14:25:02 -0600 Subject: [PATCH] smb3: allow files to be created with backslash in name Backslash is reserved in Windows (and SMB2/SMB3 by default) but allowed in POSIX so must be remapped when POSIX extensions are not enabled. The default mapping for SMB3 mounts ("SFM") allows mapping backslash (ie 0x5C in UTF8) to 0xF026 in UCS-2 (using the Unicode remapping range reserved for these characters), but this was not mapped by cifs.ko (unlike asterisk, greater than, question mark etc). This patch fixes that to allow creating files and directories with backslash in the file or directory name. Before this patch: touch "/mnt2/filewith\slash" would return touch: setting times of '/mnt2/filewith\slash': Invalid argument With the patch touch and mkdir with the backslash in the name works. This problem was found while debugging xfstest generic/453 https://bugzilla.kernel.org/show_bug.cgi?id=210961 Reported-by: Xiaoli Feng Closes: https://bugzilla.kernel.org/show_bug.cgi?id=210961 Signed-off-by: Steve French --- fs/smb/client/cifs_unicode.c | 15 ++++++++++----- fs/smb/client/cifs_unicode.h | 3 +++ fs/smb/client/cifsglob.h | 5 +---- fs/smb/client/dir.c | 18 ++++++++++++------ fs/smb/client/smb2misc.c | 18 +++++++++++------- 5 files changed, 37 insertions(+), 22 deletions(-) diff --git a/fs/smb/client/cifs_unicode.c b/fs/smb/client/cifs_unicode.c index 79d99a913944..02966853419f 100644 --- a/fs/smb/client/cifs_unicode.c +++ b/fs/smb/client/cifs_unicode.c @@ -96,6 +96,9 @@ convert_sfm_char(const __u16 src_char, char *target) case SFM_PERIOD: *target = '.'; break; + case SFM_SLASH: + *target = '\\'; + break; default: return false; } @@ -424,6 +427,9 @@ static __le16 convert_to_sfm_char(char src_char, bool end_of_string) case '|': dest_char = cpu_to_le16(SFM_PIPE); break; + case '\\': + dest_char = cpu_to_le16(SFM_SLASH); + break; case '.': if (end_of_string) dest_char = cpu_to_le16(SFM_PERIOD); @@ -436,6 +442,9 @@ static __le16 convert_to_sfm_char(char src_char, bool end_of_string) else dest_char = 0; break; + case '/': + dest_char = cpu_to_le16(UCS2_SLASH); + break; default: dest_char = 0; } @@ -495,11 +504,7 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen, dst_char = convert_to_sfm_char(src_char, end_of_string); } else dst_char = 0; - /* - * FIXME: We can not handle remapping backslash (UNI_SLASH) - * until all the calls to build_path_from_dentry are modified, - * as they use backslash as separator. - */ + if (dst_char == 0) { charlen = cp->char2uni(source + i, srclen - i, &tmp); dst_char = cpu_to_le16(tmp); diff --git a/fs/smb/client/cifs_unicode.h b/fs/smb/client/cifs_unicode.h index e137a0dfbbe9..4d414966f504 100644 --- a/fs/smb/client/cifs_unicode.h +++ b/fs/smb/client/cifs_unicode.h @@ -23,6 +23,9 @@ #include #include "../../nls/nls_ucs2_utils.h" +/* Unicode encoding of backslash character */ +#define UCS2_SLASH 0x005C + /* * Macs use an older "SFM" mapping of the symbols above. Fortunately it does * not conflict (although almost does) with the mapping above. diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index 55b3ce944022..e6f4a28275a8 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -1568,10 +1568,7 @@ CIFS_FILE_SB(struct file *file) static inline char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb) { - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) - return '/'; - else - return '\\'; + return '/'; } static inline void diff --git a/fs/smb/client/dir.c b/fs/smb/client/dir.c index 580a27a3a7e6..6c446b1210ba 100644 --- a/fs/smb/client/dir.c +++ b/fs/smb/client/dir.c @@ -160,12 +160,18 @@ check_name(struct dentry *direntry, struct cifs_tcon *tcon) le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength))) return -ENAMETOOLONG; - if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) { - for (i = 0; i < direntry->d_name.len; i++) { - if (direntry->d_name.name[i] == '\\') { - cifs_dbg(FYI, "Invalid file name\n"); - return -EINVAL; - } + /* + * SMB3.1.1 POSIX Extensions, CIFS Unix Extensions and SFM mappings + * allow \ in paths (or in latter case remaps \ to 0xF026) + */ + if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) || + (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SFM_CHR)) + return 0; + + for (i = 0; i < direntry->d_name.len; i++) { + if (direntry->d_name.name[i] == '\\') { + cifs_dbg(FYI, "Invalid file name\n"); + return -EINVAL; } } return 0; diff --git a/fs/smb/client/smb2misc.c b/fs/smb/client/smb2misc.c index e20b4354e703..0edc888ec3f8 100644 --- a/fs/smb/client/smb2misc.c +++ b/fs/smb/client/smb2misc.c @@ -469,13 +469,17 @@ cifs_convert_path_to_utf16(const char *from, struct cifs_sb_info *cifs_sb) if (from[0] == '\\') start_of_path = from + 1; - /* SMB311 POSIX extensions paths do not include leading slash */ - else if (cifs_sb_master_tlink(cifs_sb) && - cifs_sb_master_tcon(cifs_sb)->posix_extensions && - (from[0] == '/')) { - start_of_path = from + 1; - } else - start_of_path = from; + start_of_path = from; + /* + * Only old CIFS Unix extensions paths include leading slash + * Need to skip if for SMB3.1.1 POSIX Extensions and SMB1/2/3 + */ + if (from[0] == '/') { + if (((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == false) || + (cifs_sb_master_tlink(cifs_sb) && + (cifs_sb_master_tcon(cifs_sb)->posix_extensions))) + start_of_path = from + 1; + } to = cifs_strndup_to_utf16(start_of_path, PATH_MAX, &len, cifs_sb->local_nls, map_type); -- 2.40.1