mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 10:33:41 +02:00
ipw2x00: Avoid field-overflowing memcpy()
In preparation for FORTIFY_SOURCE performing compile-time and run-time
field bounds checking for memcpy(), memmove(), and memset(), avoid
intentionally writing across neighboring fields.
libipw_read_qos_param_element() copies a struct libipw_info_element
into a struct libipw_qos_information_element, but is actually wanting to
copy into the larger struct libipw_qos_parameter_info (the contents of
ac_params_record[] is later examined). Refactor the routine to perform
centralized checks, and copy the entire contents directly (since the id
and len members match the elementID and length members):
struct libipw_info_element {
u8 id;
u8 len;
u8 data[];
} __packed;
struct libipw_qos_information_element {
u8 elementID;
u8 length;
u8 qui[QOS_OUI_LEN];
u8 qui_type;
u8 qui_subtype;
u8 version;
u8 ac_info;
} __packed;
struct libipw_qos_parameter_info {
struct libipw_qos_information_element info_element;
u8 reserved;
struct libipw_qos_ac_parameter ac_params_record[QOS_QUEUE_NUM];
} __packed;
Cc: Stanislav Yakovlev <stas.yakovlev@gmail.com>
Cc: Kalle Valo <kvalo@codeaurora.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: linux-wireless@vger.kernel.org
Cc: netdev@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20210819202825.3545692-2-keescook@chromium.org
This commit is contained in:
parent
6f78f4a41e
commit
d6b6d1bb80
|
|
@ -927,7 +927,8 @@ static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
|
|||
static int libipw_verify_qos_info(struct libipw_qos_information_element
|
||||
*info_element, int sub_type)
|
||||
{
|
||||
|
||||
if (info_element->elementID != QOS_ELEMENT_ID)
|
||||
return -1;
|
||||
if (info_element->qui_subtype != sub_type)
|
||||
return -1;
|
||||
if (memcmp(info_element->qui, qos_oui, QOS_OUI_LEN))
|
||||
|
|
@ -943,57 +944,34 @@ static int libipw_verify_qos_info(struct libipw_qos_information_element
|
|||
/*
|
||||
* Parse a QoS parameter element
|
||||
*/
|
||||
static int libipw_read_qos_param_element(struct libipw_qos_parameter_info
|
||||
*element_param, struct libipw_info_element
|
||||
*info_element)
|
||||
static int libipw_read_qos_param_element(
|
||||
struct libipw_qos_parameter_info *element_param,
|
||||
struct libipw_info_element *info_element)
|
||||
{
|
||||
int ret = 0;
|
||||
u16 size = sizeof(struct libipw_qos_parameter_info) - 2;
|
||||
size_t size = sizeof(*element_param);
|
||||
|
||||
if ((info_element == NULL) || (element_param == NULL))
|
||||
if (!element_param || !info_element || info_element->len != size - 2)
|
||||
return -1;
|
||||
|
||||
if (info_element->id == QOS_ELEMENT_ID && info_element->len == size) {
|
||||
memcpy(element_param->info_element.qui, info_element->data,
|
||||
info_element->len);
|
||||
element_param->info_element.elementID = info_element->id;
|
||||
element_param->info_element.length = info_element->len;
|
||||
} else
|
||||
ret = -1;
|
||||
if (ret == 0)
|
||||
ret = libipw_verify_qos_info(&element_param->info_element,
|
||||
QOS_OUI_PARAM_SUB_TYPE);
|
||||
return ret;
|
||||
memcpy(element_param, info_element, size);
|
||||
return libipw_verify_qos_info(&element_param->info_element,
|
||||
QOS_OUI_PARAM_SUB_TYPE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a QoS information element
|
||||
*/
|
||||
static int libipw_read_qos_info_element(struct
|
||||
libipw_qos_information_element
|
||||
*element_info, struct libipw_info_element
|
||||
*info_element)
|
||||
static int libipw_read_qos_info_element(
|
||||
struct libipw_qos_information_element *element_info,
|
||||
struct libipw_info_element *info_element)
|
||||
{
|
||||
int ret = 0;
|
||||
u16 size = sizeof(struct libipw_qos_information_element) - 2;
|
||||
size_t size = sizeof(struct libipw_qos_information_element) - 2;
|
||||
|
||||
if (element_info == NULL)
|
||||
return -1;
|
||||
if (info_element == NULL)
|
||||
if (!element_info || !info_element || info_element->len != size - 2)
|
||||
return -1;
|
||||
|
||||
if ((info_element->id == QOS_ELEMENT_ID) && (info_element->len == size)) {
|
||||
memcpy(element_info->qui, info_element->data,
|
||||
info_element->len);
|
||||
element_info->elementID = info_element->id;
|
||||
element_info->length = info_element->len;
|
||||
} else
|
||||
ret = -1;
|
||||
|
||||
if (ret == 0)
|
||||
ret = libipw_verify_qos_info(element_info,
|
||||
QOS_OUI_INFO_SUB_TYPE);
|
||||
return ret;
|
||||
memcpy(element_info, info_element, size);
|
||||
return libipw_verify_qos_info(element_info, QOS_OUI_INFO_SUB_TYPE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user