Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp2987904imu; Sun, 9 Dec 2018 14:23:21 -0800 (PST) X-Google-Smtp-Source: AFSGD/V6eyQEySaF5kheg4P613TYNigFTWljAyyPsFDs1pmx8OhaIOwJjsTfoqOAhc7w0on6MdS6 X-Received: by 2002:a63:b218:: with SMTP id x24mr8589732pge.223.1544394201123; Sun, 09 Dec 2018 14:23:21 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1544394201; cv=none; d=google.com; s=arc-20160816; b=qO4sDCfJCTPMCoCK8RGRS5td0bUdIQ48IIPpZg24VKT4wbA3gN1WzYIrN1PFcJH7iC Gy/7+2IdOAQjVm2owRdP/+MZ9FmEFGqVdy2G43WGQR2GwNFyZ30XicoeqxvW8Sp1nhjo 7FcHEBkAovCHSVEOjYYS1oFTN01LslLR+Nf/oJOfFqTo7fCTpAp4xIq5gZ8hYy0LZoTQ wpEVoXNpuUrYIVgqasnteHDFskZCfDyY4IAmBA8MPWWe2jp9c8Q7uamF2Y1Qg/fLCRny vezt7rR5Ztr+pZYeUONBXklNhUcDBv5valoSY5+bUf1zMCg15Mo1tBarSxpLVl/WjgGB JpYg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:subject:message-id:date:cc:to :from:mime-version:content-transfer-encoding:content-disposition; bh=h6oZQXnt23BP/ZfBBv0/2di5p00G33lMKl1Edhzg5E4=; b=qO+4QltsR16HzjmWrGeObShRkq3Lsuzqz9qo/5FM1OONQn8g8555zzux/bY188cmS9 ckTLDkfo0Mz2xjDEP6Muw6Qu5aXvyOKkH+ePL+fkN0/bGbk6Ae7C0NW+v0MDfao09Dkj 2JgI7cheDSbVJWie30kN5DcNZiTBS1zUzDk+iXDnhw9bshVKF+XQYw5+1ry/pVF3DHE3 k5T430LjbtZmSZaJr3g54MHHaGIqCiJ0RGLkJVW/BCCiQ4i4ZDKvFGlpd/FnOoi2TgW6 5nqr9Skw41FOTGPDmaxqJ+j6F/vU2i4kxfIcJEB0oFWjJvUJAZjv7uGGQCYLl6r1+qIf exvQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a6si8652046pfo.90.2018.12.09.14.23.05; Sun, 09 Dec 2018 14:23:21 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727694AbeLIWUd (ORCPT + 99 others); Sun, 9 Dec 2018 17:20:33 -0500 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:35414 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726548AbeLIVzY (ORCPT ); Sun, 9 Dec 2018 16:55:24 -0500 Received: from pub.yeoldevic.com ([81.174.156.145] helo=deadeye) by shadbolt.decadent.org.uk with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1gW72o-0002if-6P; Sun, 09 Dec 2018 21:55:22 +0000 Received: from ben by deadeye with local (Exim 4.91) (envelope-from ) id 1gW72l-0003gP-66; Sun, 09 Dec 2018 21:55:19 +0000 Content-Type: text/plain; charset="UTF-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 From: Ben Hutchings To: linux-kernel@vger.kernel.org, stable@vger.kernel.org CC: akpm@linux-foundation.org, "Herbert Xu" , "Eric Dumazet" , "David S. Miller" , "syzbot" Date: Sun, 09 Dec 2018 21:50:33 +0000 Message-ID: X-Mailer: LinuxStableQueue (scripts by bwh) X-Patchwork-Hint: ignore Subject: [PATCH 3.16 309/328] net: make skb_partial_csum_set() more robust against overflows In-Reply-To: X-SA-Exim-Connect-IP: 81.174.156.145 X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.16.62-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Eric Dumazet commit 52b5d6f5dcf0e5201392f7d417148ccb537dbf6f upstream. syzbot managed to crash in skb_checksum_help() [1] : BUG_ON(offset + sizeof(__sum16) > skb_headlen(skb)); Root cause is the following check in skb_partial_csum_set() if (unlikely(start > skb_headlen(skb)) || unlikely((int)start + off > skb_headlen(skb) - 2)) return false; If skb_headlen(skb) is 1, then (skb_headlen(skb) - 2) becomes 0xffffffff and the check fails to detect that ((int)start + off) is off the limit, since the compare is unsigned. When we fix that, then the first condition (start > skb_headlen(skb)) becomes obsolete. Then we should also check that (skb_headroom(skb) + start) wont overflow 16bit field. [1] kernel BUG at net/core/dev.c:2880! invalid opcode: 0000 [#1] PREEMPT SMP KASAN CPU: 1 PID: 7330 Comm: syz-executor4 Not tainted 4.19.0-rc6+ #253 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 RIP: 0010:skb_checksum_help+0x9e3/0xbb0 net/core/dev.c:2880 Code: 85 00 ff ff ff 48 c1 e8 03 42 80 3c 28 00 0f 84 09 fb ff ff 48 8b bd 00 ff ff ff e8 97 a8 b9 fb e9 f8 fa ff ff e8 2d 09 76 fb <0f> 0b 48 8b bd 28 ff ff ff e8 1f a8 b9 fb e9 b1 f6 ff ff 48 89 cf RSP: 0018:ffff8801d83a6f60 EFLAGS: 00010293 RAX: ffff8801b9834380 RBX: ffff8801b9f8d8c0 RCX: ffffffff8608c6d7 RDX: 0000000000000000 RSI: ffffffff8608cc63 RDI: 0000000000000006 RBP: ffff8801d83a7068 R08: ffff8801b9834380 R09: 0000000000000000 R10: ffff8801d83a76d8 R11: 0000000000000000 R12: 0000000000000001 R13: 0000000000010001 R14: 000000000000ffff R15: 00000000000000a8 FS: 00007f1a66db5700(0000) GS:ffff8801daf00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f7d77f091b0 CR3: 00000001ba252000 CR4: 00000000001406e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: skb_csum_hwoffload_help+0x8f/0xe0 net/core/dev.c:3269 validate_xmit_skb+0xa2a/0xf30 net/core/dev.c:3312 __dev_queue_xmit+0xc2f/0x3950 net/core/dev.c:3797 dev_queue_xmit+0x17/0x20 net/core/dev.c:3838 packet_snd net/packet/af_packet.c:2928 [inline] packet_sendmsg+0x422d/0x64c0 net/packet/af_packet.c:2953 Fixes: 5ff8dda3035d ("net: Ensure partial checksum offset is inside the skb head") Signed-off-by: Eric Dumazet Cc: Herbert Xu Reported-by: syzbot Signed-off-by: David S. Miller Signed-off-by: Ben Hutchings --- net/core/skbuff.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -3593,14 +3593,16 @@ EXPORT_SYMBOL_GPL(skb_complete_wifi_ack) */ bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off) { - if (unlikely(start > skb_headlen(skb)) || - unlikely((int)start + off > skb_headlen(skb) - 2)) { - net_warn_ratelimited("bad partial csum: csum=%u/%u len=%u\n", - start, off, skb_headlen(skb)); + u32 csum_end = (u32)start + (u32)off + sizeof(__sum16); + u32 csum_start = skb_headroom(skb) + (u32)start; + + if (unlikely(csum_start > U16_MAX || csum_end > skb_headlen(skb))) { + net_warn_ratelimited("bad partial csum: csum=%u/%u headroom=%u headlen=%u\n", + start, off, skb_headroom(skb), skb_headlen(skb)); return false; } skb->ip_summed = CHECKSUM_PARTIAL; - skb->csum_start = skb_headroom(skb) + start; + skb->csum_start = csum_start; skb->csum_offset = off; skb_set_transport_header(skb, start); return true;