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@xxxxxxx> --- 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 --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; -- 2.35.3