Received: by 10.223.185.116 with SMTP id b49csp4184599wrg; Mon, 26 Feb 2018 12:45:55 -0800 (PST) X-Google-Smtp-Source: AH8x227+GuDZDT1cSwJBJm5YW0tiMHLr//oQjimtndvnEKmAYQLk0WZg89MrYTMabCuDq5KTMkSq X-Received: by 2002:a17:902:424:: with SMTP id 33-v6mr11637157ple.57.1519677955484; Mon, 26 Feb 2018 12:45:55 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519677955; cv=none; d=google.com; s=arc-20160816; b=Fj6tDQxlpdicMOh6V445+7W2E/bb9Bq5WoM1hmH7ttAC22letPQVO4sq3XCau2B/ur wC/xJRO2PSG8u7Zb4wRXssM66V9OFN5c7J5cFL4tEcWn7s77vLTgtpZJYDnFSqCZZ+ue D1NkS838EjqN92PQEBSCPy2mw5YODroBhfp+2fiTQQ/ja/Aa+rHZKlN9Rhv1qTOUBGel ITSsP4W1eT4Pe2+6SNU3kAzQ2KmZUfKvTFYa99SOVQFoDodEC6+ubDbIr73JTJ5jS3zr +C97x2oAM8sZCW/AaaziGjsJgOjn0/ov5aPZ+BsRRMDNe2qasa3q3qOJltQP4eu2qXOu G45g== 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=719SpqiG6DCboDkP4aS8lbkoNzl/nUqrHNb49L7oV6s=; b=LJUOptDz3Plck2AUsaOX1ShL277xOcY4eCXWP5g0koYug1grkLtXlMuW1x/PDKDZm5 TsmjB85kGW2Gddu+Eze4KQbhHPtHLQ58UlvOk4avwFrbqnyRLWCZyQhxy6/58PRJURzx kDw7QyRZhZj1XotMHcVtL1iWmVTTZTf3L7lFJTAmyrOWP7gec3+wtOuT2vbYnkLWx01L R0qLCOPWDTj5QRLBmmIJa4PNQUPeZO3OBD47Qns+mvv6/3jEgvnb4RTifeN3X8t7qC9a hDIGko7wfQBnHgmnFtBSDTMDakgRJCDQkcoy4y0QaktfWEZYdbIM+YP8A1qDM8UfICPM z6PA== 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 q9si5979262pgc.623.2018.02.26.12.45.38; Mon, 26 Feb 2018 12:45:55 -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 S1753464AbeBZU0f (ORCPT + 99 others); Mon, 26 Feb 2018 15:26:35 -0500 Received: from mail.linuxfoundation.org ([140.211.169.12]:35744 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753389AbeBZU0d (ORCPT ); Mon, 26 Feb 2018 15:26:33 -0500 Received: from localhost (clnet-b04-243.ikbnet.co.at [83.175.124.243]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 04C51FFC; Mon, 26 Feb 2018 20:26:32 +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.15 18/64] RDMA/uverbs: Protect from command mask overflow Date: Mon, 26 Feb 2018 21:21:55 +0100 Message-Id: <20180226202154.221410409@linuxfoundation.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180226202153.453363333@linuxfoundation.org> References: <20180226202153.453363333@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.15-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 @@ -648,12 +648,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; @@ -686,6 +695,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; @@ -697,12 +715,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; } @@ -723,8 +737,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; }