Received: by 10.223.185.116 with SMTP id b49csp4194904wrg; Mon, 26 Feb 2018 12:59:11 -0800 (PST) X-Google-Smtp-Source: AH8x226MvMcIuVblbEHme0p4TBJft8v6i2bVGUQi7DBCjsLAL9nxoOt4/lhArOK53sP0uxDCSg06 X-Received: by 10.99.67.133 with SMTP id q127mr9564452pga.365.1519678751673; Mon, 26 Feb 2018 12:59:11 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519678751; cv=none; d=google.com; s=arc-20160816; b=okT7+r67NPQFCkRdIX1MztlgIYKpCQmh1oKCrXejYLt9jYIXPPCn73xoFd7EJiMmC8 vjd3+0xhMYUUyhDrODoIPxfB7yzZYwLoaUe3T0e+f6FbLf/cUZKsAO5VFKUge0xjzetf GjOT0WYeu5ZVedw1T1zlMRksBsfUTx1EgXLNiGXbEc8CGglTEI9D8xWcQksW3R6OEq7c C5CKM2868AiSrAkUD9GDfpRxr/SmFhuuCVZISY5fEKbLu05Cfzhw6EAHsL2XItgdAcW8 JmMzKpBHeXeTuWQ6BX4rbdUdn2fryLdYvYe5CMWss33658vmHhkb+iXF9Z1uufFqiklD QYMw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=OR7E/F5NUAvnhNA8aQoeCNFggVVFtv88bZR+gi9qDx8=; b=YbWYIQgZNSshV+qxDPKx3FLh2wTawFV4g/JNDxmg4TUJkzgjl2I/Tou64WIQaTl3Aq WiOY7YpryHhq40CB7KN0dd5JcZ6RD93s01z1F2lSAvZ7X7eSnjaij9+ug/xCptEcjj+L a8ERT7oln1UqDOTtAXge8MxQ7C8sef9/vIhNC5qMGvBsJEfuN8AQlc61+AHNbG7LyppF hUyHAJYq5k3DLDtSL3Vy71/IL2WJSwjJTFx8LZOJtCIWtwzD1jd24y0+HX4MWL/TGoh+ F7swX8yGDU9ZX/CVRCAz5zRRVLna2oL7GTdmmVEaydj/nwCE6GeGpV4eUtQIc4K+iWYA 3Lew== 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 p10si5973686pgc.74.2018.02.26.12.58.54; Mon, 26 Feb 2018 12:59:11 -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 S1752541AbeBZUWt (ORCPT + 99 others); Mon, 26 Feb 2018 15:22:49 -0500 Received: from mail.linuxfoundation.org ([140.211.169.12]:34408 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752065AbeBZUWo (ORCPT ); Mon, 26 Feb 2018 15:22:44 -0500 Received: from localhost (clnet-b04-243.ikbnet.co.at [83.175.124.243]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id A9311E83; Mon, 26 Feb 2018 20:22:43 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, syzkaller , Noa Osherovich , Matan Barak , Leon Romanovsky , Jason Gunthorpe Subject: [PATCH 4.9 07/39] RDMA/uverbs: Protect from command mask overflow Date: Mon, 26 Feb 2018 21:20:28 +0100 Message-Id: <20180226201643.999219782@linuxfoundation.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180226201643.660109883@linuxfoundation.org> References: <20180226201643.660109883@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.9-stable review patch. If anyone has any objections, please let me know. ------------------ From: Leon Romanovsky commit 3f802b162dbf4a558ff98986449eddc717826209 upstream. The command number is not bounds checked against the command mask before it is shifted, resulting in an ubsan hit. This does not cause malfunction since the command number is eventually bounds checked, but we can make this ubsan clean by moving the bounds check to before the mask check. ================================================================================ UBSAN: Undefined behaviour in drivers/infiniband/core/uverbs_main.c:647:21 shift exponent 207 is too large for 64-bit type 'long long unsigned int' CPU: 0 PID: 446 Comm: syz-executor3 Not tainted 4.15.0-rc2+ #61 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.7.5-0-ge51488c-20140602_164612-nilsson.home.kraxel.org 04/01/2014 Call Trace: dump_stack+0xde/0x164 ? dma_virt_map_sg+0x22c/0x22c ubsan_epilogue+0xe/0x81 __ubsan_handle_shift_out_of_bounds+0x293/0x2f7 ? debug_check_no_locks_freed+0x340/0x340 ? __ubsan_handle_load_invalid_value+0x19b/0x19b ? lock_acquire+0x440/0x440 ? lock_acquire+0x19d/0x440 ? __might_fault+0xf4/0x240 ? ib_uverbs_write+0x68d/0xe20 ib_uverbs_write+0x68d/0xe20 ? __lock_acquire+0xcf7/0x3940 ? uverbs_devnode+0x110/0x110 ? cyc2ns_read_end+0x10/0x10 ? sched_clock_cpu+0x18/0x200 ? sched_clock_cpu+0x18/0x200 __vfs_write+0x10d/0x700 ? uverbs_devnode+0x110/0x110 ? kernel_read+0x170/0x170 ? __fget+0x35b/0x5d0 ? security_file_permission+0x93/0x260 vfs_write+0x1b0/0x550 SyS_write+0xc7/0x1a0 ? SyS_read+0x1a0/0x1a0 ? trace_hardirqs_on_thunk+0x1a/0x1c entry_SYSCALL_64_fastpath+0x18/0x85 RIP: 0033:0x448e29 RSP: 002b:00007f033f567c58 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 00007f033f5686bc RCX: 0000000000448e29 RDX: 0000000000000060 RSI: 0000000020001000 RDI: 0000000000000012 RBP: 000000000070bea0 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 00000000ffffffff R13: 00000000000056a0 R14: 00000000006e8740 R15: 0000000000000000 ================================================================================ Cc: syzkaller Cc: # 4.5 Fixes: 2dbd5186a39c ("IB/core: IB/core: Allow legacy verbs through extended interfaces") Reported-by: Noa Osherovich Reviewed-by: Matan Barak Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/core/uverbs_main.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -735,12 +735,21 @@ static int verify_command_mask(struct ib return -1; } +static bool verify_command_idx(u32 command, bool extended) +{ + if (extended) + return command < ARRAY_SIZE(uverbs_ex_cmd_table); + + return command < ARRAY_SIZE(uverbs_cmd_table); +} + static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, size_t count, loff_t *pos) { struct ib_uverbs_file *file = filp->private_data; struct ib_device *ib_dev; struct ib_uverbs_cmd_hdr hdr; + bool extended_command; __u32 command; __u32 flags; int srcu_key; @@ -770,6 +779,15 @@ static ssize_t ib_uverbs_write(struct fi } command = hdr.command & IB_USER_VERBS_CMD_COMMAND_MASK; + flags = (hdr.command & + IB_USER_VERBS_CMD_FLAGS_MASK) >> IB_USER_VERBS_CMD_FLAGS_SHIFT; + + extended_command = flags & IB_USER_VERBS_CMD_FLAG_EXTENDED; + if (!verify_command_idx(command, extended_command)) { + ret = -EINVAL; + goto out; + } + if (verify_command_mask(ib_dev, command)) { ret = -EOPNOTSUPP; goto out; @@ -781,12 +799,8 @@ static ssize_t ib_uverbs_write(struct fi goto out; } - flags = (hdr.command & - IB_USER_VERBS_CMD_FLAGS_MASK) >> IB_USER_VERBS_CMD_FLAGS_SHIFT; - if (!flags) { - if (command >= ARRAY_SIZE(uverbs_cmd_table) || - !uverbs_cmd_table[command]) { + if (!uverbs_cmd_table[command]) { ret = -EINVAL; goto out; } @@ -807,8 +821,7 @@ static ssize_t ib_uverbs_write(struct fi struct ib_udata uhw; size_t written_count = count; - if (command >= ARRAY_SIZE(uverbs_ex_cmd_table) || - !uverbs_ex_cmd_table[command]) { + if (!uverbs_ex_cmd_table[command]) { ret = -ENOSYS; goto out; }