Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp8103416imu; Tue, 4 Dec 2018 03:04:06 -0800 (PST) X-Google-Smtp-Source: AFSGD/WZF4O91cw5Jr2Nubw8hTdwrItaQJmGla3ZSMFjLJSFIQjsv1fVc6VtHstY/SFZAyLkprb5 X-Received: by 2002:a17:902:24e7:: with SMTP id l36mr7925656plg.61.1543921446640; Tue, 04 Dec 2018 03:04:06 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543921446; cv=none; d=google.com; s=arc-20160816; b=ydn+V+Da2huRAnVKGZJfuMHNyps5BL4jb/UODMHO72coLzorzg/i7jvE5AMvIry8U+ VYn5a4CoVKr9BvQ00IyDNbkhZ5pSHzssuQPiF1xiTLoO9YRv/euF+0guiSa7DY/U9ccZ Uvzh1F1b4VWjEt4SyP1EgiL1WL3fZNqPhxMSDvszHSYWdgYfe2M5+g2ZMnq9Cp3IdIR3 yE235vnXIXaQ27Tlqbrg5613neU9DuyaCD/J9q2FLaL8PLxktJojtmhXGeChbQn1/DHq stkiqmObGRy72Ed89Kj/JalApjwYBvuckjwS6O16CLoSsjqdeMZvjIK20isPdCuO9PoA sodg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=45RaW7XdSBE8ed+Dkf730v5XHMt9h3dN1JGE5RMxOrA=; b=u5YLr3PC5Yk/Vhgl7l7MpU1C7ciF79IYFGHajdTyajhBVEIEyiYIUmCHyRS9WAU8qY Lf8xI12fIiyhTIer1Xx0NHdPKSyaFpQ/uKnz3mXkJRHYCaItumzCgjAwwH2NPRedLrKT A4PySUx7KtGPgFuMibe7kL5f/gs0nAg3bs4SXeDxtoA4EovtWxyIXzv7TgMfABUgSiBG C0h2Ms5GImJKhq00V4JSpF5knHd1RF2nSD/rqiCu2Jl0tvcLTIpG2gf9+JZmAyXkfJfb U1BNgav3P8LO6NkGEsPrPxxpVB9gEOupiSYR0eyLRKMzkTsgQOqScZF09lTo+e2Ta/gW 7d7A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=2Lgk1Gm7; 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 w12si17100957pfn.212.2018.12.04.03.03.50; Tue, 04 Dec 2018 03:04:06 -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; dkim=pass header.i=@kernel.org header.s=default header.b=2Lgk1Gm7; 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 S1727419AbeLDLBC (ORCPT + 99 others); Tue, 4 Dec 2018 06:01:02 -0500 Received: from mail.kernel.org ([198.145.29.99]:46406 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727411AbeLDLBA (ORCPT ); Tue, 4 Dec 2018 06:01:00 -0500 Received: from localhost (5356596B.cm-6-7b.dynamic.ziggo.nl [83.86.89.107]) (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 2248A2087F; Tue, 4 Dec 2018 11:00:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1543921259; bh=VsoaOVQnW1YnJtYXX3R/mG+wg5NjMFAxPo7/AUscGNo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=2Lgk1Gm73xfF5BMW/gS9XEruSIZRsFzGBQuySgrf/VlHb0gye5+lH/6O0WnIVYxQU KvNHzmgAlXQhvtWzhK2cf7jmjFrnGgViFHYAJ8J4IE03INZcUojVlr26JPNMxtJv7z F7NTgrAdLAOffct7Qcqf0o5e/wTiWpNAxxIaD4Oo= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Todd Kjos , =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= Subject: [PATCH 4.19 116/139] binder: fix race that allows malicious free of live buffer Date: Tue, 4 Dec 2018 11:49:57 +0100 Message-Id: <20181204103655.392475051@linuxfoundation.org> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181204103649.950154335@linuxfoundation.org> References: <20181204103649.950154335@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review X-Patchwork-Hint: ignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.19-stable review patch. If anyone has any objections, please let me know. ------------------ From: Todd Kjos commit 7bada55ab50697861eee6bb7d60b41e68a961a9c upstream. Malicious code can attempt to free buffers using the BC_FREE_BUFFER ioctl to binder. There are protections against a user freeing a buffer while in use by the kernel, however there was a window where BC_FREE_BUFFER could be used to free a recently allocated buffer that was not completely initialized. This resulted in a use-after-free detected by KASAN with a malicious test program. This window is closed by setting the buffer's allow_user_free attribute to 0 when the buffer is allocated or when the user has previously freed it instead of waiting for the caller to set it. The problem was that when the struct buffer was recycled, allow_user_free was stale and set to 1 allowing a free to go through. Signed-off-by: Todd Kjos Acked-by: Arve Hjønnevåg Cc: stable # 4.14 Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/android/binder.c | 21 ++++++++++++--------- drivers/android/binder_alloc.c | 16 ++++++---------- drivers/android/binder_alloc.h | 3 +-- 3 files changed, 19 insertions(+), 21 deletions(-) --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2971,7 +2971,6 @@ static void binder_transaction(struct bi t->buffer = NULL; goto err_binder_alloc_buf_failed; } - t->buffer->allow_user_free = 0; t->buffer->debug_id = t->debug_id; t->buffer->transaction = t; t->buffer->target_node = target_node; @@ -3465,14 +3464,18 @@ static int binder_thread_write(struct bi buffer = binder_alloc_prepare_to_free(&proc->alloc, data_ptr); - if (buffer == NULL) { - binder_user_error("%d:%d BC_FREE_BUFFER u%016llx no match\n", - proc->pid, thread->pid, (u64)data_ptr); - break; - } - if (!buffer->allow_user_free) { - binder_user_error("%d:%d BC_FREE_BUFFER u%016llx matched unreturned buffer\n", - proc->pid, thread->pid, (u64)data_ptr); + if (IS_ERR_OR_NULL(buffer)) { + if (PTR_ERR(buffer) == -EPERM) { + binder_user_error( + "%d:%d BC_FREE_BUFFER u%016llx matched unreturned or currently freeing buffer\n", + proc->pid, thread->pid, + (u64)data_ptr); + } else { + binder_user_error( + "%d:%d BC_FREE_BUFFER u%016llx no match\n", + proc->pid, thread->pid, + (u64)data_ptr); + } break; } binder_debug(BINDER_DEBUG_FREE_BUFFER, --- a/drivers/android/binder_alloc.c +++ b/drivers/android/binder_alloc.c @@ -151,16 +151,12 @@ static struct binder_buffer *binder_allo else { /* * Guard against user threads attempting to - * free the buffer twice + * free the buffer when in use by kernel or + * after it's already been freed. */ - if (buffer->free_in_progress) { - binder_alloc_debug(BINDER_DEBUG_USER_ERROR, - "%d:%d FREE_BUFFER u%016llx user freed buffer twice\n", - alloc->pid, current->pid, - (u64)user_ptr); - return NULL; - } - buffer->free_in_progress = 1; + if (!buffer->allow_user_free) + return ERR_PTR(-EPERM); + buffer->allow_user_free = 0; return buffer; } } @@ -500,7 +496,7 @@ static struct binder_buffer *binder_allo rb_erase(best_fit, &alloc->free_buffers); buffer->free = 0; - buffer->free_in_progress = 0; + buffer->allow_user_free = 0; binder_insert_allocated_buffer_locked(alloc, buffer); binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, "%d: binder_alloc_buf size %zd got %pK\n", --- a/drivers/android/binder_alloc.h +++ b/drivers/android/binder_alloc.h @@ -50,8 +50,7 @@ struct binder_buffer { unsigned free:1; unsigned allow_user_free:1; unsigned async_transaction:1; - unsigned free_in_progress:1; - unsigned debug_id:28; + unsigned debug_id:29; struct binder_transaction *transaction;