All of lore.kernel.org
 help / color / mirror / Atom feed
From: Serban Constantinescu <Serban.Constantinescu@arm.com>
To: Greg KH <gregkh@linuxfoundation.org>
Cc: "arve@android.com" <arve@android.com>,
	"devel@driverdev.osuosl.org" <devel@driverdev.osuosl.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"john.stultz@linaro.org" <john.stultz@linaro.org>,
	"ccross@android.com" <ccross@android.com>,
	Dave Butcher <Dave.Butcher@arm.com>,
	"irogers@google.com" <irogers@google.com>,
	"romlem@android.com" <romlem@android.com>
Subject: Re: [PATCH v1 2/9] staging: android: binder: Add binder_copy_to_user()
Date: Thu, 05 Dec 2013 18:44:55 +0000	[thread overview]
Message-ID: <52A0C9A7.4050405@arm.com> (raw)
In-Reply-To: <20131204231745.GA10410@kroah.com>

On 04/12/13 23:17, Greg KH wrote:
> On Wed, Dec 04, 2013 at 06:09:34PM +0000, Serban Constantinescu wrote:
>> This patch adds binder_copy_to_user() to be used for copying binder
>> commands to user address space. This way we can abstract away the
>> copy_to_user() calls and add separate handling for the compat layer.
>>
>> Signed-off-by: Serban Constantinescu <serban.constantinescu@arm.com>
>> ---
>>   drivers/staging/android/binder.c |   39 ++++++++++++++++++++------------------
>>   1 file changed, 21 insertions(+), 18 deletions(-)
>>
>> diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
>> index 233889c..6fbb340 100644
>> --- a/drivers/staging/android/binder.c
>> +++ b/drivers/staging/android/binder.c
>> @@ -2117,6 +2117,18 @@ static int binder_has_thread_work(struct binder_thread *thread)
>>   		(thread->looper & BINDER_LOOPER_STATE_NEED_RETURN);
>>   }
>>
>> +static int binder_copy_to_user(uint32_t cmd, void *parcel,
>> +			       void __user **ptr, size_t size)
>> +{
>> +	if (put_user(cmd, (uint32_t __user *)*ptr))
>> +		return -EFAULT;
>> +	*ptr += sizeof(uint32_t);
>> +	if (copy_to_user(*ptr, parcel, size))
>> +		return -EFAULT;
>> +	*ptr += size;
>> +	return 0;
>> +}
>
> I know what you are trying to do here, but ick, why not just use the
> structure involved in the copying out here?  Or just copy the thing out
> in one "chunk", not two different calls, which should make this go
> faster, right?

Ick... agree. I do this split here for the compat handling added in the
next patches, where the cmd will have to be converted to a 32bit compat
cmd and the size, parcel ,passed here will change to a 32bit compat
size, parcel.

This patch makes more sense when looking at the following snippet:

*<snippet from patch 9/9>*

> +static int binder_copy_to_user(uint32_t cmd, void *parcel,
> +                              void __user **ptr, size_t size)
> +{
> +       if (!is_compat_task()) {
> +               if (put_user(cmd, (uint32_t __user *)*ptr))
> +                       return -EFAULT;
> +               *ptr += sizeof(uint32_t);
> +               if (copy_to_user(*ptr, parcel, size))
> +                       return -EFAULT;
> +               *ptr += size;
> +               return 0;
> +       }
> +       switch (cmd) {
> +       case BR_INCREFS:
> +       case BR_ACQUIRE:
> +       case BR_RELEASE:
> +       case BR_DECREFS: {
> +               struct binder_ptr_cookie *fp;
> +               struct compat_binder_ptr_cookie tmp;
> +
> +               cmd = compat_change_size(cmd, sizeof(tmp));

Passing the cmd, and the structure to be copied to binder_copy_to_user()
allows me to add this extra handling here. Where, first, cmd is changed
to a compat cmd, and then copied to userspace - i.e:

I change

> cmd = BR_INCREFS = _IOR('r', 7, struct binder_ptr_cookie)

to

> cmd = COMPAT_BR_INCREFS = _IOR('r', 7, struct compat_binder_ptr_cookie)

where

> struct binder_ptr_cookie {
> 	void* ptr;
> 	void* cookie;
> };

and

> struct compat_binder_ptr_cookie {
> 	compat_uptr_t ptr;
> 	compat_uptr_t cookie;
> };

Thus BR_INCREFS will be different between 32bit userspace and 64bit kernel.

> +               BUG_ON((cmd != COMPAT_BR_INCREFS) &&
> +                      (cmd != COMPAT_BR_ACQUIRE) &&
> +                      (cmd != COMPAT_BR_RELEASE) &&
> +                      (cmd != COMPAT_BR_DECREFS));
> +
> +               fp = (struct binder_ptr_cookie *) parcel;
> +               tmp.ptr = ptr_to_compat(fp->ptr);
> +               tmp.cookie = ptr_to_compat(fp->cookie);
> +               if (put_user(cmd, (uint32_t __user *)*ptr))
> +                       return -EFAULT;
> +               *ptr += sizeof(uint32_t);
> +               if (copy_to_user(*ptr, &tmp, sizeof(tmp)))
> +                       return -EFAULT;
> +               *ptr += sizeof(tmp);

Also, since the size of the parcel will differ when copied to a compat
task (32bit userspace) I increment the buffer ptr here, rather then
doing this in binder_thread_read().

This way we can safely move to the next cmd, by incrementing the buffer
ptr accordingly whether 32 or 64bit structures are needed.

*</sippet from patch 9/9>*


>> +
>>   static int binder_thread_read(struct binder_proc *proc,
>>   			      struct binder_thread *thread,
>>   			      void  __user *buffer, size_t size,
>> @@ -2263,15 +2275,12 @@ retry:
>>   				node->has_weak_ref = 0;
>>   			}
>>   			if (cmd != BR_NOOP) {
>> -				if (put_user(cmd, (uint32_t __user *)ptr))
>> -					return -EFAULT;
>> -				ptr += sizeof(uint32_t);
>> -				if (put_user(node->ptr, (void * __user *)ptr))
>> -					return -EFAULT;
>> -				ptr += sizeof(void *);
>> -				if (put_user(node->cookie, (void * __user *)ptr))
>> +				struct binder_ptr_cookie tmp;
>> +
>> +				tmp.ptr = node->ptr;
>> +				tmp.cookie = node->cookie;
>> +				if (binder_copy_to_user(cmd, &tmp, &ptr, sizeof(struct binder_ptr_cookie)))
>>   					return -EFAULT;
>> -				ptr += sizeof(void *);
>
> Are you sure this is correct?  You are now no longer incrementing ptr
> anymore, is that ok with the larger loop here?

Obscure, I should document this in the commit message! It is correct, I
increment the buffer in binder_copy_to_user() with a different size,
depending on whether the structures are copied to 32bit or 64bit
userspace. See above explanation for more detail.

>
>
>>
>>   				binder_stat_br(proc, thread, cmd);
>>   				binder_debug(BINDER_DEBUG_USER_REFS,
>> @@ -2306,12 +2315,10 @@ retry:
>>   				cmd = BR_CLEAR_DEATH_NOTIFICATION_DONE;
>>   			else
>>   				cmd = BR_DEAD_BINDER;
>> -			if (put_user(cmd, (uint32_t __user *)ptr))
>> -				return -EFAULT;
>> -			ptr += sizeof(uint32_t);
>> -			if (put_user(death->cookie, (void * __user *)ptr))
>> +
>> +			if (binder_copy_to_user(cmd, &death->cookie, &ptr, sizeof(void *)))
>>   				return -EFAULT;
>> -			ptr += sizeof(void *);
>> +
>
> Same here, no more ptr incrementing.

See above.
>
>
>>   			binder_stat_br(proc, thread, cmd);
>>   			binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION,
>>   				     "%d:%d %s %p\n",
>> @@ -2373,12 +2380,8 @@ retry:
>>   					ALIGN(t->buffer->data_size,
>>   					    sizeof(void *));
>>
>> -		if (put_user(cmd, (uint32_t __user *)ptr))
>> -			return -EFAULT;
>> -		ptr += sizeof(uint32_t);
>> -		if (copy_to_user(ptr, &tr, sizeof(tr)))
>> +		if (binder_copy_to_user(cmd, &tr, &ptr, sizeof(struct binder_transaction_data)))
>>   			return -EFAULT;
>> -		ptr += sizeof(tr);
>
> And here, no more ptr incrementing.
See above.

Thanks for your feedback Greg,
Serban C


  reply	other threads:[~2013-12-05 18:44 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-12-04 18:09 [PATCH v1 0/9] Android: Add Support for Binder Compat Serban Constantinescu
2013-12-04 18:09 ` [PATCH v1 1/9] staging: android: binder: Move some of the logic into subfunction Serban Constantinescu
2013-12-05  8:00   ` Dan Carpenter
2013-12-05 18:37     ` Serban Constantinescu
2013-12-05  8:18   ` Dan Carpenter
2013-12-05 15:31     ` Greg KH
2013-12-05 18:35     ` Serban Constantinescu
2013-12-04 18:09 ` [PATCH v1 2/9] staging: android: binder: Add binder_copy_to_user() Serban Constantinescu
2013-12-04 23:17   ` Greg KH
2013-12-05 18:44     ` Serban Constantinescu [this message]
2013-12-05  8:36   ` Dan Carpenter
2013-12-04 18:09 ` [PATCH v1 3/9] staging: android: binder: Add cmd == CMD_NAME handling Serban Constantinescu
2013-12-05  8:40   ` Dan Carpenter
2013-12-05 18:50     ` Serban Constantinescu
2013-12-04 18:09 ` [PATCH v1 4/9] staging: android: binder: Add align_helper() macro Serban Constantinescu
2013-12-05  8:41   ` Dan Carpenter
2013-12-04 18:09 ` [PATCH v1 5/9] staging: android: binder: Add deref_helper() macro Serban Constantinescu
2013-12-04 18:09 ` [PATCH v1 6/9] staging: android: binder: Add size_helper() macro Serban Constantinescu
2013-12-04 18:09 ` [PATCH v1 7/9] staging: android: binder: Add copy_flat_binder_object() Serban Constantinescu
2013-12-04 18:09 ` [PATCH v1 8/9] staging: android: binder: Add binder compat handling to binder.h Serban Constantinescu
2013-12-04 18:09 ` [PATCH v1 9/9] staging: android: binder: Add binder compat layer Serban Constantinescu
2013-12-04 18:35   ` Greg KH
2013-12-04 20:46     ` Colin Cross
2013-12-04 21:43       ` Greg KH
2013-12-04 21:55         ` Colin Cross
2013-12-04 22:02           ` Greg KH
2013-12-04 22:22             ` Colin Cross
2013-12-05  0:02               ` Greg KH
2013-12-05  0:21                 ` Colin Cross
2013-12-05  2:02             ` Arve Hjønnevåg
2013-12-05 18:31               ` Serban Constantinescu
2013-12-05 18:49                 ` Greg KH
2013-12-10  3:01               ` Octavian Purdila
2013-12-11  3:21                 ` Arve Hjønnevåg
2013-12-11 18:10                   ` Octavian Purdila
2013-12-11 23:00                     ` Arve Hjønnevåg
2013-12-12  8:45                       ` Octavian Purdila
2013-12-13  5:14                         ` Arve Hjønnevåg
2013-12-13  7:39                           ` Octavian Purdila
2013-12-04 23:21     ` One Thousand Gnomes
2013-12-04 23:40       ` Colin Cross
2013-12-05  0:32         ` One Thousand Gnomes

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=52A0C9A7.4050405@arm.com \
    --to=serban.constantinescu@arm.com \
    --cc=Dave.Butcher@arm.com \
    --cc=arve@android.com \
    --cc=ccross@android.com \
    --cc=devel@driverdev.osuosl.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=irogers@google.com \
    --cc=john.stultz@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=romlem@android.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.