All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chris Metcalf <cmetcalf@ezchip.com>
To: Catalin Marinas <catalin.marinas@arm.com>
Cc: linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org,
	ralf@linux-mips.org, benh@kernel.crashing.org, deller@gmx.de,
	"dingtianhong@huawei.com" <dingtianhong@huawei.com>,
	heiko.carstens@de.ibm.com, jejb@parisc-linux.org,
	Will Deacon <Will.Deacon@arm.com>,
	"lizefan@huawei.com" <lizefan@huawei.com>,
	Bamvor Jian Zhang <bamvor.zhangjian@huawei.com>,
	mpe@ellerman.id.au, hpa@zytor.com, schwidefsky@de.ibm.com,
	paulus@samba.org, tglx@linutronix.de, mingo@redhat.com,
	davem@davemloft.net,
	"linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>Martin Schwidefsky
	<schwidefsky@de.ibm.com>Heiko Carstens
	<heiko.carstens@de.ibm.com>"James E.J. Bottomley"
	<jejb@parisc-linux.org>Helge Deller <deller@gmx.de>
Subject: Re: [PATCH] tile: use si_int instead of si_ptr for compat_siginfo
Date: Tue, 24 Mar 2015 16:51:36 -0400	[thread overview]
Message-ID: <5511CE58.3020507@ezchip.com> (raw)
In-Reply-To: <20150323120253.GA12757@e104818-lin.cambridge.arm.com>

(+s390 and parisc maintainers)

On 03/23/2015 08:02 AM, Catalin Marinas wrote:
> On Mon, Mar 16, 2015 at 03:04:05PM -0400, Chris Metcalf wrote:
>> To be compatible with the generic get_compat_sigevent(), the
>> copy_siginfo_to_user32() and thus copy_siginfo_from_user32()
>> have to use si_int instead of si_ptr.  Using si_ptr means that
>> for the case of ILP32 compat code running in big-endian mode,
>> we would end up copying the high 32 bits of the pointer value
>> into si_int instead of the desired low 32 bits.
>>
>> Signed-off-by: Chris Metcalf <cmetcalf@ezchip.com>
>> Cc: Catalin Marinas <catalin.marinas@arm.com>
>> ---
>>   arch/tile/kernel/compat_signal.c | 9 +++------
>>   1 file changed, 3 insertions(+), 6 deletions(-)
>>
>> diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c
>> index 8c5abf2e4794..bca13054afb4 100644
>> --- a/arch/tile/kernel/compat_signal.c
>> +++ b/arch/tile/kernel/compat_signal.c
>> @@ -68,7 +68,7 @@ int copy_siginfo_to_user32(struct compat_siginfo __user *to, const siginfo_t *fr
>>   	if (from->si_code < 0) {
>>   		err |= __put_user(from->si_pid, &to->si_pid);
>>   		err |= __put_user(from->si_uid, &to->si_uid);
>> -		err |= __put_user(ptr_to_compat(from->si_ptr), &to->si_ptr);
>> +		err |= __put_user(from->si_int, &to->si_int);
>>   	} else {
>>   		/*
>>   		 * First 32bits of unions are always present:
>> @@ -93,8 +93,7 @@ int copy_siginfo_to_user32(struct compat_siginfo __user *to, const siginfo_t *fr
>>   			break;
>>   		case __SI_TIMER >> 16:
>>   			err |= __put_user(from->si_overrun, &to->si_overrun);
>> -			err |= __put_user(ptr_to_compat(from->si_ptr),
>> -					  &to->si_ptr);
>> +			err |= __put_user(from->si_int, &to->si_int);
>>   			break;
> It's usually the __SI_TIMER and __SI_MESGQ cases that matters here (the
> latter already handled). I'm not entirely sure about the si_code < 0
> change.

To be honest, I'm not even sure what path sets si_code < 0.  I see
that that is SI_FROMUSER(), but I don't see where it gets set.

In any case, I guess a risk here is that of a 64-bit process doing a 
sigqueue()
targeting a 32-bit process.  It seems like an impossible problem for the
32-bit process to know whether the 64-bit process wrote a 32-bit pointer
to the 64-bit sival_ptr field (and thus we should deliver the second 32-bit
word of the union sigval to the 32-bit user), or if the 64-bit process wrote
a 32-bit value to the 32-bit sival_int field (and thus we should deliver 
the
first 32-bit word of the union sigval).  Little-endian makes some things
a little bit easier :-)

All that said, my inclination is to use si_int here just because that's what
we're using elsewhere.  But I'm not entirely sure either.

>>   			 /* This is not generated by the kernel as of now.  */
>>   		case __SI_RT >> 16:
>> @@ -110,7 +109,6 @@ int copy_siginfo_to_user32(struct compat_siginfo __user *to, const siginfo_t *fr
>>   int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from)
>>   {
>>   	int err;
>> -	u32 ptr32;
>>   
>>   	if (!access_ok(VERIFY_READ, from, sizeof(struct compat_siginfo)))
>>   		return -EFAULT;
>> @@ -121,8 +119,7 @@ int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from)
>>   
>>   	err |= __get_user(to->si_pid, &from->si_pid);
>>   	err |= __get_user(to->si_uid, &from->si_uid);
>> -	err |= __get_user(ptr32, &from->si_ptr);
>> -	to->si_ptr = compat_ptr(ptr32);
>> +	err |= __get_user(to->si_int, &from->si_int);
> We have a memset(to, 0, sizeof(*to)) on arm64 in this function but I
> can't see it on tile. Some members or even half of si_ptr would be left
> uninitialised.

So here we presumably have the reverse problem, which is a 32-bit
process doing a sigqueue() to a 64-bit process.  If the 64-bit process
inspects the sival_ptr, it does seem like it might find garbage in it.
But it also doesn't seem portable in much the same way as the
reverse direction; for a 32-bit process to signal a 64-bit process means
the 64-bit process can't read si_ptr or it will get different values
depending on what endianness is in force, so garbage is only part
of the problem.

I was modeling this code on the very similar code for parisc and s390.
I've added their maintainers to the cc list for this email thread.
I see that x86 uses si_ptr in its equivalent code, but of course it has no
issues with big-endianness.

-- 
Chris Metcalf, EZChip Semiconductor
http://www.ezchip.com

WARNING: multiple messages have this Message-ID (diff)
From: cmetcalf@ezchip.com (Chris Metcalf)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] tile: use si_int instead of si_ptr for compat_siginfo
Date: Tue, 24 Mar 2015 16:51:36 -0400	[thread overview]
Message-ID: <5511CE58.3020507@ezchip.com> (raw)
In-Reply-To: <20150323120253.GA12757@e104818-lin.cambridge.arm.com>

(+s390 and parisc maintainers)

On 03/23/2015 08:02 AM, Catalin Marinas wrote:
> On Mon, Mar 16, 2015 at 03:04:05PM -0400, Chris Metcalf wrote:
>> To be compatible with the generic get_compat_sigevent(), the
>> copy_siginfo_to_user32() and thus copy_siginfo_from_user32()
>> have to use si_int instead of si_ptr.  Using si_ptr means that
>> for the case of ILP32 compat code running in big-endian mode,
>> we would end up copying the high 32 bits of the pointer value
>> into si_int instead of the desired low 32 bits.
>>
>> Signed-off-by: Chris Metcalf <cmetcalf@ezchip.com>
>> Cc: Catalin Marinas <catalin.marinas@arm.com>
>> ---
>>   arch/tile/kernel/compat_signal.c | 9 +++------
>>   1 file changed, 3 insertions(+), 6 deletions(-)
>>
>> diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c
>> index 8c5abf2e4794..bca13054afb4 100644
>> --- a/arch/tile/kernel/compat_signal.c
>> +++ b/arch/tile/kernel/compat_signal.c
>> @@ -68,7 +68,7 @@ int copy_siginfo_to_user32(struct compat_siginfo __user *to, const siginfo_t *fr
>>   	if (from->si_code < 0) {
>>   		err |= __put_user(from->si_pid, &to->si_pid);
>>   		err |= __put_user(from->si_uid, &to->si_uid);
>> -		err |= __put_user(ptr_to_compat(from->si_ptr), &to->si_ptr);
>> +		err |= __put_user(from->si_int, &to->si_int);
>>   	} else {
>>   		/*
>>   		 * First 32bits of unions are always present:
>> @@ -93,8 +93,7 @@ int copy_siginfo_to_user32(struct compat_siginfo __user *to, const siginfo_t *fr
>>   			break;
>>   		case __SI_TIMER >> 16:
>>   			err |= __put_user(from->si_overrun, &to->si_overrun);
>> -			err |= __put_user(ptr_to_compat(from->si_ptr),
>> -					  &to->si_ptr);
>> +			err |= __put_user(from->si_int, &to->si_int);
>>   			break;
> It's usually the __SI_TIMER and __SI_MESGQ cases that matters here (the
> latter already handled). I'm not entirely sure about the si_code < 0
> change.

To be honest, I'm not even sure what path sets si_code < 0.  I see
that that is SI_FROMUSER(), but I don't see where it gets set.

In any case, I guess a risk here is that of a 64-bit process doing a 
sigqueue()
targeting a 32-bit process.  It seems like an impossible problem for the
32-bit process to know whether the 64-bit process wrote a 32-bit pointer
to the 64-bit sival_ptr field (and thus we should deliver the second 32-bit
word of the union sigval to the 32-bit user), or if the 64-bit process wrote
a 32-bit value to the 32-bit sival_int field (and thus we should deliver 
the
first 32-bit word of the union sigval).  Little-endian makes some things
a little bit easier :-)

All that said, my inclination is to use si_int here just because that's what
we're using elsewhere.  But I'm not entirely sure either.

>>   			 /* This is not generated by the kernel as of now.  */
>>   		case __SI_RT >> 16:
>> @@ -110,7 +109,6 @@ int copy_siginfo_to_user32(struct compat_siginfo __user *to, const siginfo_t *fr
>>   int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from)
>>   {
>>   	int err;
>> -	u32 ptr32;
>>   
>>   	if (!access_ok(VERIFY_READ, from, sizeof(struct compat_siginfo)))
>>   		return -EFAULT;
>> @@ -121,8 +119,7 @@ int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from)
>>   
>>   	err |= __get_user(to->si_pid, &from->si_pid);
>>   	err |= __get_user(to->si_uid, &from->si_uid);
>> -	err |= __get_user(ptr32, &from->si_ptr);
>> -	to->si_ptr = compat_ptr(ptr32);
>> +	err |= __get_user(to->si_int, &from->si_int);
> We have a memset(to, 0, sizeof(*to)) on arm64 in this function but I
> can't see it on tile. Some members or even half of si_ptr would be left
> uninitialised.

So here we presumably have the reverse problem, which is a 32-bit
process doing a sigqueue() to a 64-bit process.  If the 64-bit process
inspects the sival_ptr, it does seem like it might find garbage in it.
But it also doesn't seem portable in much the same way as the
reverse direction; for a 32-bit process to signal a 64-bit process means
the 64-bit process can't read si_ptr or it will get different values
depending on what endianness is in force, so garbage is only part
of the problem.

I was modeling this code on the very similar code for parisc and s390.
I've added their maintainers to the cc list for this email thread.
I see that x86 uses si_ptr in its equivalent code, but of course it has no
issues with big-endianness.

-- 
Chris Metcalf, EZChip Semiconductor
http://www.ezchip.com

WARNING: multiple messages have this Message-ID (diff)
From: Chris Metcalf <cmetcalf@ezchip.com>
To: Catalin Marinas <catalin.marinas@arm.com>
Cc: <linux-kernel@vger.kernel.org>, <linux-arch@vger.kernel.org>,
	<ralf@linux-mips.org>, <benh@kernel.crashing.org>,
	<deller@gmx.de>,
	"dingtianhong@huawei.com" <dingtianhong@huawei.com>,
	<heiko.carstens@de.ibm.com>, <jejb@parisc-linux.org>,
	Will Deacon <Will.Deacon@arm.com>,
	"lizefan@huawei.com" <lizefan@huawei.com>,
	Bamvor Jian Zhang <bamvor.zhangjian@huawei.com>,
	<mpe@ellerman.id.au>, <hpa@zytor.com>, <schwidefsky@de.ibm.com>,
	<paulus@samba.org>, <tglx@linutronix.de>, <mingo@redhat.com>,
	<davem@davemloft.net>,
	"linux-arm-kernel@lists.infradead.org" 
	<linux-arm-kernel@lists.infradead.org>,
	Martin Schwidefsky <schwidefsky@de.ibm.com>,
	Heiko Carstens <heiko.carstens@de.ibm.com>,
	"James E.J. Bottomley" <jejb@parisc-linux.org>,
	Helge Deller <deller@gmx.de>
Subject: Re: [PATCH] tile: use si_int instead of si_ptr for compat_siginfo
Date: Tue, 24 Mar 2015 16:51:36 -0400	[thread overview]
Message-ID: <5511CE58.3020507@ezchip.com> (raw)
In-Reply-To: <20150323120253.GA12757@e104818-lin.cambridge.arm.com>

(+s390 and parisc maintainers)

On 03/23/2015 08:02 AM, Catalin Marinas wrote:
> On Mon, Mar 16, 2015 at 03:04:05PM -0400, Chris Metcalf wrote:
>> To be compatible with the generic get_compat_sigevent(), the
>> copy_siginfo_to_user32() and thus copy_siginfo_from_user32()
>> have to use si_int instead of si_ptr.  Using si_ptr means that
>> for the case of ILP32 compat code running in big-endian mode,
>> we would end up copying the high 32 bits of the pointer value
>> into si_int instead of the desired low 32 bits.
>>
>> Signed-off-by: Chris Metcalf <cmetcalf@ezchip.com>
>> Cc: Catalin Marinas <catalin.marinas@arm.com>
>> ---
>>   arch/tile/kernel/compat_signal.c | 9 +++------
>>   1 file changed, 3 insertions(+), 6 deletions(-)
>>
>> diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c
>> index 8c5abf2e4794..bca13054afb4 100644
>> --- a/arch/tile/kernel/compat_signal.c
>> +++ b/arch/tile/kernel/compat_signal.c
>> @@ -68,7 +68,7 @@ int copy_siginfo_to_user32(struct compat_siginfo __user *to, const siginfo_t *fr
>>   	if (from->si_code < 0) {
>>   		err |= __put_user(from->si_pid, &to->si_pid);
>>   		err |= __put_user(from->si_uid, &to->si_uid);
>> -		err |= __put_user(ptr_to_compat(from->si_ptr), &to->si_ptr);
>> +		err |= __put_user(from->si_int, &to->si_int);
>>   	} else {
>>   		/*
>>   		 * First 32bits of unions are always present:
>> @@ -93,8 +93,7 @@ int copy_siginfo_to_user32(struct compat_siginfo __user *to, const siginfo_t *fr
>>   			break;
>>   		case __SI_TIMER >> 16:
>>   			err |= __put_user(from->si_overrun, &to->si_overrun);
>> -			err |= __put_user(ptr_to_compat(from->si_ptr),
>> -					  &to->si_ptr);
>> +			err |= __put_user(from->si_int, &to->si_int);
>>   			break;
> It's usually the __SI_TIMER and __SI_MESGQ cases that matters here (the
> latter already handled). I'm not entirely sure about the si_code < 0
> change.

To be honest, I'm not even sure what path sets si_code < 0.  I see
that that is SI_FROMUSER(), but I don't see where it gets set.

In any case, I guess a risk here is that of a 64-bit process doing a 
sigqueue()
targeting a 32-bit process.  It seems like an impossible problem for the
32-bit process to know whether the 64-bit process wrote a 32-bit pointer
to the 64-bit sival_ptr field (and thus we should deliver the second 32-bit
word of the union sigval to the 32-bit user), or if the 64-bit process wrote
a 32-bit value to the 32-bit sival_int field (and thus we should deliver 
the
first 32-bit word of the union sigval).  Little-endian makes some things
a little bit easier :-)

All that said, my inclination is to use si_int here just because that's what
we're using elsewhere.  But I'm not entirely sure either.

>>   			 /* This is not generated by the kernel as of now.  */
>>   		case __SI_RT >> 16:
>> @@ -110,7 +109,6 @@ int copy_siginfo_to_user32(struct compat_siginfo __user *to, const siginfo_t *fr
>>   int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from)
>>   {
>>   	int err;
>> -	u32 ptr32;
>>   
>>   	if (!access_ok(VERIFY_READ, from, sizeof(struct compat_siginfo)))
>>   		return -EFAULT;
>> @@ -121,8 +119,7 @@ int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from)
>>   
>>   	err |= __get_user(to->si_pid, &from->si_pid);
>>   	err |= __get_user(to->si_uid, &from->si_uid);
>> -	err |= __get_user(ptr32, &from->si_ptr);
>> -	to->si_ptr = compat_ptr(ptr32);
>> +	err |= __get_user(to->si_int, &from->si_int);
> We have a memset(to, 0, sizeof(*to)) on arm64 in this function but I
> can't see it on tile. Some members or even half of si_ptr would be left
> uninitialised.

So here we presumably have the reverse problem, which is a 32-bit
process doing a sigqueue() to a 64-bit process.  If the 64-bit process
inspects the sival_ptr, it does seem like it might find garbage in it.
But it also doesn't seem portable in much the same way as the
reverse direction; for a 32-bit process to signal a 64-bit process means
the 64-bit process can't read si_ptr or it will get different values
depending on what endianness is in force, so garbage is only part
of the problem.

I was modeling this code on the very similar code for parisc and s390.
I've added their maintainers to the cc list for this email thread.
I see that x86 uses si_ptr in its equivalent code, but of course it has no
issues with big-endianness.

-- 
Chris Metcalf, EZChip Semiconductor
http://www.ezchip.com


  reply	other threads:[~2015-03-24 20:51 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-10 10:10 [PATCH] compat: Fix endian issue in union sigval Zhang Jian(Bamvor)
2015-02-10 10:10 ` Zhang Jian(Bamvor)
2015-02-10 12:27 ` Catalin Marinas
2015-02-10 12:27   ` Catalin Marinas
2015-02-11 11:22   ` Bamvor Jian Zhang
2015-02-11 11:22     ` Bamvor Jian Zhang
2015-02-11 11:22     ` Bamvor Jian Zhang
2015-02-11 15:40     ` Catalin Marinas
2015-02-11 15:40       ` Catalin Marinas
2015-02-13  8:00       ` Bamvor Jian Zhang
2015-02-13  8:00         ` Bamvor Jian Zhang
2015-02-13  8:00         ` Bamvor Jian Zhang
2015-02-13 10:44         ` Catalin Marinas
2015-02-13 10:44           ` Catalin Marinas
2015-02-13 21:56           ` Chris Metcalf
2015-02-13 21:56             ` Chris Metcalf
2015-02-13 21:56             ` Chris Metcalf
2015-02-14 11:22             ` Catalin Marinas
2015-02-14 11:22               ` Catalin Marinas
2015-02-14 11:22               ` Catalin Marinas
2015-02-17  6:42               ` Bamvor Jian Zhang
2015-02-17  6:42                 ` Bamvor Jian Zhang
2015-02-17  6:42                 ` Bamvor Jian Zhang
2015-02-21  4:05               ` Chris Metcalf
2015-02-21  4:05                 ` Chris Metcalf
2015-02-21  4:05                 ` Chris Metcalf
2015-02-21  4:05                 ` Chris Metcalf
2015-02-24 21:54               ` Chris Metcalf
2015-02-24 21:54                 ` Chris Metcalf
2015-02-24 21:54                 ` Chris Metcalf
2015-02-24 21:54                 ` Chris Metcalf
2015-02-25 10:37                 ` Catalin Marinas
2015-02-25 10:37                   ` Catalin Marinas
2015-03-16 19:04                   ` [PATCH] tile: use si_int instead of si_ptr for compat_siginfo Chris Metcalf
2015-03-16 19:04                     ` Chris Metcalf
2015-03-16 19:04                     ` Chris Metcalf
2015-03-23 12:02                     ` Catalin Marinas
2015-03-23 12:02                       ` Catalin Marinas
2015-03-24 20:51                       ` Chris Metcalf [this message]
2015-03-24 20:51                         ` Chris Metcalf
2015-03-24 20:51                         ` Chris Metcalf
2015-04-17 16:56                       ` Chris Metcalf
2015-04-17 16:56                         ` Chris Metcalf
2015-04-17 16:56                         ` Chris Metcalf
2015-02-17  7:15           ` [PATCH] compat: Fix endian issue in union sigval Bamvor Jian Zhang
2015-02-17  7:15             ` Bamvor Jian Zhang
2015-02-17  7:15             ` Bamvor Jian Zhang
2015-02-17  7:15             ` Bamvor Jian Zhang

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=5511CE58.3020507@ezchip.com \
    --to=cmetcalf@ezchip.com \
    --cc=Will.Deacon@arm.com \
    --cc=bamvor.zhangjian@huawei.com \
    --cc=benh@kernel.crashing.org \
    --cc=catalin.marinas@arm.com \
    --cc=davem@davemloft.net \
    --cc=deller@gmx.de \
    --cc=dingtianhong@huawei.com \
    --cc=heiko.carstens@de.ibm.com \
    --cc=hpa@zytor.com \
    --cc=jejb@parisc-linux.org \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lizefan@huawei.com \
    --cc=mingo@redhat.com \
    --cc=mpe@ellerman.id.au \
    --cc=paulus@samba.org \
    --cc=ralf@linux-mips.org \
    --cc=schwidefsky@de.ibm.com \
    --cc=tglx@linutronix.de \
    /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.