From nobody Thu Dec 18 12:31:47 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (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 C4F192BEC27 for ; Wed, 6 Aug 2025 20:39:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754512797; cv=none; b=JFdhif2ULz9CR5IYH7B24Fj04aCY1RvUkiH1Y6MWJ2uixyoPJ0nGtxroHvJMxd/IKj7Bg4sYFKrg/iLkv8Ng5Nv6iD9RCN6wB2iBvkha/38M0x0VUHRsCMF1FSHpkxn487+RR0zicT5eK+kPS7+IMlf02cXxyhDdM0rwNQ6FQtI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754512797; c=relaxed/simple; bh=w29jphyP+fzgfrn42RwyyriQgd/HIEHbbYuoo/K4Biw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Q4igjcq+h6QWJe3lrcqZbg9nmLm+5k0NzB7mYGdt+LkrOrF57l71GrcerPZYFnJCJ6ilYzZ5oRDIadBP7ckD662PXxhBZofSNoXKTJ1LIp8sBxOrUP7giOeXlHMABu5hjBCl7y5RT3UY7ySsG7ht6YtAUoA7Yf2r/JC1i0w7zRA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=F9D5PsVD; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="F9D5PsVD" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1754512795; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=GAakLlrB9vWvfnHytlwwIHshMEgP8xr92t7+SCjWx94=; b=F9D5PsVDtyqjp5wN0gQ2fUNHDr3cjkzzU8fQA7P0Eu23rBB63Gpueqf+ZrtxQn2v8LyXSs NhlzgpTPe6D1UkgFdcHi6sW8hHn22LyUrSxjMFVsQ3uwHjzL2gzclBtYnnyPhsCKNfyOA8 lfAACgouyhJwkdGF9p7Rww7GeJfTsY8= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-491-TWS4fjsvPk-pp9br3XjYlA-1; Wed, 06 Aug 2025 16:39:49 -0400 X-MC-Unique: TWS4fjsvPk-pp9br3XjYlA-1 X-Mimecast-MFC-AGG-ID: TWS4fjsvPk-pp9br3XjYlA_1754512774 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 92BA41955D99; Wed, 6 Aug 2025 20:39:34 +0000 (UTC) Received: from warthog.procyon.org.com (unknown [10.42.28.17]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 852BF1956086; Wed, 6 Aug 2025 20:39:31 +0000 (UTC) From: David Howells To: Steve French Cc: David Howells , Paulo Alcantara , Shyam Prasad N , Tom Talpey , Wang Zhaolong , Stefan Metzmacher , Mina Almasry , linux-cifs@vger.kernel.org, linux-kernel@vger.kernel.org, netfs@lists.linux.dev, linux-fsdevel@vger.kernel.org Subject: [RFC PATCH 29/31] cifs: Rearrange Create request subfuncs Date: Wed, 6 Aug 2025 21:36:50 +0100 Message-ID: <20250806203705.2560493-30-dhowells@redhat.com> In-Reply-To: <20250806203705.2560493-1-dhowells@redhat.com> References: <20250806203705.2560493-1-dhowells@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 Content-Type: text/plain; charset="utf-8" Signed-off-by: David Howells cc: Steve French cc: Paulo Alcantara cc: Shyam Prasad N cc: Tom Talpey cc: linux-cifs@vger.kernel.org cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org --- fs/smb/client/smb2pdu.c | 357 ++++++++++++++++++++-------------------- 1 file changed, 178 insertions(+), 179 deletions(-) diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c index 9357c4953d9f..85486748dd7b 100644 --- a/fs/smb/client/smb2pdu.c +++ b/fs/smb/client/smb2pdu.c @@ -1228,61 +1228,6 @@ static int smb311_decode_neg_context(struct smb_mess= age *smb, return rc; } =20 -static struct create_posix * -create_posix_buf(umode_t mode) -{ - struct create_posix *buf; - - buf =3D kzalloc(sizeof(struct create_posix), - GFP_KERNEL); - if (!buf) - return NULL; - - buf->ccontext.DataOffset =3D - cpu_to_le16(offsetof(struct create_posix, Mode)); - buf->ccontext.DataLength =3D cpu_to_le32(4); - buf->ccontext.NameOffset =3D - cpu_to_le16(offsetof(struct create_posix, Name)); - buf->ccontext.NameLength =3D cpu_to_le16(16); - - /* SMB2_CREATE_TAG_POSIX is "0x93AD25509CB411E7B42383DE968BCD7C" */ - buf->Name[0] =3D 0x93; - buf->Name[1] =3D 0xAD; - buf->Name[2] =3D 0x25; - buf->Name[3] =3D 0x50; - buf->Name[4] =3D 0x9C; - buf->Name[5] =3D 0xB4; - buf->Name[6] =3D 0x11; - buf->Name[7] =3D 0xE7; - buf->Name[8] =3D 0xB4; - buf->Name[9] =3D 0x23; - buf->Name[10] =3D 0x83; - buf->Name[11] =3D 0xDE; - buf->Name[12] =3D 0x96; - buf->Name[13] =3D 0x8B; - buf->Name[14] =3D 0xCD; - buf->Name[15] =3D 0x7C; - buf->Mode =3D cpu_to_le32(mode); - cifs_dbg(FYI, "mode on posix create 0%o\n", mode); - return buf; -} - -static int -add_posix_context(struct kvec *iov, unsigned int *num_iovec, umode_t mode) -{ - unsigned int num =3D *num_iovec; - - iov[num].iov_base =3D create_posix_buf(mode); - if (mode =3D=3D ACL_NO_MODE) - cifs_dbg(FYI, "%s: no mode\n", __func__); - if (iov[num].iov_base =3D=3D NULL) - return -ENOMEM; - iov[num].iov_len =3D sizeof(struct create_posix); - *num_iovec =3D num + 1; - return 0; -} - - /* * * SMB2 Worker functions follow: @@ -2443,6 +2388,60 @@ SMB2_tdis(const unsigned int xid, struct cifs_tcon *= tcon) } =20 =20 +static struct create_posix * +create_posix_buf(umode_t mode) +{ + struct create_posix *buf; + + buf =3D kzalloc(sizeof(struct create_posix), + GFP_KERNEL); + if (!buf) + return NULL; + + buf->ccontext.DataOffset =3D + cpu_to_le16(offsetof(struct create_posix, Mode)); + buf->ccontext.DataLength =3D cpu_to_le32(4); + buf->ccontext.NameOffset =3D + cpu_to_le16(offsetof(struct create_posix, Name)); + buf->ccontext.NameLength =3D cpu_to_le16(16); + + /* SMB2_CREATE_TAG_POSIX is "0x93AD25509CB411E7B42383DE968BCD7C" */ + buf->Name[0] =3D 0x93; + buf->Name[1] =3D 0xAD; + buf->Name[2] =3D 0x25; + buf->Name[3] =3D 0x50; + buf->Name[4] =3D 0x9C; + buf->Name[5] =3D 0xB4; + buf->Name[6] =3D 0x11; + buf->Name[7] =3D 0xE7; + buf->Name[8] =3D 0xB4; + buf->Name[9] =3D 0x23; + buf->Name[10] =3D 0x83; + buf->Name[11] =3D 0xDE; + buf->Name[12] =3D 0x96; + buf->Name[13] =3D 0x8B; + buf->Name[14] =3D 0xCD; + buf->Name[15] =3D 0x7C; + buf->Mode =3D cpu_to_le32(mode); + cifs_dbg(FYI, "mode on posix create 0%o\n", mode); + return buf; +} + +static int +add_posix_context(struct kvec *iov, unsigned int *num_iovec, umode_t mode) +{ + unsigned int num =3D *num_iovec; + + iov[num].iov_base =3D create_posix_buf(mode); + if (mode =3D=3D ACL_NO_MODE) + cifs_dbg(FYI, "%s: no mode\n", __func__); + if (iov[num].iov_base =3D=3D NULL) + return -ENOMEM; + iov[num].iov_len =3D sizeof(struct create_posix); + *num_iovec =3D num + 1; + return 0; +} + static struct create_durable * create_durable_buf(void) { @@ -2491,130 +2490,6 @@ create_reconnect_durable_buf(struct cifs_fid *fid) return buf; } =20 -static void -parse_query_id_ctxt(struct create_context *cc, struct smb2_file_all_info *= buf) -{ - struct create_disk_id_rsp *pdisk_id =3D (struct create_disk_id_rsp *)cc; - - cifs_dbg(FYI, "parse query id context 0x%llx 0x%llx\n", - pdisk_id->DiskFileId, pdisk_id->VolumeId); - buf->IndexNumber =3D pdisk_id->DiskFileId; -} - -static void -parse_posix_ctxt(struct create_context *cc, struct smb2_file_all_info *inf= o, - struct create_posix_rsp *posix) -{ - int sid_len; - u8 *beg =3D (u8 *)cc + le16_to_cpu(cc->DataOffset); - u8 *end =3D beg + le32_to_cpu(cc->DataLength); - u8 *sid; - - memset(posix, 0, sizeof(*posix)); - - posix->nlink =3D le32_to_cpu(*(__le32 *)(beg + 0)); - posix->reparse_tag =3D le32_to_cpu(*(__le32 *)(beg + 4)); - posix->mode =3D le32_to_cpu(*(__le32 *)(beg + 8)); - - sid =3D beg + 12; - sid_len =3D posix_info_sid_size(sid, end); - if (sid_len < 0) { - cifs_dbg(VFS, "bad owner sid in posix create response\n"); - return; - } - memcpy(&posix->owner, sid, sid_len); - - sid =3D sid + sid_len; - sid_len =3D posix_info_sid_size(sid, end); - if (sid_len < 0) { - cifs_dbg(VFS, "bad group sid in posix create response\n"); - return; - } - memcpy(&posix->group, sid, sid_len); - - cifs_dbg(FYI, "nlink=3D%d mode=3D%o reparse_tag=3D%x\n", - posix->nlink, posix->mode, posix->reparse_tag); -} - -int smb2_parse_contexts(struct TCP_Server_Info *server, - struct kvec *rsp_iov, - __u16 *epoch, - char *lease_key, __u8 *oplock, - struct smb2_file_all_info *buf, - struct create_posix_rsp *posix) -{ - struct smb2_create_rsp *rsp =3D rsp_iov->iov_base; - struct create_context *cc; - size_t rem, off, len; - size_t doff, dlen; - size_t noff, nlen; - char *name; - static const char smb3_create_tag_posix[] =3D { - 0x93, 0xAD, 0x25, 0x50, 0x9C, - 0xB4, 0x11, 0xE7, 0xB4, 0x23, 0x83, - 0xDE, 0x96, 0x8B, 0xCD, 0x7C - }; - - *oplock =3D 0; - - off =3D le32_to_cpu(rsp->CreateContextsOffset); - rem =3D le32_to_cpu(rsp->CreateContextsLength); - if (check_add_overflow(off, rem, &len) || len > rsp_iov->iov_len) - return -EINVAL; - cc =3D (struct create_context *)((u8 *)rsp + off); - - /* Initialize inode number to 0 in case no valid data in qfid context */ - if (buf) - buf->IndexNumber =3D 0; - - while (rem >=3D sizeof(*cc)) { - doff =3D le16_to_cpu(cc->DataOffset); - dlen =3D le32_to_cpu(cc->DataLength); - if (check_add_overflow(doff, dlen, &len) || len > rem) - return -EINVAL; - - noff =3D le16_to_cpu(cc->NameOffset); - nlen =3D le16_to_cpu(cc->NameLength); - if (noff + nlen > doff) - return -EINVAL; - - name =3D (char *)cc + noff; - switch (nlen) { - case 4: - if (!strncmp(name, SMB2_CREATE_REQUEST_LEASE, 4)) { - *oplock =3D server->ops->parse_lease_buf(cc, epoch, - lease_key); - } else if (buf && - !strncmp(name, SMB2_CREATE_QUERY_ON_DISK_ID, 4)) { - parse_query_id_ctxt(cc, buf); - } - break; - case 16: - if (posix && !memcmp(name, smb3_create_tag_posix, 16)) - parse_posix_ctxt(cc, buf, posix); - break; - default: - cifs_dbg(FYI, "%s: unhandled context (nlen=3D%zu dlen=3D%zu)\n", - __func__, nlen, dlen); - if (IS_ENABLED(CONFIG_CIFS_DEBUG2)) - cifs_dump_mem("context data: ", cc, dlen); - break; - } - - off =3D le32_to_cpu(cc->Next); - if (!off) - break; - if (check_sub_overflow(rem, off, &rem)) - return -EINVAL; - cc =3D (struct create_context *)((u8 *)cc + off); - } - - if (rsp->OplockLevel !=3D SMB2_OPLOCK_LEVEL_LEASE) - *oplock =3D rsp->OplockLevel; - - return 0; -} - static int add_lease_context(struct TCP_Server_Info *server, struct smb2_create_req *req, @@ -3383,6 +3258,130 @@ SMB2_open_init(struct cifs_tcon *tcon, struct TCP_S= erver_Info *server, return 0; } =20 +static void +parse_query_id_ctxt(struct create_context *cc, struct smb2_file_all_info *= buf) +{ + struct create_disk_id_rsp *pdisk_id =3D (struct create_disk_id_rsp *)cc; + + cifs_dbg(FYI, "parse query id context 0x%llx 0x%llx\n", + pdisk_id->DiskFileId, pdisk_id->VolumeId); + buf->IndexNumber =3D pdisk_id->DiskFileId; +} + +static void +parse_posix_ctxt(struct create_context *cc, struct smb2_file_all_info *inf= o, + struct create_posix_rsp *posix) +{ + int sid_len; + u8 *beg =3D (u8 *)cc + le16_to_cpu(cc->DataOffset); + u8 *end =3D beg + le32_to_cpu(cc->DataLength); + u8 *sid; + + memset(posix, 0, sizeof(*posix)); + + posix->nlink =3D le32_to_cpu(*(__le32 *)(beg + 0)); + posix->reparse_tag =3D le32_to_cpu(*(__le32 *)(beg + 4)); + posix->mode =3D le32_to_cpu(*(__le32 *)(beg + 8)); + + sid =3D beg + 12; + sid_len =3D posix_info_sid_size(sid, end); + if (sid_len < 0) { + cifs_dbg(VFS, "bad owner sid in posix create response\n"); + return; + } + memcpy(&posix->owner, sid, sid_len); + + sid =3D sid + sid_len; + sid_len =3D posix_info_sid_size(sid, end); + if (sid_len < 0) { + cifs_dbg(VFS, "bad group sid in posix create response\n"); + return; + } + memcpy(&posix->group, sid, sid_len); + + cifs_dbg(FYI, "nlink=3D%d mode=3D%o reparse_tag=3D%x\n", + posix->nlink, posix->mode, posix->reparse_tag); +} + +int smb2_parse_contexts(struct TCP_Server_Info *server, + struct kvec *rsp_iov, + __u16 *epoch, + char *lease_key, __u8 *oplock, + struct smb2_file_all_info *buf, + struct create_posix_rsp *posix) +{ + struct smb2_create_rsp *rsp =3D rsp_iov->iov_base; + struct create_context *cc; + size_t rem, off, len; + size_t doff, dlen; + size_t noff, nlen; + char *name; + static const char smb3_create_tag_posix[] =3D { + 0x93, 0xAD, 0x25, 0x50, 0x9C, + 0xB4, 0x11, 0xE7, 0xB4, 0x23, 0x83, + 0xDE, 0x96, 0x8B, 0xCD, 0x7C + }; + + *oplock =3D 0; + + off =3D le32_to_cpu(rsp->CreateContextsOffset); + rem =3D le32_to_cpu(rsp->CreateContextsLength); + if (check_add_overflow(off, rem, &len) || len > rsp_iov->iov_len) + return -EINVAL; + cc =3D (struct create_context *)((u8 *)rsp + off); + + /* Initialize inode number to 0 in case no valid data in qfid context */ + if (buf) + buf->IndexNumber =3D 0; + + while (rem >=3D sizeof(*cc)) { + doff =3D le16_to_cpu(cc->DataOffset); + dlen =3D le32_to_cpu(cc->DataLength); + if (check_add_overflow(doff, dlen, &len) || len > rem) + return -EINVAL; + + noff =3D le16_to_cpu(cc->NameOffset); + nlen =3D le16_to_cpu(cc->NameLength); + if (noff + nlen > doff) + return -EINVAL; + + name =3D (char *)cc + noff; + switch (nlen) { + case 4: + if (!strncmp(name, SMB2_CREATE_REQUEST_LEASE, 4)) { + *oplock =3D server->ops->parse_lease_buf(cc, epoch, + lease_key); + } else if (buf && + !strncmp(name, SMB2_CREATE_QUERY_ON_DISK_ID, 4)) { + parse_query_id_ctxt(cc, buf); + } + break; + case 16: + if (posix && !memcmp(name, smb3_create_tag_posix, 16)) + parse_posix_ctxt(cc, buf, posix); + break; + default: + cifs_dbg(FYI, "%s: unhandled context (nlen=3D%zu dlen=3D%zu)\n", + __func__, nlen, dlen); + if (IS_ENABLED(CONFIG_CIFS_DEBUG2)) + cifs_dump_mem("context data: ", cc, dlen); + break; + } + + off =3D le32_to_cpu(cc->Next); + if (!off) + break; + if (check_sub_overflow(rem, off, &rem)) + return -EINVAL; + cc =3D (struct create_context *)((u8 *)cc + off); + } + + if (rsp->OplockLevel !=3D SMB2_OPLOCK_LEVEL_LEASE) + *oplock =3D rsp->OplockLevel; + + return 0; +} + /* rq_iov[0] is the request and is released by cifs_small_buf_release(). * All other vectors are freed by kfree(). */