lkml.org 
[lkml]   [2018]   [Nov]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 048/160] net/ipv4: defensive cipso option parsing
    Date
    4.4-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Stefan Nuernberger <snu@amazon.com>

    commit 076ed3da0c9b2f88d9157dbe7044a45641ae369e upstream.

    commit 40413955ee26 ("Cipso: cipso_v4_optptr enter infinite loop") fixed
    a possible infinite loop in the IP option parsing of CIPSO. The fix
    assumes that ip_options_compile filtered out all zero length options and
    that no other one-byte options beside IPOPT_END and IPOPT_NOOP exist.
    While this assumption currently holds true, add explicit checks for zero
    length and invalid length options to be safe for the future. Even though
    ip_options_compile should have validated the options, the introduction of
    new one-byte options can still confuse this code without the additional
    checks.

    Signed-off-by: Stefan Nuernberger <snu@amazon.com>
    Cc: David Woodhouse <dwmw@amazon.co.uk>
    Cc: Simon Veith <sveith@amazon.de>
    Cc: stable@vger.kernel.org
    Acked-by: Paul Moore <paul@paul-moore.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    net/ipv4/cipso_ipv4.c | 11 +++++++----
    1 file changed, 7 insertions(+), 4 deletions(-)

    --- a/net/ipv4/cipso_ipv4.c
    +++ b/net/ipv4/cipso_ipv4.c
    @@ -1582,7 +1582,7 @@ static int cipso_v4_parsetag_loc(const s
    *
    * Description:
    * Parse the packet's IP header looking for a CIPSO option. Returns a pointer
    - * to the start of the CIPSO option on success, NULL if one if not found.
    + * to the start of the CIPSO option on success, NULL if one is not found.
    *
    */
    unsigned char *cipso_v4_optptr(const struct sk_buff *skb)
    @@ -1592,10 +1592,8 @@ unsigned char *cipso_v4_optptr(const str
    int optlen;
    int taglen;

    - for (optlen = iph->ihl*4 - sizeof(struct iphdr); optlen > 0; ) {
    + for (optlen = iph->ihl*4 - sizeof(struct iphdr); optlen > 1; ) {
    switch (optptr[0]) {
    - case IPOPT_CIPSO:
    - return optptr;
    case IPOPT_END:
    return NULL;
    case IPOPT_NOOP:
    @@ -1604,6 +1602,11 @@ unsigned char *cipso_v4_optptr(const str
    default:
    taglen = optptr[1];
    }
    + if (!taglen || taglen > optlen)
    + return NULL;
    + if (optptr[0] == IPOPT_CIPSO)
    + return optptr;
    +
    optlen -= taglen;
    optptr += taglen;
    }

    \
     
     \ /
      Last update: 2018-11-19 18:23    [W:4.124 / U:0.088 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site