Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp9093604pxu; Mon, 28 Dec 2020 06:29:20 -0800 (PST) X-Google-Smtp-Source: ABdhPJwlJMrccMPZ6sE8Qdu68YxMLc5p7OMzgb5nomRJ6sxuwqZ/iH87f10dBr43A3/KFo1IoUDy X-Received: by 2002:a50:c3c5:: with SMTP id i5mr42603799edf.166.1609165760485; Mon, 28 Dec 2020 06:29:20 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1609165760; cv=none; d=google.com; s=arc-20160816; b=KaaowgRCKM8LkDqyJgMUnPtHapj482+ieX8cCksylBmZEBfYoqVURF/Bol6ZOHhdZz uw3RnhKK2skRJhp0t07HtVRTyt72EAM0v4kNGjOpDw4PM0Zj7BJWgSVmvz+J+bA3M789 l7zBBQ//zvIEoQBC7LpMzpvxPOv/xFL7CPydEej/yYwRScN7C8dWm4ofBFXQCa7pUAzo JLxpiiwZPXDhcv4PrbHlTw5u0NcE1rrB4yeiQdXgTPQhirb0h6s+BGyTuinOnjg4YCvR o6pE4eU/pwF9nR3pUGvxMcuM5hy1ZDNbsOJrqRRbkDsCfIiVeyCPEHO7Y4+8zZGpY7E1 1ZlA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=VcEX0TvNGyMaM22MpNY5a/N7kaablR4CbuhqhKIhdck=; b=i/7T3TdqyhIMp9EQIpr6l+Nz4lWXSCRGzxRRynEjNjxMRvPW3EnYHnArTSJnRuXLAD PNMu4/3V/QA/VqXx/DmWTAl1OrcRgbJw/utqWIGpcVfk3ovm9fozCCZ64v04A3S4s3fg dBa9hMCmkFuKqMJ8y4sYaIvX+d0BmnI6+Zau0lYlCTe7txDgLg+A4RfDvPJ8Uq9M/lCd SJ6rvIsVgAAauSMst6e0x0shBY1m9eFdhwIc65okgSryUUqvfzU1jMrD1OGi4ZRVwbZ7 bhb2F4lxHQIWkIr67rKuewMS2ca0CtB4kk1DT6iRWPSFHR0Xdb5+m2gfMTV8FyrljAjJ 4UsA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=sUypuMdj; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id bm3si19190155edb.188.2020.12.28.06.28.55; Mon, 28 Dec 2020 06:29:20 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=sUypuMdj; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2503341AbgL1O0O (ORCPT + 99 others); Mon, 28 Dec 2020 09:26:14 -0500 Received: from mail.kernel.org ([198.145.29.99]:33738 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2503331AbgL1OZz (ORCPT ); Mon, 28 Dec 2020 09:25:55 -0500 Received: by mail.kernel.org (Postfix) with ESMTPSA id B8DB022AEC; Mon, 28 Dec 2020 14:25:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1609165514; bh=R7hPqRPRgIIrkzn0lvGXXPQkYZa7EbjSF48MeX3NhJA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sUypuMdjJ/m4NQYG1MYkiFhLVMmFUTjjwHU7rowJ3cOFB3izt+fH9dgRZw1oiQbiv WhYCO/NyVRBNlL5nrG0qYs0EAGEDWSHjxGsnSpi4BwQ/WSxBxjyLpezkgdyTcMpgfh ecKUsVPV4sHmtT3ICplCy2Ycr5MmzGxUO9/Nm3ls= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Todd Kjos Subject: [PATCH 5.10 559/717] binder: add flag to clear buffer on txn complete Date: Mon, 28 Dec 2020 13:49:17 +0100 Message-Id: <20201228125047.705472163@linuxfoundation.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201228125020.963311703@linuxfoundation.org> References: <20201228125020.963311703@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Todd Kjos commit 0f966cba95c78029f491b433ea95ff38f414a761 upstream. Add a per-transaction flag to indicate that the buffer must be cleared when the transaction is complete to prevent copies of sensitive data from being preserved in memory. Signed-off-by: Todd Kjos Link: https://lore.kernel.org/r/20201120233743.3617529-1-tkjos@google.com Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/android/binder.c | 1 drivers/android/binder_alloc.c | 48 ++++++++++++++++++++++++++++++++++++ drivers/android/binder_alloc.h | 4 ++- include/uapi/linux/android/binder.h | 1 4 files changed, 53 insertions(+), 1 deletion(-) --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3146,6 +3146,7 @@ static void binder_transaction(struct bi t->buffer->debug_id = t->debug_id; t->buffer->transaction = t; t->buffer->target_node = target_node; + t->buffer->clear_on_free = !!(t->flags & TF_CLEAR_BUF); trace_binder_transaction_alloc_buf(t->buffer); if (binder_alloc_copy_user_to_buffer( --- a/drivers/android/binder_alloc.c +++ b/drivers/android/binder_alloc.c @@ -696,6 +696,8 @@ static void binder_free_buf_locked(struc binder_insert_free_buffer(alloc, buffer); } +static void binder_alloc_clear_buf(struct binder_alloc *alloc, + struct binder_buffer *buffer); /** * binder_alloc_free_buf() - free a binder buffer * @alloc: binder_alloc for this proc @@ -706,6 +708,18 @@ static void binder_free_buf_locked(struc void binder_alloc_free_buf(struct binder_alloc *alloc, struct binder_buffer *buffer) { + /* + * We could eliminate the call to binder_alloc_clear_buf() + * from binder_alloc_deferred_release() by moving this to + * binder_alloc_free_buf_locked(). However, that could + * increase contention for the alloc mutex if clear_on_free + * is used frequently for large buffers. The mutex is not + * needed for correctness here. + */ + if (buffer->clear_on_free) { + binder_alloc_clear_buf(alloc, buffer); + buffer->clear_on_free = false; + } mutex_lock(&alloc->mutex); binder_free_buf_locked(alloc, buffer); mutex_unlock(&alloc->mutex); @@ -802,6 +816,10 @@ void binder_alloc_deferred_release(struc /* Transaction should already have been freed */ BUG_ON(buffer->transaction); + if (buffer->clear_on_free) { + binder_alloc_clear_buf(alloc, buffer); + buffer->clear_on_free = false; + } binder_free_buf_locked(alloc, buffer); buffers++; } @@ -1136,6 +1154,36 @@ static struct page *binder_alloc_get_pag } /** + * binder_alloc_clear_buf() - zero out buffer + * @alloc: binder_alloc for this proc + * @buffer: binder buffer to be cleared + * + * memset the given buffer to 0 + */ +static void binder_alloc_clear_buf(struct binder_alloc *alloc, + struct binder_buffer *buffer) +{ + size_t bytes = binder_alloc_buffer_size(alloc, buffer); + binder_size_t buffer_offset = 0; + + while (bytes) { + unsigned long size; + struct page *page; + pgoff_t pgoff; + void *kptr; + + page = binder_alloc_get_page(alloc, buffer, + buffer_offset, &pgoff); + size = min_t(size_t, bytes, PAGE_SIZE - pgoff); + kptr = kmap(page) + pgoff; + memset(kptr, 0, size); + kunmap(page); + bytes -= size; + buffer_offset += size; + } +} + +/** * binder_alloc_copy_user_to_buffer() - copy src user to tgt user * @alloc: binder_alloc for this proc * @buffer: binder buffer to be accessed --- a/drivers/android/binder_alloc.h +++ b/drivers/android/binder_alloc.h @@ -23,6 +23,7 @@ struct binder_transaction; * @entry: entry alloc->buffers * @rb_node: node for allocated_buffers/free_buffers rb trees * @free: %true if buffer is free + * @clear_on_free: %true if buffer must be zeroed after use * @allow_user_free: %true if user is allowed to free buffer * @async_transaction: %true if buffer is in use for an async txn * @debug_id: unique ID for debugging @@ -41,9 +42,10 @@ struct binder_buffer { struct rb_node rb_node; /* free entry by size or allocated entry */ /* by address */ unsigned free:1; + unsigned clear_on_free:1; unsigned allow_user_free:1; unsigned async_transaction:1; - unsigned debug_id:29; + unsigned debug_id:28; struct binder_transaction *transaction; --- a/include/uapi/linux/android/binder.h +++ b/include/uapi/linux/android/binder.h @@ -248,6 +248,7 @@ enum transaction_flags { TF_ROOT_OBJECT = 0x04, /* contents are the component's root object */ TF_STATUS_CODE = 0x08, /* contents are a 32-bit status code */ TF_ACCEPT_FDS = 0x10, /* allow replies with file descriptors */ + TF_CLEAR_BUF = 0x20, /* clear buffer on txn complete */ }; struct binder_transaction_data {