The kernel is globally removing the ambiguous 0-length and 1-element
arrays in favor of flexible arrays, so that we can gain both compile-time
and run-time array bounds checking[1].
Replace the trailing 1-element array with a flexible array in the
following structures:
struct smb2_err_rsp
struct smb2_tree_connect_req
struct smb2_negotiate_rsp
struct smb2_sess_setup_req
struct smb2_sess_setup_rsp
struct smb2_read_req
struct smb2_read_rsp
struct smb2_write_req
struct smb2_write_rsp
struct smb2_query_directory_req
struct smb2_query_directory_rsp
struct smb2_set_info_req
struct smb2_change_notify_rsp
struct smb2_create_rsp
struct smb2_query_info_req
struct smb2_query_info_rsp
Replace the trailing 1-element array with a flexible array, but leave
the existing structure padding:
struct smb2_file_all_info
struct smb2_lock_req
Adjust all related size calculations to match the changes to sizeof().
No machine code output differences are produced after these changes.
[1] For lots of details, see both:
https://docs.kernel.org/process/deprecated.html#zero-length-and-one-element-arrays
https://people.kernel.org/kees/bounded-flexible-arrays-in-c
Cc: Steve French <[email protected]>
Cc: Paulo Alcantara <[email protected]>
Cc: Ronnie Sahlberg <[email protected]>
Cc: Shyam Prasad N <[email protected]>
Cc: Tom Talpey <[email protected]>
Cc: Namjae Jeon <[email protected]>
Cc: Sergey Senozhatsky <[email protected]>
Cc: Gustavo A. R. Silva <[email protected]>
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Kees Cook <[email protected]>
---
fs/cifs/smb2file.c | 2 +-
fs/cifs/smb2misc.c | 2 +-
fs/cifs/smb2pdu.c | 16 +++++++--------
fs/cifs/smb2pdu.h | 2 +-
fs/ksmbd/smb2pdu.c | 6 ++----
fs/smbfs_common/smb2pdu.h | 42 ++++++++++++++++++++++-----------------
6 files changed, 36 insertions(+), 34 deletions(-)
diff --git a/fs/cifs/smb2file.c b/fs/cifs/smb2file.c
index 9f1dd04b555a..e0ee96d69d49 100644
--- a/fs/cifs/smb2file.c
+++ b/fs/cifs/smb2file.c
@@ -35,7 +35,7 @@ static struct smb2_symlink_err_rsp *symlink_data(const struct kvec *iov)
len = (u32)err->ErrorContextCount * (offsetof(struct smb2_error_context_rsp,
ErrorContextData) +
sizeof(struct smb2_symlink_err_rsp));
- if (le32_to_cpu(err->ByteCount) < len || iov->iov_len < len + sizeof(*err))
+ if (le32_to_cpu(err->ByteCount) < len || iov->iov_len < len + sizeof(*err) + 1)
return ERR_PTR(-EINVAL);
p = (struct smb2_error_context_rsp *)err->ErrorData;
diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c
index 572293c18e16..3935a60db5c3 100644
--- a/fs/cifs/smb2misc.c
+++ b/fs/cifs/smb2misc.c
@@ -113,7 +113,7 @@ static __u32 get_neg_ctxt_len(struct smb2_hdr *hdr, __u32 len,
} else if (nc_offset + 1 == non_ctxlen) {
cifs_dbg(FYI, "no SPNEGO security blob in negprot rsp\n");
size_of_pad_before_neg_ctxts = 0;
- } else if (non_ctxlen == SMB311_NEGPROT_BASE_SIZE)
+ } else if (non_ctxlen == SMB311_NEGPROT_BASE_SIZE + 1)
/* has padding, but no SPNEGO blob */
size_of_pad_before_neg_ctxts = nc_offset - non_ctxlen + 1;
else
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index c5cb2639b3f1..22145e7e08f6 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -1373,7 +1373,7 @@ SMB2_sess_sendreceive(struct SMB2_sess_data *sess_data)
/* Testing shows that buffer offset must be at location of Buffer[0] */
req->SecurityBufferOffset =
- cpu_to_le16(sizeof(struct smb2_sess_setup_req) - 1 /* pad */);
+ cpu_to_le16(sizeof(struct smb2_sess_setup_req));
req->SecurityBufferLength = cpu_to_le16(sess_data->iov[1].iov_len);
memset(&rqst, 0, sizeof(struct smb_rqst));
@@ -1892,8 +1892,7 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
iov[0].iov_len = total_len - 1;
/* Testing shows that buffer offset must be at location of Buffer[0] */
- req->PathOffset = cpu_to_le16(sizeof(struct smb2_tree_connect_req)
- - 1 /* pad */);
+ req->PathOffset = cpu_to_le16(sizeof(struct smb2_tree_connect_req));
req->PathLength = cpu_to_le16(unc_path_len - 2);
iov[1].iov_base = unc_path;
iov[1].iov_len = unc_path_len;
@@ -3773,7 +3772,7 @@ SMB2_change_notify(const unsigned int xid, struct cifs_tcon *tcon,
ses->Suid, (u8)watch_tree, completion_filter);
/* validate that notify information is plausible */
if ((rsp_iov.iov_base == NULL) ||
- (rsp_iov.iov_len < sizeof(struct smb2_change_notify_rsp)))
+ (rsp_iov.iov_len < sizeof(struct smb2_change_notify_rsp) + 1))
goto cnotify_exit;
smb_rsp = (struct smb2_change_notify_rsp *)rsp_iov.iov_base;
@@ -4966,7 +4965,7 @@ int SMB2_query_directory_init(const unsigned int xid,
memcpy(bufptr, &asteriks, len);
req->FileNameOffset =
- cpu_to_le16(sizeof(struct smb2_query_directory_req) - 1);
+ cpu_to_le16(sizeof(struct smb2_query_directory_req));
req->FileNameLength = cpu_to_le16(len);
/*
* BB could be 30 bytes or so longer if we used SMB2 specific
@@ -5162,8 +5161,7 @@ SMB2_set_info_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
req->VolatileFileId = volatile_fid;
req->AdditionalInformation = cpu_to_le32(additional_info);
- req->BufferOffset =
- cpu_to_le16(sizeof(struct smb2_set_info_req) - 1);
+ req->BufferOffset = cpu_to_le16(sizeof(struct smb2_set_info_req));
req->BufferLength = cpu_to_le32(*size);
memcpy(req->Buffer, *data, *size);
@@ -5397,9 +5395,9 @@ build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon,
req->VolatileFileId = volatile_fid;
/* 1 for pad */
req->InputBufferOffset =
- cpu_to_le16(sizeof(struct smb2_query_info_req) - 1);
+ cpu_to_le16(sizeof(struct smb2_query_info_req));
req->OutputBufferLength = cpu_to_le32(
- outbuf_len + sizeof(struct smb2_query_info_rsp) - 1);
+ outbuf_len + sizeof(struct smb2_query_info_rsp));
iov->iov_base = (char *)req;
iov->iov_len = total_len;
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h
index 1237bb86e93a..a5773a06aba8 100644
--- a/fs/cifs/smb2pdu.h
+++ b/fs/cifs/smb2pdu.h
@@ -57,7 +57,7 @@ struct smb2_rdma_crypto_transform {
#define COMPOUND_FID 0xFFFFFFFFFFFFFFFFULL
#define SMB2_SYMLINK_STRUCT_SIZE \
- (sizeof(struct smb2_err_rsp) - 1 + sizeof(struct smb2_symlink_err_rsp))
+ (sizeof(struct smb2_err_rsp) + sizeof(struct smb2_symlink_err_rsp))
#define SYMLINK_ERROR_TAG 0x4c4d5953
diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c
index 619857af0cc2..aef72077fc75 100644
--- a/fs/ksmbd/smb2pdu.c
+++ b/fs/ksmbd/smb2pdu.c
@@ -274,8 +274,7 @@ int init_smb2_neg_rsp(struct ksmbd_work *work)
le16_to_cpu(rsp->SecurityBufferOffset));
inc_rfc1001_len(work->response_buf,
sizeof(struct smb2_negotiate_rsp) -
- sizeof(struct smb2_hdr) - sizeof(rsp->Buffer) +
- AUTH_GSS_LENGTH);
+ sizeof(struct smb2_hdr) + AUTH_GSS_LENGTH);
rsp->SecurityMode = SMB2_NEGOTIATE_SIGNING_ENABLED_LE;
if (server_conf.signing == KSMBD_CONFIG_OPT_MANDATORY)
rsp->SecurityMode |= SMB2_NEGOTIATE_SIGNING_REQUIRED_LE;
@@ -1205,8 +1204,7 @@ int smb2_handle_negotiate(struct ksmbd_work *work)
ksmbd_copy_gss_neg_header((char *)(&rsp->hdr) +
le16_to_cpu(rsp->SecurityBufferOffset));
inc_rfc1001_len(work->response_buf, sizeof(struct smb2_negotiate_rsp) -
- sizeof(struct smb2_hdr) - sizeof(rsp->Buffer) +
- AUTH_GSS_LENGTH);
+ sizeof(struct smb2_hdr) + AUTH_GSS_LENGTH);
rsp->SecurityMode = SMB2_NEGOTIATE_SIGNING_ENABLED_LE;
conn->use_spnego = true;
diff --git a/fs/smbfs_common/smb2pdu.h b/fs/smbfs_common/smb2pdu.h
index 7d605db3bb3b..ace133cf6072 100644
--- a/fs/smbfs_common/smb2pdu.h
+++ b/fs/smbfs_common/smb2pdu.h
@@ -167,7 +167,7 @@ struct smb2_err_rsp {
__u8 ErrorContextCount;
__u8 Reserved;
__le32 ByteCount; /* even if zero, at least one byte follows */
- __u8 ErrorData[1]; /* variable length */
+ __u8 ErrorData[]; /* variable length */
} __packed;
#define SMB3_AES_CCM_NONCE 11
@@ -308,7 +308,7 @@ struct smb2_tree_connect_req {
__le16 Flags; /* Flags in SMB3.1.1 */
__le16 PathOffset;
__le16 PathLength;
- __u8 Buffer[1]; /* variable length */
+ __u8 Buffer[]; /* variable length */
} __packed;
/* Possible ShareType values */
@@ -595,7 +595,7 @@ struct smb2_negotiate_rsp {
__le16 SecurityBufferOffset;
__le16 SecurityBufferLength;
__le32 NegotiateContextOffset; /* Pre:SMB3.1.1 was reserved/ignored */
- __u8 Buffer[1]; /* variable length GSS security buffer */
+ __u8 Buffer[]; /* variable length GSS security buffer */
} __packed;
@@ -616,7 +616,7 @@ struct smb2_sess_setup_req {
__le16 SecurityBufferOffset;
__le16 SecurityBufferLength;
__le64 PreviousSessionId;
- __u8 Buffer[1]; /* variable length GSS security buffer */
+ __u8 Buffer[]; /* variable length GSS security buffer */
} __packed;
/* Currently defined SessionFlags */
@@ -633,7 +633,7 @@ struct smb2_sess_setup_rsp {
__le16 SessionFlags;
__le16 SecurityBufferOffset;
__le16 SecurityBufferLength;
- __u8 Buffer[1]; /* variable length GSS security buffer */
+ __u8 Buffer[]; /* variable length GSS security buffer */
} __packed;
@@ -715,7 +715,7 @@ struct smb2_read_req {
__le32 RemainingBytes;
__le16 ReadChannelInfoOffset;
__le16 ReadChannelInfoLength;
- __u8 Buffer[1];
+ __u8 Buffer[];
} __packed;
/* Read flags */
@@ -730,7 +730,7 @@ struct smb2_read_rsp {
__le32 DataLength;
__le32 DataRemaining;
__le32 Flags;
- __u8 Buffer[1];
+ __u8 Buffer[];
} __packed;
@@ -754,7 +754,7 @@ struct smb2_write_req {
__le16 WriteChannelInfoOffset;
__le16 WriteChannelInfoLength;
__le32 Flags;
- __u8 Buffer[1];
+ __u8 Buffer[];
} __packed;
struct smb2_write_rsp {
@@ -765,7 +765,7 @@ struct smb2_write_rsp {
__le32 DataLength;
__le32 DataRemaining;
__u32 Reserved2;
- __u8 Buffer[1];
+ __u8 Buffer[];
} __packed;
@@ -812,7 +812,10 @@ struct smb2_lock_req {
__u64 PersistentFileId;
__u64 VolatileFileId;
/* Followed by at least one */
- struct smb2_lock_element locks[1];
+ union {
+ struct smb2_lock_element lock;
+ DECLARE_FLEX_ARRAY(struct smb2_lock_element, locks);
+ };
} __packed;
struct smb2_lock_rsp {
@@ -866,7 +869,7 @@ struct smb2_query_directory_req {
__le16 FileNameOffset;
__le16 FileNameLength;
__le32 OutputBufferLength;
- __u8 Buffer[1];
+ __u8 Buffer[];
} __packed;
struct smb2_query_directory_rsp {
@@ -874,7 +877,7 @@ struct smb2_query_directory_rsp {
__le16 StructureSize; /* Must be 9 */
__le16 OutputBufferOffset;
__le32 OutputBufferLength;
- __u8 Buffer[1];
+ __u8 Buffer[];
} __packed;
/*
@@ -897,7 +900,7 @@ struct smb2_set_info_req {
__le32 AdditionalInformation;
__u64 PersistentFileId;
__u64 VolatileFileId;
- __u8 Buffer[1];
+ __u8 Buffer[];
} __packed;
struct smb2_set_info_rsp {
@@ -952,7 +955,7 @@ struct smb2_change_notify_rsp {
__le16 StructureSize; /* Must be 9 */
__le16 OutputBufferOffset;
__le32 OutputBufferLength;
- __u8 Buffer[1]; /* array of file notify structs */
+ __u8 Buffer[]; /* array of file notify structs */
} __packed;
@@ -1158,7 +1161,7 @@ struct smb2_create_rsp {
__u64 VolatileFileId;
__le32 CreateContextsOffset;
__le32 CreateContextsLength;
- __u8 Buffer[1];
+ __u8 Buffer[];
} __packed;
struct create_posix {
@@ -1501,7 +1504,7 @@ struct smb2_query_info_req {
__le32 Flags;
__u64 PersistentFileId;
__u64 VolatileFileId;
- __u8 Buffer[1];
+ __u8 Buffer[];
} __packed;
struct smb2_query_info_rsp {
@@ -1509,7 +1512,7 @@ struct smb2_query_info_rsp {
__le16 StructureSize; /* Must be 9 */
__le16 OutputBufferOffset;
__le32 OutputBufferLength;
- __u8 Buffer[1];
+ __u8 Buffer[];
} __packed;
/*
@@ -1570,7 +1573,10 @@ struct smb2_file_all_info { /* data block encoding of response to level 18 */
__le32 Mode;
__le32 AlignmentRequirement;
__le32 FileNameLength;
- char FileName[1];
+ union {
+ char __pad; /* Legacy structure padding */
+ DECLARE_FLEX_ARRAY(char, FileName);
+ };
} __packed; /* level 18 Query */
struct smb2_file_eof_info { /* encoding of request for level 10 */
--
2.34.1
This seems to have a lot of conflicts with for-next (doesn't apply).
Any chance you could rebase it on linux-next
On Tue, Feb 14, 2023 at 3:57 PM Kees Cook <[email protected]> wrote:
>
> The kernel is globally removing the ambiguous 0-length and 1-element
> arrays in favor of flexible arrays, so that we can gain both compile-time
> and run-time array bounds checking[1].
>
> Replace the trailing 1-element array with a flexible array in the
> following structures:
>
> struct smb2_err_rsp
> struct smb2_tree_connect_req
> struct smb2_negotiate_rsp
> struct smb2_sess_setup_req
> struct smb2_sess_setup_rsp
> struct smb2_read_req
> struct smb2_read_rsp
> struct smb2_write_req
> struct smb2_write_rsp
> struct smb2_query_directory_req
> struct smb2_query_directory_rsp
> struct smb2_set_info_req
> struct smb2_change_notify_rsp
> struct smb2_create_rsp
> struct smb2_query_info_req
> struct smb2_query_info_rsp
>
> Replace the trailing 1-element array with a flexible array, but leave
> the existing structure padding:
>
> struct smb2_file_all_info
> struct smb2_lock_req
>
> Adjust all related size calculations to match the changes to sizeof().
>
> No machine code output differences are produced after these changes.
>
> [1] For lots of details, see both:
> https://docs.kernel.org/process/deprecated.html#zero-length-and-one-element-arrays
> https://people.kernel.org/kees/bounded-flexible-arrays-in-c
>
> Cc: Steve French <[email protected]>
> Cc: Paulo Alcantara <[email protected]>
> Cc: Ronnie Sahlberg <[email protected]>
> Cc: Shyam Prasad N <[email protected]>
> Cc: Tom Talpey <[email protected]>
> Cc: Namjae Jeon <[email protected]>
> Cc: Sergey Senozhatsky <[email protected]>
> Cc: Gustavo A. R. Silva <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> Signed-off-by: Kees Cook <[email protected]>
> ---
> fs/cifs/smb2file.c | 2 +-
> fs/cifs/smb2misc.c | 2 +-
> fs/cifs/smb2pdu.c | 16 +++++++--------
> fs/cifs/smb2pdu.h | 2 +-
> fs/ksmbd/smb2pdu.c | 6 ++----
> fs/smbfs_common/smb2pdu.h | 42 ++++++++++++++++++++++-----------------
> 6 files changed, 36 insertions(+), 34 deletions(-)
>
> diff --git a/fs/cifs/smb2file.c b/fs/cifs/smb2file.c
> index 9f1dd04b555a..e0ee96d69d49 100644
> --- a/fs/cifs/smb2file.c
> +++ b/fs/cifs/smb2file.c
> @@ -35,7 +35,7 @@ static struct smb2_symlink_err_rsp *symlink_data(const struct kvec *iov)
> len = (u32)err->ErrorContextCount * (offsetof(struct smb2_error_context_rsp,
> ErrorContextData) +
> sizeof(struct smb2_symlink_err_rsp));
> - if (le32_to_cpu(err->ByteCount) < len || iov->iov_len < len + sizeof(*err))
> + if (le32_to_cpu(err->ByteCount) < len || iov->iov_len < len + sizeof(*err) + 1)
> return ERR_PTR(-EINVAL);
>
> p = (struct smb2_error_context_rsp *)err->ErrorData;
> diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c
> index 572293c18e16..3935a60db5c3 100644
> --- a/fs/cifs/smb2misc.c
> +++ b/fs/cifs/smb2misc.c
> @@ -113,7 +113,7 @@ static __u32 get_neg_ctxt_len(struct smb2_hdr *hdr, __u32 len,
> } else if (nc_offset + 1 == non_ctxlen) {
> cifs_dbg(FYI, "no SPNEGO security blob in negprot rsp\n");
> size_of_pad_before_neg_ctxts = 0;
> - } else if (non_ctxlen == SMB311_NEGPROT_BASE_SIZE)
> + } else if (non_ctxlen == SMB311_NEGPROT_BASE_SIZE + 1)
> /* has padding, but no SPNEGO blob */
> size_of_pad_before_neg_ctxts = nc_offset - non_ctxlen + 1;
> else
> diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
> index c5cb2639b3f1..22145e7e08f6 100644
> --- a/fs/cifs/smb2pdu.c
> +++ b/fs/cifs/smb2pdu.c
> @@ -1373,7 +1373,7 @@ SMB2_sess_sendreceive(struct SMB2_sess_data *sess_data)
>
> /* Testing shows that buffer offset must be at location of Buffer[0] */
> req->SecurityBufferOffset =
> - cpu_to_le16(sizeof(struct smb2_sess_setup_req) - 1 /* pad */);
> + cpu_to_le16(sizeof(struct smb2_sess_setup_req));
> req->SecurityBufferLength = cpu_to_le16(sess_data->iov[1].iov_len);
>
> memset(&rqst, 0, sizeof(struct smb_rqst));
> @@ -1892,8 +1892,7 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
> iov[0].iov_len = total_len - 1;
>
> /* Testing shows that buffer offset must be at location of Buffer[0] */
> - req->PathOffset = cpu_to_le16(sizeof(struct smb2_tree_connect_req)
> - - 1 /* pad */);
> + req->PathOffset = cpu_to_le16(sizeof(struct smb2_tree_connect_req));
> req->PathLength = cpu_to_le16(unc_path_len - 2);
> iov[1].iov_base = unc_path;
> iov[1].iov_len = unc_path_len;
> @@ -3773,7 +3772,7 @@ SMB2_change_notify(const unsigned int xid, struct cifs_tcon *tcon,
> ses->Suid, (u8)watch_tree, completion_filter);
> /* validate that notify information is plausible */
> if ((rsp_iov.iov_base == NULL) ||
> - (rsp_iov.iov_len < sizeof(struct smb2_change_notify_rsp)))
> + (rsp_iov.iov_len < sizeof(struct smb2_change_notify_rsp) + 1))
> goto cnotify_exit;
>
> smb_rsp = (struct smb2_change_notify_rsp *)rsp_iov.iov_base;
> @@ -4966,7 +4965,7 @@ int SMB2_query_directory_init(const unsigned int xid,
> memcpy(bufptr, &asteriks, len);
>
> req->FileNameOffset =
> - cpu_to_le16(sizeof(struct smb2_query_directory_req) - 1);
> + cpu_to_le16(sizeof(struct smb2_query_directory_req));
> req->FileNameLength = cpu_to_le16(len);
> /*
> * BB could be 30 bytes or so longer if we used SMB2 specific
> @@ -5162,8 +5161,7 @@ SMB2_set_info_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
> req->VolatileFileId = volatile_fid;
> req->AdditionalInformation = cpu_to_le32(additional_info);
>
> - req->BufferOffset =
> - cpu_to_le16(sizeof(struct smb2_set_info_req) - 1);
> + req->BufferOffset = cpu_to_le16(sizeof(struct smb2_set_info_req));
> req->BufferLength = cpu_to_le32(*size);
>
> memcpy(req->Buffer, *data, *size);
> @@ -5397,9 +5395,9 @@ build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon,
> req->VolatileFileId = volatile_fid;
> /* 1 for pad */
> req->InputBufferOffset =
> - cpu_to_le16(sizeof(struct smb2_query_info_req) - 1);
> + cpu_to_le16(sizeof(struct smb2_query_info_req));
> req->OutputBufferLength = cpu_to_le32(
> - outbuf_len + sizeof(struct smb2_query_info_rsp) - 1);
> + outbuf_len + sizeof(struct smb2_query_info_rsp));
>
> iov->iov_base = (char *)req;
> iov->iov_len = total_len;
> diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h
> index 1237bb86e93a..a5773a06aba8 100644
> --- a/fs/cifs/smb2pdu.h
> +++ b/fs/cifs/smb2pdu.h
> @@ -57,7 +57,7 @@ struct smb2_rdma_crypto_transform {
> #define COMPOUND_FID 0xFFFFFFFFFFFFFFFFULL
>
> #define SMB2_SYMLINK_STRUCT_SIZE \
> - (sizeof(struct smb2_err_rsp) - 1 + sizeof(struct smb2_symlink_err_rsp))
> + (sizeof(struct smb2_err_rsp) + sizeof(struct smb2_symlink_err_rsp))
>
> #define SYMLINK_ERROR_TAG 0x4c4d5953
>
> diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c
> index 619857af0cc2..aef72077fc75 100644
> --- a/fs/ksmbd/smb2pdu.c
> +++ b/fs/ksmbd/smb2pdu.c
> @@ -274,8 +274,7 @@ int init_smb2_neg_rsp(struct ksmbd_work *work)
> le16_to_cpu(rsp->SecurityBufferOffset));
> inc_rfc1001_len(work->response_buf,
> sizeof(struct smb2_negotiate_rsp) -
> - sizeof(struct smb2_hdr) - sizeof(rsp->Buffer) +
> - AUTH_GSS_LENGTH);
> + sizeof(struct smb2_hdr) + AUTH_GSS_LENGTH);
> rsp->SecurityMode = SMB2_NEGOTIATE_SIGNING_ENABLED_LE;
> if (server_conf.signing == KSMBD_CONFIG_OPT_MANDATORY)
> rsp->SecurityMode |= SMB2_NEGOTIATE_SIGNING_REQUIRED_LE;
> @@ -1205,8 +1204,7 @@ int smb2_handle_negotiate(struct ksmbd_work *work)
> ksmbd_copy_gss_neg_header((char *)(&rsp->hdr) +
> le16_to_cpu(rsp->SecurityBufferOffset));
> inc_rfc1001_len(work->response_buf, sizeof(struct smb2_negotiate_rsp) -
> - sizeof(struct smb2_hdr) - sizeof(rsp->Buffer) +
> - AUTH_GSS_LENGTH);
> + sizeof(struct smb2_hdr) + AUTH_GSS_LENGTH);
> rsp->SecurityMode = SMB2_NEGOTIATE_SIGNING_ENABLED_LE;
> conn->use_spnego = true;
>
> diff --git a/fs/smbfs_common/smb2pdu.h b/fs/smbfs_common/smb2pdu.h
> index 7d605db3bb3b..ace133cf6072 100644
> --- a/fs/smbfs_common/smb2pdu.h
> +++ b/fs/smbfs_common/smb2pdu.h
> @@ -167,7 +167,7 @@ struct smb2_err_rsp {
> __u8 ErrorContextCount;
> __u8 Reserved;
> __le32 ByteCount; /* even if zero, at least one byte follows */
> - __u8 ErrorData[1]; /* variable length */
> + __u8 ErrorData[]; /* variable length */
> } __packed;
>
> #define SMB3_AES_CCM_NONCE 11
> @@ -308,7 +308,7 @@ struct smb2_tree_connect_req {
> __le16 Flags; /* Flags in SMB3.1.1 */
> __le16 PathOffset;
> __le16 PathLength;
> - __u8 Buffer[1]; /* variable length */
> + __u8 Buffer[]; /* variable length */
> } __packed;
>
> /* Possible ShareType values */
> @@ -595,7 +595,7 @@ struct smb2_negotiate_rsp {
> __le16 SecurityBufferOffset;
> __le16 SecurityBufferLength;
> __le32 NegotiateContextOffset; /* Pre:SMB3.1.1 was reserved/ignored */
> - __u8 Buffer[1]; /* variable length GSS security buffer */
> + __u8 Buffer[]; /* variable length GSS security buffer */
> } __packed;
>
>
> @@ -616,7 +616,7 @@ struct smb2_sess_setup_req {
> __le16 SecurityBufferOffset;
> __le16 SecurityBufferLength;
> __le64 PreviousSessionId;
> - __u8 Buffer[1]; /* variable length GSS security buffer */
> + __u8 Buffer[]; /* variable length GSS security buffer */
> } __packed;
>
> /* Currently defined SessionFlags */
> @@ -633,7 +633,7 @@ struct smb2_sess_setup_rsp {
> __le16 SessionFlags;
> __le16 SecurityBufferOffset;
> __le16 SecurityBufferLength;
> - __u8 Buffer[1]; /* variable length GSS security buffer */
> + __u8 Buffer[]; /* variable length GSS security buffer */
> } __packed;
>
>
> @@ -715,7 +715,7 @@ struct smb2_read_req {
> __le32 RemainingBytes;
> __le16 ReadChannelInfoOffset;
> __le16 ReadChannelInfoLength;
> - __u8 Buffer[1];
> + __u8 Buffer[];
> } __packed;
>
> /* Read flags */
> @@ -730,7 +730,7 @@ struct smb2_read_rsp {
> __le32 DataLength;
> __le32 DataRemaining;
> __le32 Flags;
> - __u8 Buffer[1];
> + __u8 Buffer[];
> } __packed;
>
>
> @@ -754,7 +754,7 @@ struct smb2_write_req {
> __le16 WriteChannelInfoOffset;
> __le16 WriteChannelInfoLength;
> __le32 Flags;
> - __u8 Buffer[1];
> + __u8 Buffer[];
> } __packed;
>
> struct smb2_write_rsp {
> @@ -765,7 +765,7 @@ struct smb2_write_rsp {
> __le32 DataLength;
> __le32 DataRemaining;
> __u32 Reserved2;
> - __u8 Buffer[1];
> + __u8 Buffer[];
> } __packed;
>
>
> @@ -812,7 +812,10 @@ struct smb2_lock_req {
> __u64 PersistentFileId;
> __u64 VolatileFileId;
> /* Followed by at least one */
> - struct smb2_lock_element locks[1];
> + union {
> + struct smb2_lock_element lock;
> + DECLARE_FLEX_ARRAY(struct smb2_lock_element, locks);
> + };
> } __packed;
>
> struct smb2_lock_rsp {
> @@ -866,7 +869,7 @@ struct smb2_query_directory_req {
> __le16 FileNameOffset;
> __le16 FileNameLength;
> __le32 OutputBufferLength;
> - __u8 Buffer[1];
> + __u8 Buffer[];
> } __packed;
>
> struct smb2_query_directory_rsp {
> @@ -874,7 +877,7 @@ struct smb2_query_directory_rsp {
> __le16 StructureSize; /* Must be 9 */
> __le16 OutputBufferOffset;
> __le32 OutputBufferLength;
> - __u8 Buffer[1];
> + __u8 Buffer[];
> } __packed;
>
> /*
> @@ -897,7 +900,7 @@ struct smb2_set_info_req {
> __le32 AdditionalInformation;
> __u64 PersistentFileId;
> __u64 VolatileFileId;
> - __u8 Buffer[1];
> + __u8 Buffer[];
> } __packed;
>
> struct smb2_set_info_rsp {
> @@ -952,7 +955,7 @@ struct smb2_change_notify_rsp {
> __le16 StructureSize; /* Must be 9 */
> __le16 OutputBufferOffset;
> __le32 OutputBufferLength;
> - __u8 Buffer[1]; /* array of file notify structs */
> + __u8 Buffer[]; /* array of file notify structs */
> } __packed;
>
>
> @@ -1158,7 +1161,7 @@ struct smb2_create_rsp {
> __u64 VolatileFileId;
> __le32 CreateContextsOffset;
> __le32 CreateContextsLength;
> - __u8 Buffer[1];
> + __u8 Buffer[];
> } __packed;
>
> struct create_posix {
> @@ -1501,7 +1504,7 @@ struct smb2_query_info_req {
> __le32 Flags;
> __u64 PersistentFileId;
> __u64 VolatileFileId;
> - __u8 Buffer[1];
> + __u8 Buffer[];
> } __packed;
>
> struct smb2_query_info_rsp {
> @@ -1509,7 +1512,7 @@ struct smb2_query_info_rsp {
> __le16 StructureSize; /* Must be 9 */
> __le16 OutputBufferOffset;
> __le32 OutputBufferLength;
> - __u8 Buffer[1];
> + __u8 Buffer[];
> } __packed;
>
> /*
> @@ -1570,7 +1573,10 @@ struct smb2_file_all_info { /* data block encoding of response to level 18 */
> __le32 Mode;
> __le32 AlignmentRequirement;
> __le32 FileNameLength;
> - char FileName[1];
> + union {
> + char __pad; /* Legacy structure padding */
> + DECLARE_FLEX_ARRAY(char, FileName);
> + };
> } __packed; /* level 18 Query */
>
> struct smb2_file_eof_info { /* encoding of request for level 10 */
> --
> 2.34.1
>
--
Thanks,
Steve
On Tue, Feb 14, 2023 at 04:53:10PM -0600, Steve French wrote:
> This seems to have a lot of conflicts with for-next (doesn't apply).
> Any chance you could rebase it on linux-next
Ah, dang. I was working off of 20230203. I will rebase! Sorry for the
noise. :)
--
Kees Cook