Message ID | 20250118123528.3342182-1-buaajxlj@163.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | [v2] smb: client: correctly handle ErrorContextData as a flexible array | expand |
updated patch in for-next now On Sat, Jan 18, 2025 at 6:37 AM Liang Jie <buaajxlj@163.com> wrote: > > From: Liang Jie <liangjie@lixiang.com> > > The `smb2_symlink_err_rsp` structure was previously defined with > `ErrorContextData` as a single `__u8` byte. However, the `ErrorContextData` > field is intended to be a variable-length array based on `ErrorDataLength`. > This mismatch leads to incorrect pointer arithmetic and potential memory > access issues when processing error contexts. > > Updates the `ErrorContextData` field to be a flexible array > (`__u8 ErrorContextData[]`). Additionally, it modifies the corresponding > casts in the `symlink_data()` function to properly handle the flexible > array, ensuring correct memory calculations and data handling. > > These changes improve the robustness of SMB2 symlink error processing. > > Signed-off-by: Liang Jie <liangjie@lixiang.com> > Suggested-by: Tom Talpey <tom@talpey.com> > --- > > Changes in v2: > - Add the __counted_by_le attribute to reference the ErrorDataLength protocol field. > - Link to v1: https://lore.kernel.org/all/20250116072948.682402-1-buaajxlj@163.com/ > > fs/smb/client/smb2file.c | 4 ++-- > fs/smb/client/smb2pdu.h | 2 +- > 2 files changed, 3 insertions(+), 3 deletions(-) > > diff --git a/fs/smb/client/smb2file.c b/fs/smb/client/smb2file.c > index e836bc2193dd..9ec44eab8dbc 100644 > --- a/fs/smb/client/smb2file.c > +++ b/fs/smb/client/smb2file.c > @@ -42,14 +42,14 @@ static struct smb2_symlink_err_rsp *symlink_data(const struct kvec *iov) > end = (struct smb2_error_context_rsp *)((u8 *)err + iov->iov_len); > do { > if (le32_to_cpu(p->ErrorId) == SMB2_ERROR_ID_DEFAULT) { > - sym = (struct smb2_symlink_err_rsp *)&p->ErrorContextData; > + sym = (struct smb2_symlink_err_rsp *)p->ErrorContextData; > break; > } > cifs_dbg(FYI, "%s: skipping unhandled error context: 0x%x\n", > __func__, le32_to_cpu(p->ErrorId)); > > len = ALIGN(le32_to_cpu(p->ErrorDataLength), 8); > - p = (struct smb2_error_context_rsp *)((u8 *)&p->ErrorContextData + len); > + p = (struct smb2_error_context_rsp *)(p->ErrorContextData + len); > } while (p < end); > } else if (le32_to_cpu(err->ByteCount) >= sizeof(*sym) && > iov->iov_len >= SMB2_SYMLINK_STRUCT_SIZE) { > diff --git a/fs/smb/client/smb2pdu.h b/fs/smb/client/smb2pdu.h > index 076d9e83e1a0..3c09a58dfd07 100644 > --- a/fs/smb/client/smb2pdu.h > +++ b/fs/smb/client/smb2pdu.h > @@ -79,7 +79,7 @@ struct smb2_symlink_err_rsp { > struct smb2_error_context_rsp { > __le32 ErrorDataLength; > __le32 ErrorId; > - __u8 ErrorContextData; /* ErrorDataLength long array */ > + __u8 ErrorContextData[] __counted_by_le(ErrorDataLength); > } __packed; > > /* ErrorId values */ > -- > 2.25.1 > > -- Thanks, Steve
diff --git a/fs/smb/client/smb2file.c b/fs/smb/client/smb2file.c index e836bc2193dd..9ec44eab8dbc 100644 --- a/fs/smb/client/smb2file.c +++ b/fs/smb/client/smb2file.c @@ -42,14 +42,14 @@ static struct smb2_symlink_err_rsp *symlink_data(const struct kvec *iov) end = (struct smb2_error_context_rsp *)((u8 *)err + iov->iov_len); do { if (le32_to_cpu(p->ErrorId) == SMB2_ERROR_ID_DEFAULT) { - sym = (struct smb2_symlink_err_rsp *)&p->ErrorContextData; + sym = (struct smb2_symlink_err_rsp *)p->ErrorContextData; break; } cifs_dbg(FYI, "%s: skipping unhandled error context: 0x%x\n", __func__, le32_to_cpu(p->ErrorId)); len = ALIGN(le32_to_cpu(p->ErrorDataLength), 8); - p = (struct smb2_error_context_rsp *)((u8 *)&p->ErrorContextData + len); + p = (struct smb2_error_context_rsp *)(p->ErrorContextData + len); } while (p < end); } else if (le32_to_cpu(err->ByteCount) >= sizeof(*sym) && iov->iov_len >= SMB2_SYMLINK_STRUCT_SIZE) { diff --git a/fs/smb/client/smb2pdu.h b/fs/smb/client/smb2pdu.h index 076d9e83e1a0..3c09a58dfd07 100644 --- a/fs/smb/client/smb2pdu.h +++ b/fs/smb/client/smb2pdu.h @@ -79,7 +79,7 @@ struct smb2_symlink_err_rsp { struct smb2_error_context_rsp { __le32 ErrorDataLength; __le32 ErrorId; - __u8 ErrorContextData; /* ErrorDataLength long array */ + __u8 ErrorContextData[] __counted_by_le(ErrorDataLength); } __packed; /* ErrorId values */