Message ID | 20220721032158.31479-1-xiaolinkui@kylinos.cn |
---|---|
State | New |
Headers | show |
Series | wireless: ath6kl: fix out of bound from length. | expand |
On Thu, Jul 21, 2022 at 11:21:58AM +0800, xiaolinkui wrote: > From: Linkui Xiao <xiaolinkui@kylinos.cn> > > If length from debug_buf.length is 4294967293 (0xfffffffd), the result of > ALIGN(size, 4) will be 0. > > length = ALIGN(length, 4); > > In case of length == 4294967293 after four-byte aligned access, length will > become 0. > > ret = ath6kl_diag_read(ar, address, buf, length); > > will fail to read. It looks like "length" is untrustworthy. Generally, I kind of distrust all endian data by default, but I dug a bit deeper and I don't trust it. Unfortunately, if "length" is larger than ATH6KL_FWLOG_PAYLOAD_SIZE (1500) then we are screwed. Can you add a check for that instead? Please check my work on this because I didn't look *super* carefully. No need to make any changes to the types, just add the upper bounds check on ATH6KL_FWLOG_PAYLOAD_SIZE. The type changes didn't fix the bug on 32 bit systems anyway... regards, dan carpenter
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 77e052336eb5..b90ad9541e09 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -907,7 +907,7 @@ void ath6kl_cleanup_amsdu_rxbufs(struct ath6kl *ar); int ath6kl_diag_write32(struct ath6kl *ar, u32 address, __le32 value); int ath6kl_diag_write(struct ath6kl *ar, u32 address, void *data, u32 length); int ath6kl_diag_read32(struct ath6kl *ar, u32 address, u32 *value); -int ath6kl_diag_read(struct ath6kl *ar, u32 address, void *data, u32 length); +int ath6kl_diag_read(struct ath6kl *ar, u32 address, void *data, size_t length); int ath6kl_read_fwlogs(struct ath6kl *ar); void ath6kl_init_profile_info(struct ath6kl_vif *vif); void ath6kl_tx_data_cleanup(struct ath6kl *ar); diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index d3aa9e7a37c2..e9e66d5ad505 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -233,7 +233,7 @@ int ath6kl_diag_write32(struct ath6kl *ar, u32 address, __le32 value) return 0; } -int ath6kl_diag_read(struct ath6kl *ar, u32 address, void *data, u32 length) +int ath6kl_diag_read(struct ath6kl *ar, u32 address, void *data, size_t length) { u32 count, *buf = data; int ret; @@ -272,7 +272,8 @@ int ath6kl_read_fwlogs(struct ath6kl *ar) { struct ath6kl_dbglog_hdr debug_hdr; struct ath6kl_dbglog_buf debug_buf; - u32 address, length, firstbuf, debug_hdr_addr; + u32 address, firstbuf, debug_hdr_addr; + size_t length; int ret, loop; u8 *buf;