Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp6444365imu; Wed, 30 Jan 2019 15:02:57 -0800 (PST) X-Google-Smtp-Source: ALg8bN4wnsMEz0QaqsuPLPtVWh5PlRkO8ri3cuTWWL7fNNoXfivjtzW260yBo7i4ZOUWN2PrIwVv X-Received: by 2002:a63:1444:: with SMTP id 4mr29519776pgu.430.1548889377782; Wed, 30 Jan 2019 15:02:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548889377; cv=none; d=google.com; s=arc-20160816; b=kjHxtHAIeRYWMr7UlxHystXH4Ml4x08VTIcNNKiIG9vtIvniT90mlsN/e8Miy7lxtW 8NzprAfH6arh58W6aw4bkFvAOm6k1obaE+G91Ne7rxTg/KhyOftGWdO5ly+AygVS4J9p Ok1w0QgcUj7L8BEkpS6oUNZUS5Q8Ndg+/UZ3wCoehR+DS4/5T72qM0brB0zCjSDtstML 1+Yw4Tl3KMU6eNW7vUcp1yaky8gesP+CCH2zLf1JQ8op0iX6W6sZarlIW/56vmJeD3CC n5m58MMtOvx2YAtJ9OBnyIM1YPcVZ+A7znB2QrwVM3F4KAv6bdWnkjQYiZju013PUJDf hFIw== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=rNMn+pyy2gsaevwWKdrqrFWTffJpE4WOCxp1btViDsU=; b=k0qqLss59BhryqP1Ztd9oInYCDQhvfpHZjmzk0g9a10s68PQtCplXm1whm/wlARNYa MZd7bJEMowzkl6bjFvw36ATbaNtheGcfvrK6QOuwLMPfAc5l0+7aEc7q1K81HoEa/gfJ NwTlUE+H2UoWcU6HMQblwz5/ZEzs836I2efv+HM6cENwpP6jwpjWF8z1GTzlz8S2XDDk EEkCLkR4Cj0GCwIQoamUDy9ZR5UH2JSDqgTjmvJ5fdwHlsJ/hxwzHikp2sNp3faEpxpk hOOz7rS0buDV+atpfJbjg5/Ld/q8Fm7Nc0u1LviKy+iKvbngVsMV7SzXPN1MmpTaIVnN 0dUA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@android.com header.s=20161025 header.b=LxBnHt00; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=android.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g5si2509773plt.273.2019.01.30.15.02.42; Wed, 30 Jan 2019 15:02:57 -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=@android.com header.s=20161025 header.b=LxBnHt00; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=android.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730771AbfA3Wxp (ORCPT + 99 others); Wed, 30 Jan 2019 17:53:45 -0500 Received: from mail-pg1-f193.google.com ([209.85.215.193]:36066 "EHLO mail-pg1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725890AbfA3Wxp (ORCPT ); Wed, 30 Jan 2019 17:53:45 -0500 Received: by mail-pg1-f193.google.com with SMTP id n2so482440pgm.3 for ; Wed, 30 Jan 2019 14:53:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=android.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=rNMn+pyy2gsaevwWKdrqrFWTffJpE4WOCxp1btViDsU=; b=LxBnHt00LaUaUMQhtWHt0VS5vAVYzsqJM2RI1184iHqMax8fmpQ4UbmrpqKrPBbKs9 rqxOWqUMesKW8yBIOdoC+ZFnUlxUiWRqvhM6K6kqcXDdg6ImoY7s03nlg5oAz9ZK7C4a 8YKmp8ZYy0al5uFFJJOWuuZHi2BuQNjrZBzo1SByT93B9zYwSCEYrXHYPjfOISFLBWMe nthck5ZkTmiqWSJqUVkBUj9CY768zN8lAw1Me49O16enmfVC4pXKLES8qZ8WPX81Q5Pz jqIDnjtYWAN91u7kXFm21ZiUlALQwp1miv4vSdENg5bqXXsizm5BwEQ0sSNRz6KzXiCD p5rw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=rNMn+pyy2gsaevwWKdrqrFWTffJpE4WOCxp1btViDsU=; b=oQGburomivQDHulol+1pAYBVBfdwsjkm8UPPCqfL7xVGUGIDvv5jAeRd/6YNlXi/Lb 9lmUZCX3THwvcbSvv1xo33eO8SGuzE/SPdRpZnUJ7WLlER5LTlUTvep0rCubH7kG/vTS EqDmd8NJpHaUQj0IhVpPoVQoBolNRAMCFmUkLqPQueu3QM/a61+ZbIKiWjB5ZTfezGc9 Ogjavi+vx0ZJ4lD+1NnbdnbjQf8vPshrLf8/M3l/vMqkpo2b+OjzyGhm5R5/o/u3tuw2 iMNbJHpxWxYxevfOP8qNPjlnEl7jroqUjPawjXFc6XU1j686Qk0G5c6EctwNGzMZniZk um/g== X-Gm-Message-State: AJcUuke4/EM2B2AkYpjUUQT9bom+T5tkHw5Y4lkryEU1mtLViBn03A4I W75bZ4NGgCyUt2AL2ayerA+EeQ== X-Received: by 2002:a63:9041:: with SMTP id a62mr28591565pge.163.1548888434773; Wed, 30 Jan 2019 14:47:14 -0800 (PST) Received: from ava-linux2.mtv.corp.google.com ([2620:0:1000:1601:6cc0:d41d:b970:fd7]) by smtp.googlemail.com with ESMTPSA id w136sm4219190pfd.169.2019.01.30.14.47.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 30 Jan 2019 14:47:14 -0800 (PST) From: Todd Kjos X-Google-Original-From: Todd Kjos To: tkjos@google.com, gregkh@linuxfoundation.org, arve@android.com, devel@driverdev.osuosl.org, linux-kernel@vger.kernel.org, maco@google.com Cc: joel@joelfernandes.org, kernel-team@android.com Subject: [PATCH v2 3/7] binder: add function to copy binder object from buffer Date: Wed, 30 Jan 2019 14:46:51 -0800 Message-Id: <20190130224655.255149-4-tkjos@google.com> X-Mailer: git-send-email 2.20.1.495.gaa96b0ce6b-goog In-Reply-To: <20190130224655.255149-1-tkjos@google.com> References: <20190130224655.255149-1-tkjos@google.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When creating or tearing down a transaction, the binder driver examines objects in the buffer and takes appropriate action. To do this without needing to dereference pointers into the buffer, the local copies of the objects are needed. This patch introduces a function to validate and copy binder objects from the buffer to a local structure. Signed-off-by: Todd Kjos --- v2: remove casts as suggested by Dan Carpenter drivers/android/binder.c | 75 +++++++++++++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 17 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 74d0c1ff874e..8063b405e4fa 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -628,6 +628,26 @@ struct binder_transaction { spinlock_t lock; }; +/** + * struct binder_object - union of flat binder object types + * @hdr: generic object header + * @fbo: binder object (nodes and refs) + * @fdo: file descriptor object + * @bbo: binder buffer pointer + * @fdao: file descriptor array + * + * Used for type-independent object copies + */ +struct binder_object { + union { + struct binder_object_header hdr; + struct flat_binder_object fbo; + struct binder_fd_object fdo; + struct binder_buffer_object bbo; + struct binder_fd_array_object fdao; + }; +}; + /** * binder_proc_lock() - Acquire outer lock for given binder_proc * @proc: struct binder_proc to acquire @@ -2017,26 +2037,33 @@ static void binder_cleanup_transaction(struct binder_transaction *t, } /** - * binder_validate_object() - checks for a valid metadata object in a buffer. + * binder_get_object() - gets object and checks for valid metadata + * @proc: binder_proc owning the buffer * @buffer: binder_buffer that we're parsing. - * @offset: offset in the buffer at which to validate an object. + * @offset: offset in the @buffer at which to validate an object. + * @object: struct binder_object to read into * * Return: If there's a valid metadata object at @offset in @buffer, the - * size of that object. Otherwise, it returns zero. + * size of that object. Otherwise, it returns zero. The object + * is read into the struct binder_object pointed to by @object. */ -static size_t binder_validate_object(struct binder_buffer *buffer, u64 offset) +static size_t binder_get_object(struct binder_proc *proc, + struct binder_buffer *buffer, + unsigned long offset, + struct binder_object *object) { - /* Check if we can read a header first */ + size_t read_size; struct binder_object_header *hdr; size_t object_size = 0; - if (buffer->data_size < sizeof(*hdr) || - offset > buffer->data_size - sizeof(*hdr) || - !IS_ALIGNED(offset, sizeof(u32))) + read_size = min_t(size_t, sizeof(*object), buffer->data_size - offset); + if (read_size < sizeof(*hdr)) return 0; + binder_alloc_copy_from_buffer(&proc->alloc, object, buffer, + offset, read_size); - /* Ok, now see if we can read a complete object. */ - hdr = (struct binder_object_header *)(buffer->data + offset); + /* Ok, now see if we read a complete object. */ + hdr = &object->hdr; switch (hdr->type) { case BINDER_TYPE_BINDER: case BINDER_TYPE_WEAK_BINDER: @@ -2245,6 +2272,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, for (offp = off_start; offp < off_end; offp++) { struct binder_object_header *hdr; size_t object_size; + struct binder_object object; binder_size_t object_offset; binder_size_t buffer_offset = (uintptr_t)offp - (uintptr_t)buffer->data; @@ -2252,14 +2280,14 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, binder_alloc_copy_from_buffer(&proc->alloc, &object_offset, buffer, buffer_offset, sizeof(object_offset)); - object_size = binder_validate_object(buffer, object_offset); + object_size = binder_get_object(proc, buffer, + object_offset, &object); if (object_size == 0) { pr_err("transaction release %d bad object at offset %lld, size %zd\n", debug_id, (u64)object_offset, buffer->data_size); continue; } - hdr = (struct binder_object_header *) - (buffer->data + object_offset); + hdr = &object.hdr; switch (hdr->type) { case BINDER_TYPE_BINDER: case BINDER_TYPE_WEAK_BINDER: { @@ -3159,6 +3187,7 @@ static void binder_transaction(struct binder_proc *proc, for (; offp < off_end; offp++) { struct binder_object_header *hdr; size_t object_size; + struct binder_object object; binder_size_t object_offset; binder_size_t buffer_offset = (uintptr_t)offp - (uintptr_t)t->buffer->data; @@ -3168,7 +3197,8 @@ static void binder_transaction(struct binder_proc *proc, t->buffer, buffer_offset, sizeof(object_offset)); - object_size = binder_validate_object(t->buffer, object_offset); + object_size = binder_get_object(target_proc, t->buffer, + object_offset, &object); if (object_size == 0 || object_offset < off_min) { binder_user_error("%d:%d got transaction with invalid offset (%lld, min %lld max %lld) or object.\n", proc->pid, thread->pid, @@ -3181,8 +3211,7 @@ static void binder_transaction(struct binder_proc *proc, goto err_bad_offset; } - hdr = (struct binder_object_header *) - (t->buffer->data + object_offset); + hdr = &object.hdr; off_min = object_offset + object_size; switch (hdr->type) { case BINDER_TYPE_BINDER: @@ -3197,6 +3226,9 @@ static void binder_transaction(struct binder_proc *proc, return_error_line = __LINE__; goto err_translate_failed; } + binder_alloc_copy_to_buffer(&target_proc->alloc, + t->buffer, object_offset, + fp, sizeof(*fp)); } break; case BINDER_TYPE_HANDLE: case BINDER_TYPE_WEAK_HANDLE: { @@ -3210,6 +3242,9 @@ static void binder_transaction(struct binder_proc *proc, return_error_line = __LINE__; goto err_translate_failed; } + binder_alloc_copy_to_buffer(&target_proc->alloc, + t->buffer, object_offset, + fp, sizeof(*fp)); } break; case BINDER_TYPE_FD: { @@ -3226,6 +3261,9 @@ static void binder_transaction(struct binder_proc *proc, goto err_translate_failed; } fp->pad_binder = 0; + binder_alloc_copy_to_buffer(&target_proc->alloc, + t->buffer, object_offset, + fp, sizeof(*fp)); } break; case BINDER_TYPE_FDA: { struct binder_fd_array_object *fda = @@ -3310,7 +3348,10 @@ static void binder_transaction(struct binder_proc *proc, return_error_line = __LINE__; goto err_translate_failed; } - last_fixup_obj = bp; + binder_alloc_copy_to_buffer(&target_proc->alloc, + t->buffer, object_offset, + bp, sizeof(*bp)); + last_fixup_obj = t->buffer->data + object_offset; last_fixup_min_off = 0; } break; default: -- 2.20.1.495.gaa96b0ce6b-goog