diff mbox series

[v4,8/8] cifs: use MAX_CIFS_SMALL_BUFFER_SIZE-8 as padding buffer

Message ID 20220929175655.6906-4-ematsumiya@suse.de
State New
Headers show
Series None | expand

Commit Message

Enzo Matsumiya Sept. 29, 2022, 5:56 p.m. UTC
AES-GMAC is more picky about buffers locality, alignment, and size, so
we can't use a stack-allocated buffer as padding (smb2_padding).

This commit drops smb2_padding and "reserves" the 8 last bytes of each
small buffer, which are slab-allocated, as the padding buffer space.

Introduce SMB2_PADDING_BUF(buf) macro to easily grab the padding buffer.
For now, only used by smb2_set_next_command().

Signed-off-by: Enzo Matsumiya <ematsumiya@suse.de>
---
v4:
  - move SMB2_PADDING_BUF to smb2glob.h
  - check if iov is SMB2_PADDING_BUF in the free functions where
    smb2_padding was previously used (pointed out by metze)

 fs/cifs/smb2glob.h | 5 +++++
 fs/cifs/smb2ops.c  | 4 +---
 fs/cifs/smb2pdu.c  | 9 +++++++--
 fs/cifs/smb2pdu.h  | 2 --
 4 files changed, 13 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/fs/cifs/smb2glob.h b/fs/cifs/smb2glob.h
index 3a3e81b1b8cb..f3dd39c9be97 100644
--- a/fs/cifs/smb2glob.h
+++ b/fs/cifs/smb2glob.h
@@ -41,6 +41,11 @@ 
 #define END_OF_CHAIN 4
 #define RELATED_REQUEST 8
 
+/*
+ * Use the last 8 bytes of the small buf as the padding buffer, when necessary
+ */
+#define SMB2_PADDING_BUF(buf) (buf + MAX_CIFS_SMALL_BUFFER_SIZE - 8)
+
 static inline const char *smb2_signing_algo_str(u16 algo)
 {
 	switch (algo) {
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index e08065103b61..571961ca61ff 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -2323,8 +2323,6 @@  smb2_set_related(struct smb_rqst *rqst)
 	shdr->Flags |= SMB2_FLAGS_RELATED_OPERATIONS;
 }
 
-char smb2_padding[7] = {0, 0, 0, 0, 0, 0, 0};
-
 void
 smb2_set_next_command(struct cifs_tcon *tcon, struct smb_rqst *rqst)
 {
@@ -2352,7 +2350,7 @@  smb2_set_next_command(struct cifs_tcon *tcon, struct smb_rqst *rqst)
 		 * If we do not have encryption then we can just add an extra
 		 * iov for the padding.
 		 */
-		rqst->rq_iov[rqst->rq_nvec].iov_base = smb2_padding;
+		rqst->rq_iov[rqst->rq_nvec].iov_base = SMB2_PADDING_BUF(rqst->rq_iov[0].iov_base);
 		rqst->rq_iov[rqst->rq_nvec].iov_len = num_padding;
 		rqst->rq_nvec++;
 		len += num_padding;
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 97dac970cd52..a4da04472377 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -362,6 +362,9 @@  fill_small_buf(__le16 smb2_command, struct cifs_tcon *tcon,
 	/*
 	 * smaller than SMALL_BUFFER_SIZE but bigger than fixed area of
 	 * largest operations (Create)
+	 *
+	 * Note that the last 8 bytes of the small buffer are reserved for padding when required
+	 * (see SMB2_PADDING_BUF in smb2ops.c)
 	 */
 	memset(buf, 0, 256);
 
@@ -2992,7 +2995,8 @@  SMB2_open_free(struct smb_rqst *rqst)
 	if (rqst && rqst->rq_iov) {
 		cifs_small_buf_release(rqst->rq_iov[0].iov_base);
 		for (i = 1; i < rqst->rq_nvec; i++)
-			if (rqst->rq_iov[i].iov_base != smb2_padding)
+			if (rqst->rq_iov[i].iov_base !=
+			    SMB2_PADDING_BUF(rqst->rq_iov[0].iov_base))
 				kfree(rqst->rq_iov[i].iov_base);
 	}
 }
@@ -3186,7 +3190,8 @@  SMB2_ioctl_free(struct smb_rqst *rqst)
 	if (rqst && rqst->rq_iov) {
 		cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */
 		for (i = 1; i < rqst->rq_nvec; i++)
-			if (rqst->rq_iov[i].iov_base != smb2_padding)
+			if (rqst->rq_iov[i].iov_base !=
+			    SMB2_PADDING_BUF(rqst->rq_iov[0].iov_base))
 				kfree(rqst->rq_iov[i].iov_base);
 	}
 }
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h
index f57881b8464f..689973a3acbb 100644
--- a/fs/cifs/smb2pdu.h
+++ b/fs/cifs/smb2pdu.h
@@ -371,8 +371,6 @@  struct smb2_file_id_extd_directory_info {
 	char FileName[1];
 } __packed; /* level 60 */
 
-extern char smb2_padding[7];
-
 /* equivalent of the contents of SMB3.1.1 POSIX open context response */
 struct create_posix_rsp {
 	u32 nlink;