lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250831123602.14037-24-pali@kernel.org>
Date: Sun, 31 Aug 2025 14:35:50 +0200
From: Pali Rohár <pali@...nel.org>
To: Steve French <sfrench@...ba.org>,
	Paulo Alcantara <pc@...guebit.com>,
	ronnie sahlberg <ronniesahlberg@...il.com>
Cc: linux-cifs@...r.kernel.org,
	linux-kernel@...r.kernel.org
Subject: [PATCH 23/35] cifs: Fix SMBLegacyOpen() function

Function SMBLegacyOpen() contains many FIXME comments, commented code and
missing handling of different flags.

Fix the FIXME comments, add missing handling of different flags and use
named macros as constants instead of magic numbers.

This is done according to MS-CIFS spec.

Signed-off-by: Pali Rohár <pali@...nel.org>
---
 fs/smb/client/cifspdu.h |  4 +++
 fs/smb/client/cifssmb.c | 73 +++++++++++++++++++++++++++--------------
 fs/smb/client/smb1ops.c |  4 ++-
 3 files changed, 55 insertions(+), 26 deletions(-)

diff --git a/fs/smb/client/cifspdu.h b/fs/smb/client/cifspdu.h
index d9cf7db0ac35..cb1f99d22dd7 100644
--- a/fs/smb/client/cifspdu.h
+++ b/fs/smb/client/cifspdu.h
@@ -137,6 +137,10 @@
  * Flags on SMB open
  */
 #define SMBOPEN_WRITE_THROUGH 0x4000
+#define SMBOPEN_DO_NOT_CACHE  0x1000
+#define SMBOPEN_RANDOM_ACCESS 0x0200
+#define SMBOPEN_SEQUENTIAL    0x0100
+#define SMBOPEN_DENY_COMPAT   0x0000
 #define SMBOPEN_DENY_ALL      0x0010
 #define SMBOPEN_DENY_WRITE    0x0020
 #define SMBOPEN_DENY_READ     0x0030
diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c
index 2a83fbc65395..c09713ebdc7c 100644
--- a/fs/smb/client/cifssmb.c
+++ b/fs/smb/client/cifssmb.c
@@ -1103,32 +1103,41 @@ SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
 		count = 0;      /* no pad */
 		name_len = copy_path_name(pSMB->fileName, fileName);
 	}
-	if (*pOplock & REQ_OPLOCK)
-		pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
-	else if (*pOplock & REQ_BATCHOPLOCK)
+
+	if (*pOplock & REQ_BATCHOPLOCK)
 		pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
+	else if (*pOplock & REQ_OPLOCK)
+		pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
+
+	if (pfile_info)
+		pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
 
-	pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
 	pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
-	pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
+	pSMB->Mode |= cpu_to_le16(SMBOPEN_DENY_NONE);
+
+	if (create_options & CREATE_WRITE_THROUGH)
+		pSMB->Mode |= cpu_to_le16(SMBOPEN_WRITE_THROUGH);
+
+	if (create_options & CREATE_NO_BUFFER)
+		pSMB->Mode |= cpu_to_le16(SMBOPEN_DO_NOT_CACHE);
+
+	if (create_options & CREATE_RANDOM_ACCESS)
+		pSMB->Mode |= cpu_to_le16(SMBOPEN_RANDOM_ACCESS);
+	else if (create_options & CREATE_SEQUENTIAL)
+		pSMB->Mode |= cpu_to_le16(SMBOPEN_SEQUENTIAL);
+
 	/* set file as system file if special file such as fifo,
 	 * socket, char or block and server expecting SFU style and
 	   no Unix extensions */
-
 	if (create_options & CREATE_OPTION_SPECIAL)
 		pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
-	else /* BB FIXME BB */
-		pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
+	else
+		pSMB->FileAttributes = cpu_to_le16(0);
 
 	if (create_options & CREATE_OPTION_READONLY)
 		pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
 
-	/* BB FIXME BB */
-/*	pSMB->CreateOptions = cpu_to_le32(create_options &
-						 CREATE_OPTIONS_MASK); */
-	/* BB FIXME END BB */
-
-	pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
+	pSMB->Sattr = cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_ARCHIVE);
 	pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
 	count += name_len;
 	inc_rfc1001_len(pSMB, count);
@@ -1139,24 +1148,38 @@ SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
 	cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
 	if (rc) {
 		cifs_dbg(FYI, "Error in Open = %d\n", rc);
+	} else if (pSMBr->hdr.WordCount != 15) {
+		rc = -EIO;
 	} else {
-	/* BB verify if wct == 15 */
-
-/*		*pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
+		if (!(pSMBr->Action & 0x8000))
+			*pOplock = OPLOCK_NONE;
+		else if (*pOplock & REQ_BATCHOPLOCK)
+			*pOplock = OPLOCK_BATCH;
+		else if (*pOplock & REQ_OPLOCK)
+			*pOplock = OPLOCK_EXCLUSIVE;
+		else
+			*pOplock = OPLOCK_NONE;
 
 		*netfid = pSMBr->Fid;   /* cifs fid stays in le */
+
 		/* Let caller know file was created so we can set the mode. */
 		/* Do we care about the CreateAction in any other cases? */
-	/* BB FIXME BB */
-/*		if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
-			*pOplock |= CIFS_CREATE_ACTION; */
-	/* BB FIXME END */
+		if ((pSMBr->Action & 0x0003) == 2)
+			*pOplock |= CIFS_CREATE_ACTION;
 
 		if (pfile_info) {
-			pfile_info->CreationTime = 0; /* BB convert CreateTime*/
-			pfile_info->LastAccessTime = 0; /* BB fixme */
-			pfile_info->LastWriteTime = 0; /* BB fixme */
-			pfile_info->ChangeTime = 0;  /* BB fixme */
+			struct timespec64 ts;
+			__u32 time = le32_to_cpu(pSMBr->LastWriteTime);
+
+			ts.tv_nsec = 0;
+			ts.tv_sec = time;
+			pfile_info->LastWriteTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
+			pfile_info->ChangeTime = pfile_info->LastWriteTime;
+			if (*pOplock & CIFS_CREATE_ACTION)
+				pfile_info->CreationTime = pfile_info->LastWriteTime;
+			else
+				pfile_info->CreationTime = 0;
+			pfile_info->LastAccessTime = 0;
 			pfile_info->Attributes =
 				cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
 			/* the file_info buf is endian converted by caller */
diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
index 6e928e90d72b..73d3dc83faa6 100644
--- a/fs/smb/client/smb1ops.c
+++ b/fs/smb/client/smb1ops.c
@@ -853,7 +853,9 @@ static int cifs_open_file(const unsigned int xid, struct cifs_open_parms *oparms
 				   oparms->disposition,
 				   oparms->desired_access,
 				   oparms->create_options,
-				   &oparms->fid->netfid, oplock, &fi,
+				   &oparms->fid->netfid,
+				   oplock,
+				   data ? &fi : NULL,
 				   oparms->cifs_sb->local_nls,
 				   cifs_remap(oparms->cifs_sb));
 	else
-- 
2.20.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ