From patchwork Fri Aug 12 08:29:13 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vegard Nossum X-Patchwork-Id: 658550 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3s9dPF0tZdz9sdm for ; Fri, 12 Aug 2016 18:30:25 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752508AbcHLIaW (ORCPT ); Fri, 12 Aug 2016 04:30:22 -0400 Received: from aserp1040.oracle.com ([141.146.126.69]:49437 "EHLO aserp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752487AbcHLIaU (ORCPT ); Fri, 12 Aug 2016 04:30:20 -0400 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id u7C8Tj5I007262 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 12 Aug 2016 08:29:45 GMT Received: from lenuta.oracle.com (dhcp-ukc1-twvpn-1-vpnpool-10-175-165-43.vpn.oracle.com [10.175.165.43]) by aserv0022.oracle.com (8.14.4/8.14.4) with ESMTP id u7C8TgY9001131; Fri, 12 Aug 2016 08:29:43 GMT From: Vegard Nossum To: Samuel Ortiz Cc: irda-users@lists.sourceforge.net, netdev@vger.kernel.org, Vegard Nossum , stable@vger.kernel.org Subject: [PATCH] net/irda: handle iriap_register_lsap() allocation failure Date: Fri, 12 Aug 2016 10:29:13 +0200 Message-Id: <1470990553-19921-1-git-send-email-vegard.nossum@oracle.com> X-Mailer: git-send-email 1.9.1 X-Source-IP: aserv0022.oracle.com [141.146.126.234] Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org If iriap_register_lsap() fails to allocate memory, self->lsap is set to NULL. However, none of the callers handle the failure and irlmp_connect_request() will happily dereference it: iriap_register_lsap: Unable to allocated LSAP! ================================================================================ UBSAN: Undefined behaviour in net/irda/irlmp.c:378:2 member access within null pointer of type 'struct lsap_cb' CPU: 1 PID: 15403 Comm: trinity-c0 Not tainted 4.8.0-rc1+ #81 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.9.3-0-ge2fc41e-prebuilt.qemu-project.org 04/01/2014 0000000000000000 ffff88010c7e78a8 ffffffff82344f40 0000000041b58ab3 ffffffff84f98000 ffffffff82344e94 ffff88010c7e78d0 ffff88010c7e7880 ffff88010630ad00 ffffffff84a5fae0 ffffffff84d3f5c0 000000000000017a Call Trace: [] dump_stack+0xac/0xfc [] ubsan_epilogue+0xd/0x8a [] __ubsan_handle_type_mismatch+0x157/0x411 [] irlmp_connect_request+0x7ac/0x970 [] iriap_connect_request+0xa0/0x160 [] state_s_disconnect+0x88/0xd0 [] iriap_do_client_event+0x94/0x120 [] iriap_getvaluebyclass_request+0x3e0/0x6d0 [] irda_find_lsap_sel+0x1eb/0x630 [] irda_connect+0x828/0x12d0 [] SYSC_connect+0x22b/0x340 [] SyS_connect+0x9/0x10 [] do_syscall_64+0x1b3/0x4b0 [] entry_SYSCALL64_slow_path+0x25/0x25 ================================================================================ The bug seems to have been around since forever. There's more problems with missing error checks in iriap_init() (and indeed all of irda_init()), but that's a bigger problem that needs very careful review and testing. This patch will fix the most serious bug (as it's easily reached from unprivileged userspace). I have tested my patch with a reproducer. Cc: stable@vger.kernel.org Signed-off-by: Vegard Nossum --- net/irda/iriap.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/net/irda/iriap.c b/net/irda/iriap.c index 4a7ae32a..1138eaf 100644 --- a/net/irda/iriap.c +++ b/net/irda/iriap.c @@ -185,8 +185,12 @@ struct iriap_cb *iriap_open(__u8 slsap_sel, int mode, void *priv, self->magic = IAS_MAGIC; self->mode = mode; - if (mode == IAS_CLIENT) - iriap_register_lsap(self, slsap_sel, mode); + if (mode == IAS_CLIENT) { + if (iriap_register_lsap(self, slsap_sel, mode)) { + kfree(self); + return NULL; + } + } self->confirm = callback; self->priv = priv;