From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.1 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A8332C7618B for ; Fri, 26 Jul 2019 13:47:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8276E22CE5 for ; Fri, 26 Jul 2019 13:47:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1564148836; bh=KksOCRP5oAAMVGFAqWVrf0Id1TYALXnhRYE2PxfZghw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=FW8bUm4SSkrLjmYy7yZFrPh/cpYbf0uCz8Jxh37n/KqYjxlY3pbaAM0LOujc1uSH4 1UYnZwkD2jgP4e1JY5J9fW+tcfcQoNPTEL1BHf55hsg9diWmTzmLb5cgU4GQTwMLUE zmUzZVIibafOSYKpNxSupOado8sB+Ptbx2wCRzYc= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388330AbfGZNrP (ORCPT ); Fri, 26 Jul 2019 09:47:15 -0400 Received: from mail.kernel.org ([198.145.29.99]:55446 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388639AbfGZNqG (ORCPT ); Fri, 26 Jul 2019 09:46:06 -0400 Received: from sasha-vm.mshome.net (c-73-47-72-35.hsd1.nh.comcast.net [73.47.72.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id DD02F22CEB; Fri, 26 Jul 2019 13:46:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1564148765; bh=KksOCRP5oAAMVGFAqWVrf0Id1TYALXnhRYE2PxfZghw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jOk4QPj6MRCzPisdduveUsBw4O0kcg98OaCuPRlr632C6jERMjVZGByCvY4roQm4d TXbOzHwkqwStDAV7z0vq+bGBm6qZZ1LQGEZn0icXxHrppr0+pHz4gzboN/F5aIUZ0S 6AxHGarBF9R/EUZ4DPgeMayi9Qe+UiPGih4B1H7s= From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Kees Cook , Andreas Christoforou , "Eric W. Biederman" , Al Viro , Arnd Bergmann , Davidlohr Bueso , Manfred Spraul , Andrew Morton , Linus Torvalds , Sasha Levin Subject: [PATCH AUTOSEL 4.4 20/23] ipc/mqueue.c: only perform resource calculation if user valid Date: Fri, 26 Jul 2019 09:45:19 -0400 Message-Id: <20190726134522.13308-20-sashal@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190726134522.13308-1-sashal@kernel.org> References: <20190726134522.13308-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Kees Cook [ Upstream commit a318f12ed8843cfac53198390c74a565c632f417 ] Andreas Christoforou reported: UBSAN: Undefined behaviour in ipc/mqueue.c:414:49 signed integer overflow: 9 * 2305843009213693951 cannot be represented in type 'long int' ... Call Trace: mqueue_evict_inode+0x8e7/0xa10 ipc/mqueue.c:414 evict+0x472/0x8c0 fs/inode.c:558 iput_final fs/inode.c:1547 [inline] iput+0x51d/0x8c0 fs/inode.c:1573 mqueue_get_inode+0x8eb/0x1070 ipc/mqueue.c:320 mqueue_create_attr+0x198/0x440 ipc/mqueue.c:459 vfs_mkobj+0x39e/0x580 fs/namei.c:2892 prepare_open ipc/mqueue.c:731 [inline] do_mq_open+0x6da/0x8e0 ipc/mqueue.c:771 Which could be triggered by: struct mq_attr attr = { .mq_flags = 0, .mq_maxmsg = 9, .mq_msgsize = 0x1fffffffffffffff, .mq_curmsgs = 0, }; if (mq_open("/testing", 0x40, 3, &attr) == (mqd_t) -1) perror("mq_open"); mqueue_get_inode() was correctly rejecting the giant mq_msgsize, and preparing to return -EINVAL. During the cleanup, it calls mqueue_evict_inode() which performed resource usage tracking math for updating "user", before checking if there was a valid "user" at all (which would indicate that the calculations would be sane). Instead, delay this check to after seeing a valid "user". The overflow was real, but the results went unused, so while the flaw is harmless, it's noisy for kernel fuzzers, so just fix it by moving the calculation under the non-NULL "user" where it actually gets used. Link: http://lkml.kernel.org/r/201906072207.ECB65450@keescook Signed-off-by: Kees Cook Reported-by: Andreas Christoforou Acked-by: "Eric W. Biederman" Cc: Al Viro Cc: Arnd Bergmann Cc: Davidlohr Bueso Cc: Manfred Spraul Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin --- ipc/mqueue.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 6ed74825ab54..2a39784d5704 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -371,7 +371,6 @@ static void mqueue_evict_inode(struct inode *inode) { struct mqueue_inode_info *info; struct user_struct *user; - unsigned long mq_bytes, mq_treesize; struct ipc_namespace *ipc_ns; struct msg_msg *msg, *nmsg; LIST_HEAD(tmp_msg); @@ -394,16 +393,18 @@ static void mqueue_evict_inode(struct inode *inode) free_msg(msg); } - /* Total amount of bytes accounted for the mqueue */ - mq_treesize = info->attr.mq_maxmsg * sizeof(struct msg_msg) + - min_t(unsigned int, info->attr.mq_maxmsg, MQ_PRIO_MAX) * - sizeof(struct posix_msg_tree_node); - - mq_bytes = mq_treesize + (info->attr.mq_maxmsg * - info->attr.mq_msgsize); - user = info->user; if (user) { + unsigned long mq_bytes, mq_treesize; + + /* Total amount of bytes accounted for the mqueue */ + mq_treesize = info->attr.mq_maxmsg * sizeof(struct msg_msg) + + min_t(unsigned int, info->attr.mq_maxmsg, MQ_PRIO_MAX) * + sizeof(struct posix_msg_tree_node); + + mq_bytes = mq_treesize + (info->attr.mq_maxmsg * + info->attr.mq_msgsize); + spin_lock(&mq_lock); user->mq_bytes -= mq_bytes; /* -- 2.20.1