lkml.org 
[lkml]   [2019]   [Sep]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 43/79] batman-adv: Only read OGM2 tvlv_len after buffer len check
    Date
    From: Sven Eckelmann <sven@narfation.org>

    [ Upstream commit 0ff0f15a32c093381ad1abc06abe85afb561ab28 ]

    Multiple batadv_ogm2_packet can be stored in an skbuff. The functions
    batadv_v_ogm_send_to_if() uses batadv_v_ogm_aggr_packet() to check if there
    is another additional batadv_ogm2_packet in the skb or not before they
    continue processing the packet.

    The length for such an OGM2 is BATADV_OGM2_HLEN +
    batadv_ogm2_packet->tvlv_len. The check must first check that at least
    BATADV_OGM2_HLEN bytes are available before it accesses tvlv_len (which is
    part of the header. Otherwise it might try read outside of the currently
    available skbuff to get the content of tvlv_len.

    Fixes: 9323158ef9f4 ("batman-adv: OGMv2 - implement originators logic")
    Signed-off-by: Sven Eckelmann <sven@narfation.org>
    Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    net/batman-adv/bat_v_ogm.c | 18 ++++++++++++------
    1 file changed, 12 insertions(+), 6 deletions(-)

    diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c
    index 2948b41b06d47..d241ccc0ca027 100644
    --- a/net/batman-adv/bat_v_ogm.c
    +++ b/net/batman-adv/bat_v_ogm.c
    @@ -643,17 +643,23 @@ batadv_v_ogm_process_per_outif(struct batadv_priv *bat_priv,
    * batadv_v_ogm_aggr_packet() - checks if there is another OGM aggregated
    * @buff_pos: current position in the skb
    * @packet_len: total length of the skb
    - * @tvlv_len: tvlv length of the previously considered OGM
    + * @ogm2_packet: potential OGM2 in buffer
    *
    * Return: true if there is enough space for another OGM, false otherwise.
    */
    -static bool batadv_v_ogm_aggr_packet(int buff_pos, int packet_len,
    - __be16 tvlv_len)
    +static bool
    +batadv_v_ogm_aggr_packet(int buff_pos, int packet_len,
    + const struct batadv_ogm2_packet *ogm2_packet)
    {
    int next_buff_pos = 0;

    - next_buff_pos += buff_pos + BATADV_OGM2_HLEN;
    - next_buff_pos += ntohs(tvlv_len);
    + /* check if there is enough space for the header */
    + next_buff_pos += buff_pos + sizeof(*ogm2_packet);
    + if (next_buff_pos > packet_len)
    + return false;
    +
    + /* check if there is enough space for the optional TVLV */
    + next_buff_pos += ntohs(ogm2_packet->tvlv_len);

    return (next_buff_pos <= packet_len) &&
    (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES);
    @@ -830,7 +836,7 @@ int batadv_v_ogm_packet_recv(struct sk_buff *skb,
    ogm_packet = (struct batadv_ogm2_packet *)skb->data;

    while (batadv_v_ogm_aggr_packet(ogm_offset, skb_headlen(skb),
    - ogm_packet->tvlv_len)) {
    + ogm_packet)) {
    batadv_v_ogm_process(skb, ogm_offset, if_incoming);

    ogm_offset += BATADV_OGM2_HLEN;
    --
    2.20.1


    \
     
     \ /
      Last update: 2019-09-20 00:15    [W:4.746 / U:1.628 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site