lkml.org 
[lkml]   [2020]   [Jan]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 012/110] staging: most: net: fix buffer overflow
    Date
    From: Andrey Shvetsov <andrey.shvetsov@k2l.de>

    commit 4d1356ac12f4d5180d0df345d85ff0ee42b89c72 upstream.

    If the length of the socket buffer is 0xFFFFFFFF (max size for an
    unsigned int), then payload_len becomes 0xFFFFFFF1 after subtracting 14
    (ETH_HLEN). Then, mdp_len is set to payload_len + 16 (MDP_HDR_LEN)
    which overflows and results in a value of 2. These values for
    payload_len and mdp_len will pass current buffer size checks.

    This patch checks if derived from skb->len sum may overflow.

    The check is based on the following idea:

    For any `unsigned V1, V2` and derived `unsigned SUM = V1 + V2`,
    `V1 + V2` overflows iif `SUM < V1`.

    Reported-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Signed-off-by: Andrey Shvetsov <andrey.shvetsov@k2l.de>
    Cc: stable <stable@vger.kernel.org>
    Link: https://lore.kernel.org/r/20200116172238.6046-1-andrey.shvetsov@microchip.com
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/staging/most/net/net.c | 10 ++++++++++
    1 file changed, 10 insertions(+)

    --- a/drivers/staging/most/net/net.c
    +++ b/drivers/staging/most/net/net.c
    @@ -81,6 +81,11 @@ static int skb_to_mamac(const struct sk_
    unsigned int payload_len = skb->len - ETH_HLEN;
    unsigned int mdp_len = payload_len + MDP_HDR_LEN;

    + if (mdp_len < skb->len) {
    + pr_err("drop: too large packet! (%u)\n", skb->len);
    + return -EINVAL;
    + }
    +
    if (mbo->buffer_length < mdp_len) {
    pr_err("drop: too small buffer! (%d for %d)\n",
    mbo->buffer_length, mdp_len);
    @@ -128,6 +133,11 @@ static int skb_to_mep(const struct sk_bu
    u8 *buff = mbo->virt_address;
    unsigned int mep_len = skb->len + MEP_HDR_LEN;

    + if (mep_len < skb->len) {
    + pr_err("drop: too large packet! (%u)\n", skb->len);
    + return -EINVAL;
    + }
    +
    if (mbo->buffer_length < mep_len) {
    pr_err("drop: too small buffer! (%d for %d)\n",
    mbo->buffer_length, mep_len);

    \
     
     \ /
      Last update: 2020-01-30 19:44    [W:4.215 / U:0.048 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site