Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp2270703imm; Mon, 28 May 2018 05:08:39 -0700 (PDT) X-Google-Smtp-Source: ADUXVKIMUiKj/YfR/DeuN/YxdAS9NguNkvwrtaIaySx07WM4JG1vIGIENHGP+lgtIUBuuHvC0bxZ X-Received: by 2002:a17:902:b216:: with SMTP id t22-v6mr9628253plr.199.1527509319001; Mon, 28 May 2018 05:08:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527509318; cv=none; d=google.com; s=arc-20160816; b=bAcfPCm0HdQUU32Po+b/dXZ2JsWnw9cy9qR+XoXphD9mpOz6HxdNwcDsiRLFOfPirG uZLtujRpetfGNbEFAUrXfAGOJHjCu0Mr2Q1LB3qNlzyIbuQu2adxG4OvScHGZbMc18Uu duk8DheUWSALVlOCwg594/pM2vjK0qBISHNgyg3/nkobkNHVPr38aHEJUqMYGU8Jqja4 HTI33vcdb9QcPFgxFu5PkfdxA2ItXc5W1GCfGY2yIItwAd+4uh5miyFaJ0QK+Cbm+DvO XaHfWP16koGGdw7aVQ5eUPq3p4n9GOJG8Mlbt/+IXmit1CLVOWSXPvDdXkUXVnkMwgeP UCsw== 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:dkim-signature :arc-authentication-results; bh=MQoKAmiemUhO4nMvRx0xHx7iOEfMF7GlJd05Dkkwq6A=; b=wcdP5AD1c9q3LAbEpESDWOQqFYc/KVUVJx495YbbjKz0gowLuB3sujoMtl+Cy1sTg8 cSiAMwGXJTVq/QMdQsA+5NuXiiIxSV3/RVZIlHPdJ6BwPhhZDGo7mAe931xNrZLvn39e HqBE53ZZt7N8O2YOEkjSTuQUXgzuyAlzikW2Yr309yinVBPEJOPKTarHCzHhIt2bbBUQ wzbsMcSZ36pS0iK8JHyvfDm2ixOVWAi5EhaWEBU9d0xvjMoDktOixf6a2tcbsUMvd5VR /4VDX/JeLE/ZfrFE0gKIUcFq9bx7jKefyl97ygXW/OTnw/LkHGkI+WPUdWAUZU9ZxYt+ iQPg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=VUo1QzxA; 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 h3-v6si7664675pgc.571.2018.05.28.05.08.24; Mon, 28 May 2018 05:08:38 -0700 (PDT) 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; dkim=pass header.i=@kernel.org header.s=default header.b=VUo1QzxA; 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 S1423200AbeE1MHi (ORCPT + 99 others); Mon, 28 May 2018 08:07:38 -0400 Received: from mail.kernel.org ([198.145.29.99]:52348 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1423097AbeE1LFS (ORCPT ); Mon, 28 May 2018 07:05:18 -0400 Received: from localhost (LFbn-1-12247-202.w90-92.abo.wanadoo.fr [90.92.61.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id E8F7A2087E; Mon, 28 May 2018 11:05:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1527505517; bh=fXG6QErZNZ0uoU9nyB3TIpN2qZnWXOimt3yfSVkZsuA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VUo1QzxArty+Vi43SdZG9l3SyDmi9mO3XtMeufh3Q1lfE52pGnlSNpdge3oKyJYkF a/+OJG3p9tBd/1FrEeJ873eNK+WWXa1qAmcQzXS0H/wMy0mqRDSl+KmYqBYz9SUjay 91Rdcx2pc9CFOsxyC+KVP6wCpHyiITBYgfPQUMMY= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, syzbot+35666cba7f0a337e2e79@syzkaller.appspotmail.com, Matthew Wilcox , Andrew Morton , Linus Torvalds Subject: [PATCH 4.16 031/272] idr: fix invalid ptr dereference on item delete Date: Mon, 28 May 2018 12:01:04 +0200 Message-Id: <20180528100243.344810743@linuxfoundation.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180528100240.256525891@linuxfoundation.org> References: <20180528100240.256525891@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.16-stable review patch. If anyone has any objections, please let me know. ------------------ From: Matthew Wilcox commit 7a4deea1aa8bddfed4ef1b35fc2b6732563d8ad5 upstream. If the radix tree underlying the IDR happens to be full and we attempt to remove an id which is larger than any id in the IDR, we will call __radix_tree_delete() with an uninitialised 'slot' pointer, at which point anything could happen. This was easiest to hit with a single entry at id 0 and attempting to remove a non-0 id, but it could have happened with 64 entries and attempting to remove an id >= 64. Roman said: The syzcaller test boils down to opening /dev/kvm, creating an eventfd, and calling a couple of KVM ioctls. None of this requires superuser. And the result is dereferencing an uninitialized pointer which is likely a crash. The specific path caught by syzbot is via KVM_HYPERV_EVENTD ioctl which is new in 4.17. But I guess there are other user-triggerable paths, so cc:stable is probably justified. Matthew added: We have around 250 calls to idr_remove() in the kernel today. Many of them pass an ID which is embedded in the object they're removing, so they're safe. Picking a few likely candidates: drivers/firewire/core-cdev.c looks unsafe; the ID comes from an ioctl. drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c is similar drivers/atm/nicstar.c could be taken down by a handcrafted packet Link: http://lkml.kernel.org/r/20180518175025.GD6361@bombadil.infradead.org Fixes: 0a835c4f090a ("Reimplement IDR and IDA using the radix tree") Reported-by: Debugged-by: Roman Kagan Signed-off-by: Matthew Wilcox Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- lib/radix-tree.c | 4 +++- tools/testing/radix-tree/idr-test.c | 7 +++++++ 2 files changed, 10 insertions(+), 1 deletion(-) --- a/lib/radix-tree.c +++ b/lib/radix-tree.c @@ -2034,10 +2034,12 @@ void *radix_tree_delete_item(struct radi unsigned long index, void *item) { struct radix_tree_node *node = NULL; - void __rcu **slot; + void __rcu **slot = NULL; void *entry; entry = __radix_tree_lookup(root, index, &node, &slot); + if (!slot) + return NULL; if (!entry && (!is_idr(root) || node_tag_get(root, node, IDR_FREE, get_slot_offset(node, slot)))) return NULL; --- a/tools/testing/radix-tree/idr-test.c +++ b/tools/testing/radix-tree/idr-test.c @@ -252,6 +252,13 @@ void idr_checks(void) idr_remove(&idr, 3); idr_remove(&idr, 0); + assert(idr_alloc(&idr, DUMMY_PTR, 0, 0, GFP_KERNEL) == 0); + idr_remove(&idr, 1); + for (i = 1; i < RADIX_TREE_MAP_SIZE; i++) + assert(idr_alloc(&idr, DUMMY_PTR, 0, 0, GFP_KERNEL) == i); + idr_remove(&idr, 1 << 30); + idr_destroy(&idr); + for (i = INT_MAX - 3UL; i < INT_MAX + 1UL; i++) { struct item *item = item_create(i, 0); assert(idr_alloc(&idr, item, i, i + 10, GFP_KERNEL) == i);