mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 10:33:41 +02:00
batman-adv: tvlv: reject oversized TVLV packets
batadv_tvlv_container_ogm_append() builds a TVLV packet section from
the tvlv.container_list. The total size of this section is computed by
batadv_tvlv_container_list_size(), which sums the sizes of all registered
containers.
The return type and accumulator in batadv_tvlv_container_list_size() were
u16. If the accumulated size exceeds U16_MAX, the value wraps around,
causing the subsequent allocation in batadv_tvlv_container_ogm_append()
to be undersized. The memcpy-style copy that follows would then write
beyond the end of the allocated buffer, corrupting kernel memory.
Fix this by widening the return type of batadv_tvlv_container_list_size()
to size_t. In batadv_tvlv_container_ogm_append(), check the computed length
against U16_MAX before proceeding, and bail out as if the allocation had
failed when the limit is exceeded.
Cc: stable@kernel.org
Fixes: ef26157747 ("batman-adv: tvlv - basic infrastructure")
Reported-by: Yuan Tan <yuantan098@gmail.com>
Reported-by: Yifan Wu <yifanwucs@gmail.com>
Reported-by: Juefei Pu <tomapufckgml@gmail.com>
Reported-by: Xin Liu <bird@lzu.edu.cn>
Reviewed-by: Yuan Tan <yuantan098@gmail.com>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
This commit is contained in:
parent
5013685065
commit
f50487e356
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/gfp.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/kref.h>
|
||||
#include <linux/limits.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/lockdep.h>
|
||||
#include <linux/netdevice.h>
|
||||
|
|
@ -160,10 +161,10 @@ batadv_tvlv_container_get(struct batadv_priv *bat_priv, u8 type, u8 version)
|
|||
*
|
||||
* Return: size of all currently registered tvlv containers in bytes.
|
||||
*/
|
||||
static u16 batadv_tvlv_container_list_size(struct batadv_priv *bat_priv)
|
||||
static size_t batadv_tvlv_container_list_size(struct batadv_priv *bat_priv)
|
||||
{
|
||||
struct batadv_tvlv_container *tvlv;
|
||||
u16 tvlv_len = 0;
|
||||
size_t tvlv_len = 0;
|
||||
|
||||
lockdep_assert_held(&bat_priv->tvlv.container_list_lock);
|
||||
|
||||
|
|
@ -316,13 +317,17 @@ int batadv_tvlv_container_ogm_append(struct batadv_priv *bat_priv,
|
|||
{
|
||||
struct batadv_tvlv_container *tvlv;
|
||||
struct batadv_tvlv_hdr *tvlv_hdr;
|
||||
u16 tvlv_value_len;
|
||||
size_t tvlv_value_len;
|
||||
void *tvlv_value;
|
||||
int tvlv_len_ret;
|
||||
bool ret;
|
||||
|
||||
spin_lock_bh(&bat_priv->tvlv.container_list_lock);
|
||||
tvlv_value_len = batadv_tvlv_container_list_size(bat_priv);
|
||||
if (tvlv_value_len > U16_MAX) {
|
||||
tvlv_len_ret = -E2BIG;
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = batadv_tvlv_realloc_packet_buff(packet_buff, packet_buff_len,
|
||||
packet_min_len, tvlv_value_len);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user