Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755779AbbLQA5M (ORCPT ); Wed, 16 Dec 2015 19:57:12 -0500 Received: from aserp1040.oracle.com ([141.146.126.69]:43488 "EHLO aserp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755540AbbLQA5I (ORCPT ); Wed, 16 Dec 2015 19:57:08 -0500 From: Vegard Nossum To: "David S. Miller" Cc: Eric Dumazet , netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] inet: sanitize socket() protocol value Date: Thu, 17 Dec 2015 01:57:01 +0100 Message-Id: <1450313821-27217-1-git-send-email-vegard.nossum@oracle.com> X-Mailer: git-send-email 1.9.1 X-Source-IP: aserv0021.oracle.com [141.146.126.233] Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3012 Lines: 73 If you create a raw socket with a protocol of e.g. 0x10000, then inet_sk(sk)->inet_num will get set to 0 since it only has room for 16 bits. This causes problems further down the line as lots of code makes assumptions about ->inet_num, for example connect()...inet_autobind() will attempt to call sk->sk_prot->get_port() which is invalid: BUG: unable to handle kernel NULL pointer dereference at (null) IP: [< (null)>] (null) PGD 19ea0067 PUD 19d3f067 PMD 0 Oops: 0010 [#1] SMP CPU: 1 PID: 849 Comm: a.out Not tainted 4.4.0-rc4+ #287 task: ffff880019a12640 ti: ffff88000008c000 task.ti: ffff88000008c000 RIP: 0010:[<0000000000000000>] [< (null)>] (null) RSP: 0018:ffff88000008fe50 EFLAGS: 00010246 RAX: ffffffff81cc61f0 RBX: ffff880019d2ca80 RCX: 0000000000000802 RDX: 0000000000000001 RSI: 0000000000000000 RDI: ffff880019d2ca80 RBP: ffff88000008fe60 R08: 00007f0e6b132e80 R09: ffff880019d2ca80 R10: ffff88001a7a72e0 R11: ffff880019a12640 R12: 000000000000000b R13: 0000000000400644 R14: 0000000000000000 R15: 0000000000000000 FS: 00007f0e6b355740(0000) GS:ffff88001a900000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 0000000019d3d000 CR4: 00000000001406a0 Stack: ffffffff815f1c69 ffff880019d2ca80 ffff88000008fe88 ffffffff815f1cde 0000000b0000000b ffff88000008fea0 ffff880019484000 ffff88000008ff38 ffffffff8156f310 0000000000000000 2a2a2a2a2a2a2a2a ffffffff8100002a Call Trace: [] ? inet_autobind+0x23/0x50 [] inet_dgram_connect+0x48/0x64 [] SYSC_connect+0x84/0xae [] ? sock_alloc_file+0xb3/0x108 [] ? fd_install+0x20/0x22 [] ? SYSC_socket+0x62/0x90 [] SyS_connect+0x9/0xb [] entry_SYSCALL_64_fastpath+0x12/0x71 Code: Bad RIP value. RIP [< (null)>] (null) RSP CR2: 0000000000000000 ---[ end trace bd60b4fe2edc2537 ]--- Signed-off-by: Vegard Nossum Cc: Eric Dumazet Cc: --- net/ipv4/af_inet.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git net/ipv4/af_inet.c net/ipv4/af_inet.c index 11c4ca1..4e1583a 100644 --- net/ipv4/af_inet.c +++ net/ipv4/af_inet.c @@ -316,6 +316,12 @@ lookup_protocol: WARN_ON(!answer_prot->slab); + /* Check that the protocol we were given will actually fit in + * inet->inet_num. */ + err = -EINVAL; + if (protocol != (typeof(inet->inet_num)) protocol) + goto out; + err = -ENOBUFS; sk = sk_alloc(net, PF_INET, GFP_KERNEL, answer_prot, kern); if (!sk) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/