Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1243168 > unrolled thread
| Started by | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| First post | 2015-10-09 11:10 +0200 |
| Last post | 2015-10-18 02:30 +0200 |
| Articles | 5 — 4 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: [RFC]: Possible race condition in kernel futex code Thomas Gleixner <tglx@linutronix.de> - 2015-10-09 11:10 +0200
Re: [RFC]: Possible race condition in kernel futex code Hans Zuidam <h.zuidam@online.nl> - 2015-10-09 12:00 +0200
Re: [RFC]: Possible race condition in kernel futex code Thomas Gleixner <tglx@linutronix.de> - 2015-10-09 12:30 +0200
Re: [RFC]: Possible race condition in kernel futex code Peter Zijlstra <peterz@infradead.org> - 2015-10-09 13:40 +0200
Re: [RFC]: Possible race condition in kernel futex code Greg KH <greg@kroah.com> - 2015-10-18 02:30 +0200
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Date | 2015-10-09 11:10 +0200 |
| Subject | Re: [RFC]: Possible race condition in kernel futex code |
| Message-ID | <qhBQC-63L-23@gated-at.bofh.it> |
On Mon, 5 Oct 2015, Jaccon Bastiaansen wrote:
> We did some tests with different compilers, kernel versions and kernel
> configs, with the following results:
>
> Linux 3.12.48, x86_64_defconfig, GCC 4.6.1 :
> copy_user_generic_unrolled being used, so race condition possible
> Linux 3.12.48, x86_64_defconfig, GCC 4.9.1 :
> copy_user_generic_unrolled being used, so race condition possible
> Linux 4.2.3, x86_64_defconfig, GCC 4.6.1 : 32 bit read being used, no
> race condition
> Linux 4.2.3, x86_64_defconfig, GCC 4.9.1 : 32 bit read being used, no
> race condition
>
>
> Our idea to fix this problem is use an explicit 32 bit read in
> get_futex_value_locked() instead of using the generic function
> copy_from_user_inatomic() and hoping the compiler uses an atomic
> access and the right access size.
You cannot use an explicit 32bit read. We need an access which handles
the fault gracefully.
In current mainline this is done proper:
ret = __copy_from_user_inatomic(dst, src, size = sizeof(u32))
__copy_from_user_nocheck(dst, src, size)
if (!__builtin_constant_p(size))
return copy_user_generic(dst, (__force void *)src, size);
size is constant so we end up in the switch case
switch(size) {
case 4:
__get_user_asm(*(u32 *)dst, (u32 __user *)src,
ret, "l", "k", "=r", 4);
return ret;
....
In 3.12 this is different:
__copy_from_user_inatomic()
copy_user_generic()
copy_user_generic_unrolled()
So this is only an issue for kernel versions < 3.13. It was fixed with
ff47ab4ff3cd: Add 1/2/4/8 byte optimization to 64bit __copy_{from,to}_user_inatomic
but nobody noticed that the race you described can happen, so it was
never backported to the stable kernels.
@stable: Can you please pick up ff47ab4ff3cd plus
df90ca969035d x86, sparse: Do not force removal of __user when calling copy_to/from_user_nocheck()
for stable kernels <= 3.12?
If that's too much of churn, then I can come up with an explicit fix
for this. Let me know.
Thanks,
tglx
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | Hans Zuidam <h.zuidam@online.nl> |
|---|---|
| Date | 2015-10-09 12:00 +0200 |
| Message-ID | <qhCCZ-6Yo-3@gated-at.bofh.it> |
| In reply to | #1243168 |
Hi Thomas, On 9 okt. 2015, at 11:06, Thomas Gleixner <tglx@linutronix.de> wrote: On Mon, 5 Oct 2015, Jaccon Bastiaansen wrote: >> We did some tests with different compilers, kernel versions and kernel >> configs, with the following results: > You cannot use an explicit 32bit read. We need an access which handles the fault gracefully. The reason for the explicit read suggestion is to avoid the _builtin_constant_p() in __copy_from_user_nocheck(). The GCC manual says that there may be situations where it returns 0 even though the argument is a constant. Although none of the compiler/kernel combinations we have tried showed this happening, we think it is probably better to be safe than sorry. With kind regards, Hans Zuidam -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Date | 2015-10-09 12:30 +0200 |
| Message-ID | <qhD61-7Lm-5@gated-at.bofh.it> |
| In reply to | #1243203 |
Hans, On Fri, 9 Oct 2015, Hans Zuidam wrote: > On 9 okt. 2015, at 11:06, Thomas Gleixner <tglx@linutronix.de> wrote: > > You cannot use an explicit 32bit read. We need an access which > > handles the fault gracefully. > > The reason for the explicit read suggestion is to avoid the > _builtin_constant_p() in __copy_from_user_nocheck(). The GCC manual > says that there may be situations where it returns 0 even though the > argument is a constant. That's insane at best. > Although none of the compiler/kernel combinations we have tried > showed this happening, we think it is probably better to be safe > than sorry. So we would need something like: futex_copy_from_user() which can be mapped to __copy_from_user_inatomic() first. Then go through all architectures and the asm-generic stuff and provide the specific variants which are guaranteed to use a 32bit access. I really prefer that we don't have to do that and the compiler people get their act together and fix that _builtin_constant_p() thingy. Thanks, tglx -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2015-10-09 13:40 +0200 |
| Message-ID | <qhEbN-R9-25@gated-at.bofh.it> |
| In reply to | #1243223 |
On Fri, Oct 09, 2015 at 11:25:09AM +0100, Thomas Gleixner wrote: > Hans, > > On Fri, 9 Oct 2015, Hans Zuidam wrote: > > On 9 okt. 2015, at 11:06, Thomas Gleixner <tglx@linutronix.de> wrote: > > > You cannot use an explicit 32bit read. We need an access which > > > handles the fault gracefully. > > > > The reason for the explicit read suggestion is to avoid the > > _builtin_constant_p() in __copy_from_user_nocheck(). The GCC manual > > says that there may be situations where it returns 0 even though the > > argument is a constant. > > That's insane at best. Right, but I bet that is for cases where constant propagation completely fails, and this is a trivial case, I have no problem relying on it. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Greg KH <greg@kroah.com> |
|---|---|
| Date | 2015-10-18 02:30 +0200 |
| Message-ID | <qkK1k-5l6-3@gated-at.bofh.it> |
| In reply to | #1243168 |
On Fri, Oct 09, 2015 at 10:06:41AM +0100, Thomas Gleixner wrote:
> On Mon, 5 Oct 2015, Jaccon Bastiaansen wrote:
> > We did some tests with different compilers, kernel versions and kernel
> > configs, with the following results:
> >
> > Linux 3.12.48, x86_64_defconfig, GCC 4.6.1 :
> > copy_user_generic_unrolled being used, so race condition possible
> > Linux 3.12.48, x86_64_defconfig, GCC 4.9.1 :
> > copy_user_generic_unrolled being used, so race condition possible
> > Linux 4.2.3, x86_64_defconfig, GCC 4.6.1 : 32 bit read being used, no
> > race condition
> > Linux 4.2.3, x86_64_defconfig, GCC 4.9.1 : 32 bit read being used, no
> > race condition
> >
> >
> > Our idea to fix this problem is use an explicit 32 bit read in
> > get_futex_value_locked() instead of using the generic function
> > copy_from_user_inatomic() and hoping the compiler uses an atomic
> > access and the right access size.
>
> You cannot use an explicit 32bit read. We need an access which handles
> the fault gracefully.
>
> In current mainline this is done proper:
>
> ret = __copy_from_user_inatomic(dst, src, size = sizeof(u32))
>
> __copy_from_user_nocheck(dst, src, size)
>
> if (!__builtin_constant_p(size))
> return copy_user_generic(dst, (__force void *)src, size);
>
> size is constant so we end up in the switch case
>
> switch(size) {
>
> case 4:
> __get_user_asm(*(u32 *)dst, (u32 __user *)src,
> ret, "l", "k", "=r", 4);
> return ret;
> ....
>
> In 3.12 this is different:
>
> __copy_from_user_inatomic()
> copy_user_generic()
> copy_user_generic_unrolled()
>
> So this is only an issue for kernel versions < 3.13. It was fixed with
>
> ff47ab4ff3cd: Add 1/2/4/8 byte optimization to 64bit __copy_{from,to}_user_inatomic
>
> but nobody noticed that the race you described can happen, so it was
> never backported to the stable kernels.
>
> @stable: Can you please pick up ff47ab4ff3cd plus
>
> df90ca969035d x86, sparse: Do not force removal of __user when calling copy_to/from_user_nocheck()
>
> for stable kernels <= 3.12?
>
> If that's too much of churn, then I can come up with an explicit fix
> for this. Let me know.
Now applied to 3.10-stable, thanks.
greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web