Received: by 10.223.185.116 with SMTP id b49csp4192009wrg; Mon, 26 Feb 2018 12:55:17 -0800 (PST) X-Google-Smtp-Source: AH8x226YobKr3tPRxfdzEBSrspHCl+mpXIuugtdByqvO3FCa4V0Qx8M53pkKD13S1xQbUABAMMc4 X-Received: by 2002:a17:902:6bc6:: with SMTP id m6-v6mr12100109plt.100.1519678517671; Mon, 26 Feb 2018 12:55:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519678517; cv=none; d=google.com; s=arc-20160816; b=azUommLzwFJ35J20lIXeySBQ4gxP/jF+UOJeL0OUnrsEjIOF6cCgeD3NTlJIxdJZg8 36AGmINnuMEkRX+iVBMuTBjbrSkZWXBdjkafhJ+DMXQnQ0E+hm16BUHCVigEl9ZZmvcZ Sg8jAgCCJSBjgnaKZP+pi6a4iCCk0CgcTWj3qAOBNiLx1rsJx97mwrHAurLoiV8ez6DS nmse48ofCS/lSPUU1UrVk3wUvxl/5+097L5fkVMLe8JqRzqQTmL2S+NQqoF7cCV4FLbc z9zBDg3wlCubZ7Xz5mlDvo7dF9Qt2Bhs1yKAocyFjMBU5lzDwpljgvlkKTa9knDaxg7s n3Aw== 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=Ju60a/asJwSgtKwfx2cMeNllLJ7FIzQG3yf1I1dmV4I=; b=X3ayZo+x/ToWjlYkVFZF6Cj2+TB0//1ta5kONKoRxjDcKZel6on0TfmANnCriHdDQq VB00Ll7s/FyDpQRmalgOmYCcFUYdGnRIHU5BRQ9CJavOxaD33Qr0N74dAeAB0zADtZQ9 TSdORsdTcKjmuJrrHXAMzAimrJLEE/m7araHSg0xdl3ajI19qRhcrpKbYg/+Y4KRtQUL riHIJzc6wBEUpbGzKFua8AQ2UjvlrHxz2rjJ9cGuVg0NGNYwJSZH1TdssqVr9S6s/SA5 X1/9hJPvAO4c92eR8QJ/UyPwAnC+sbHF9ETidBfSEGlbqYFyPma6JCb03Fepyjjas5i+ oKdA== 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 d13si5988513pgu.554.2018.02.26.12.55.01; Mon, 26 Feb 2018 12:55:17 -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 S1752719AbeBZUXl (ORCPT + 99 others); Mon, 26 Feb 2018 15:23:41 -0500 Received: from mail.linuxfoundation.org ([140.211.169.12]:34870 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751448AbeBZUXi (ORCPT ); Mon, 26 Feb 2018 15:23:38 -0500 Received: from localhost (clnet-b04-243.ikbnet.co.at [83.175.124.243]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 0DFEBF2C; Mon, 26 Feb 2018 20:23:37 +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.14 17/54] RDMA/uverbs: Protect from command mask overflow Date: Mon, 26 Feb 2018 21:21:54 +0100 Message-Id: <20180226202145.232133681@linuxfoundation.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180226202144.375869933@linuxfoundation.org> References: <20180226202144.375869933@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.14-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 @@ -647,12 +647,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; @@ -685,6 +694,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; @@ -696,12 +714,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; } @@ -722,8 +736,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; }