All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] x86, pkeys: check against max pkey to avoid overflows
@ 2017-02-23 22:26 Dave Hansen
  2017-02-23 22:26 ` [PATCH 2/2] selftests, x86, pkeys: test with random, unallocated protection keys Dave Hansen
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Dave Hansen @ 2017-02-23 22:26 UTC (permalink / raw)
  To: linux-kernel
  Cc: x86, Dave Hansen, kirill.shutemov, shuah, linux-kselftest, stable


From: Dave Hansen <dave.hansen@linux.intel.com>

Kirill got a warning from UBSAN about undefined behavior when using
protection keys.  He is running on hardware that actually has support
for it, which is not widely available.

The warning was because we did some very large shifts of integers when
doing a pkey_free() of a large, invalid value because we never check
that the pkey "fits" into the mm_pkey_allocation_map().

I do not believe there is any danger here of anything bad happening
other than some aliasing issues where somebody could do:

	pkey_free(35);

and the kernel would effectively execute:

	pkey_free(8);

While this might be confusing to an app that was doing something
stupid, it has to do something stupid and the effects are limited to
the app shooting itself in the foot.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Shuah Khan <shuah@kernel.org>
Cc: linux-kselftest@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: x86@kernel.org
Cc: stable@vger.kernel.org
---

 b/arch/x86/include/asm/pkeys.h |   15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff -puN arch/x86/include/asm/pkeys.h~do-max-pkey-check arch/x86/include/asm/pkeys.h
--- a/arch/x86/include/asm/pkeys.h~do-max-pkey-check	2017-02-23 14:17:33.291953218 -0800
+++ b/arch/x86/include/asm/pkeys.h	2017-02-23 14:24:32.573666333 -0800
@@ -46,6 +46,15 @@ extern int __arch_set_user_pkey_access(s
 static inline
 bool mm_pkey_is_allocated(struct mm_struct *mm, int pkey)
 {
+	/*
+	 * "Allocated" pkeys are those that have been returned
+	 * from pkey_alloc().  pkey 0 is special, and never
+	 * returned from pkey_alloc().
+	 */
+	if (pkey <= 0)
+		return false;
+	if (pkey >= arch_max_pkey())
+		return false;
 	return mm_pkey_allocation_map(mm) & (1U << pkey);
 }
 
@@ -82,12 +91,6 @@ int mm_pkey_alloc(struct mm_struct *mm)
 static inline
 int mm_pkey_free(struct mm_struct *mm, int pkey)
 {
-	/*
-	 * pkey 0 is special, always allocated and can never
-	 * be freed.
-	 */
-	if (!pkey)
-		return -EINVAL;
 	if (!mm_pkey_is_allocated(mm, pkey))
 		return -EINVAL;
 
_

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 2/2] selftests, x86, pkeys: test with random, unallocated protection keys
  2017-02-23 22:26 [PATCH 1/2] x86, pkeys: check against max pkey to avoid overflows Dave Hansen
@ 2017-02-23 22:26 ` Dave Hansen
  2017-02-23 22:36   ` Shuah Khan
  2017-02-24  0:10   ` Kirill A. Shutemov
  2017-02-24  0:07 ` [PATCH 1/2] x86, pkeys: check against max pkey to avoid overflows Kirill A. Shutemov
  2017-03-01  9:57 ` [tip:x86/urgent] x86/pkeys: Check " tip-bot for Dave Hansen
  2 siblings, 2 replies; 9+ messages in thread
From: Dave Hansen @ 2017-02-23 22:26 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, Dave Hansen, shuah, linux-kselftest



Shuah, I assume you'll take this patch in through the selftests tree.

--
From: Dave Hansen <dave.hansen@linux.intel.com>

The kernel pkeys code had a minor bug where it did some large shifts
to an integer which is undefined behavior in C.  It didn't cause any
real harm, but it is screwy behavior that the kernel should have
rejected.

Add a test case for this.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
ec: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Shuah Khan <shuah@kernel.org>
Cc: linux-kselftest@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: x86@kernel.org
---

 b/tools/testing/selftests/x86/protection_keys.c |   25 ++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff -puN tools/testing/selftests/x86/protection_keys.c~pkeys-better-selftests-of-random-pkey tools/testing/selftests/x86/protection_keys.c
--- a/tools/testing/selftests/x86/protection_keys.c~pkeys-better-selftests-of-random-pkey	2017-02-23 14:21:05.168391529 -0800
+++ b/tools/testing/selftests/x86/protection_keys.c	2017-02-23 14:23:03.244671815 -0800
@@ -1123,6 +1123,30 @@ void test_pkey_syscalls_on_non_allocated
 }
 
 /* Assumes that all pkeys other than 'pkey' are unallocated */
+void test_pkey_syscalls_on_non_allocated_random_pkey(int *ptr, u16 pkey)
+{
+	int err;
+	int nr_tests = 0;
+
+	while (nr_tests < 1000) {
+		int test_pkey = rand();
+
+		/* do not test with the pkey we know is good */
+		if (pkey == test_pkey)
+			continue;
+
+		dprintf1("trying free/mprotect bad pkey: %2d\n", test_pkey);
+		err = sys_pkey_free(test_pkey);
+		pkey_assert(err);
+
+		err = sys_mprotect_pkey(ptr, PAGE_SIZE, PROT_READ, test_pkey);
+		pkey_assert(err);
+
+		nr_tests++;
+	}
+}
+
+/* Assumes that all pkeys other than 'pkey' are unallocated */
 void test_pkey_syscalls_bad_args(int *ptr, u16 pkey)
 {
 	int err;
@@ -1320,6 +1344,7 @@ void (*pkey_tests[])(int *ptr, u16 pkey)
 	test_executing_on_unreadable_memory,
 	test_ptrace_of_child,
 	test_pkey_syscalls_on_non_allocated_pkey,
+	test_pkey_syscalls_on_non_allocated_random_pkey,
 	test_pkey_syscalls_bad_args,
 	test_pkey_alloc_exhaust,
 };
_

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/2] selftests, x86, pkeys: test with random, unallocated protection keys
  2017-02-23 22:26 ` [PATCH 2/2] selftests, x86, pkeys: test with random, unallocated protection keys Dave Hansen
@ 2017-02-23 22:36   ` Shuah Khan
  2017-02-24  7:45     ` Ingo Molnar
  2017-02-24  0:10   ` Kirill A. Shutemov
  1 sibling, 1 reply; 9+ messages in thread
From: Shuah Khan @ 2017-02-23 22:36 UTC (permalink / raw)
  To: Dave Hansen, linux-kernel; +Cc: x86, linux-kselftest, Shuah Khan

On 02/23/2017 03:26 PM, Dave Hansen wrote:
> Shuah, I assume you'll take this patch in through the selftests tree.

Yes I can do that.

-- Shuah

> 
> --
> From: Dave Hansen <dave.hansen@linux.intel.com>
> 
> The kernel pkeys code had a minor bug where it did some large shifts
> to an integer which is undefined behavior in C.  It didn't cause any
> real harm, but it is screwy behavior that the kernel should have
> rejected.
> 
> Add a test case for this.
> 
> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
> ec: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
> Cc: Shuah Khan <shuah@kernel.org>
> Cc: linux-kselftest@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> Cc: x86@kernel.org
> ---
> 
>  b/tools/testing/selftests/x86/protection_keys.c |   25 ++++++++++++++++++++++++
>  1 file changed, 25 insertions(+)
> 
> diff -puN tools/testing/selftests/x86/protection_keys.c~pkeys-better-selftests-of-random-pkey tools/testing/selftests/x86/protection_keys.c
> --- a/tools/testing/selftests/x86/protection_keys.c~pkeys-better-selftests-of-random-pkey	2017-02-23 14:21:05.168391529 -0800
> +++ b/tools/testing/selftests/x86/protection_keys.c	2017-02-23 14:23:03.244671815 -0800
> @@ -1123,6 +1123,30 @@ void test_pkey_syscalls_on_non_allocated
>  }
>  
>  /* Assumes that all pkeys other than 'pkey' are unallocated */
> +void test_pkey_syscalls_on_non_allocated_random_pkey(int *ptr, u16 pkey)
> +{
> +	int err;
> +	int nr_tests = 0;
> +
> +	while (nr_tests < 1000) {
> +		int test_pkey = rand();
> +
> +		/* do not test with the pkey we know is good */
> +		if (pkey == test_pkey)
> +			continue;
> +
> +		dprintf1("trying free/mprotect bad pkey: %2d\n", test_pkey);
> +		err = sys_pkey_free(test_pkey);
> +		pkey_assert(err);
> +
> +		err = sys_mprotect_pkey(ptr, PAGE_SIZE, PROT_READ, test_pkey);
> +		pkey_assert(err);
> +
> +		nr_tests++;
> +	}
> +}
> +
> +/* Assumes that all pkeys other than 'pkey' are unallocated */
>  void test_pkey_syscalls_bad_args(int *ptr, u16 pkey)
>  {
>  	int err;
> @@ -1320,6 +1344,7 @@ void (*pkey_tests[])(int *ptr, u16 pkey)
>  	test_executing_on_unreadable_memory,
>  	test_ptrace_of_child,
>  	test_pkey_syscalls_on_non_allocated_pkey,
> +	test_pkey_syscalls_on_non_allocated_random_pkey,
>  	test_pkey_syscalls_bad_args,
>  	test_pkey_alloc_exhaust,
>  };
> _
> 
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/2] x86, pkeys: check against max pkey to avoid overflows
  2017-02-23 22:26 [PATCH 1/2] x86, pkeys: check against max pkey to avoid overflows Dave Hansen
  2017-02-23 22:26 ` [PATCH 2/2] selftests, x86, pkeys: test with random, unallocated protection keys Dave Hansen
@ 2017-02-24  0:07 ` Kirill A. Shutemov
  2017-03-01  9:57 ` [tip:x86/urgent] x86/pkeys: Check " tip-bot for Dave Hansen
  2 siblings, 0 replies; 9+ messages in thread
From: Kirill A. Shutemov @ 2017-02-24  0:07 UTC (permalink / raw)
  To: Dave Hansen
  Cc: linux-kernel, x86, kirill.shutemov, shuah, linux-kselftest, stable

On Thu, Feb 23, 2017 at 02:26:03PM -0800, Dave Hansen wrote:
> 
> From: Dave Hansen <dave.hansen@linux.intel.com>
> 
> Kirill got a warning from UBSAN about undefined behavior when using
> protection keys.  He is running on hardware that actually has support
> for it, which is not widely available.
> 
> The warning was because we did some very large shifts of integers when
> doing a pkey_free() of a large, invalid value because we never check
> that the pkey "fits" into the mm_pkey_allocation_map().
> 
> I do not believe there is any danger here of anything bad happening
> other than some aliasing issues where somebody could do:
> 
> 	pkey_free(35);
> 
> and the kernel would effectively execute:
> 
> 	pkey_free(8);
> 
> While this might be confusing to an app that was doing something
> stupid, it has to do something stupid and the effects are limited to
> the app shooting itself in the foot.
> 
> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>

Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>

-- 
 Kirill A. Shutemov

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/2] selftests, x86, pkeys: test with random, unallocated protection keys
  2017-02-23 22:26 ` [PATCH 2/2] selftests, x86, pkeys: test with random, unallocated protection keys Dave Hansen
  2017-02-23 22:36   ` Shuah Khan
@ 2017-02-24  0:10   ` Kirill A. Shutemov
  1 sibling, 0 replies; 9+ messages in thread
From: Kirill A. Shutemov @ 2017-02-24  0:10 UTC (permalink / raw)
  To: Dave Hansen; +Cc: linux-kernel, x86, shuah, linux-kselftest

On Thu, Feb 23, 2017 at 02:26:04PM -0800, Dave Hansen wrote:
> 
> 
> Shuah, I assume you'll take this patch in through the selftests tree.
> 
> --
> From: Dave Hansen <dave.hansen@linux.intel.com>
> 
> The kernel pkeys code had a minor bug where it did some large shifts
> to an integer which is undefined behavior in C.  It didn't cause any
> real harm, but it is screwy behavior that the kernel should have
> rejected.
> 
> Add a test case for this.
> 
> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
> ec: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
> Cc: Shuah Khan <shuah@kernel.org>
> Cc: linux-kselftest@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> Cc: x86@kernel.org
> ---
> 
>  b/tools/testing/selftests/x86/protection_keys.c |   25 ++++++++++++++++++++++++
>  1 file changed, 25 insertions(+)
> 
> diff -puN tools/testing/selftests/x86/protection_keys.c~pkeys-better-selftests-of-random-pkey tools/testing/selftests/x86/protection_keys.c
> --- a/tools/testing/selftests/x86/protection_keys.c~pkeys-better-selftests-of-random-pkey	2017-02-23 14:21:05.168391529 -0800
> +++ b/tools/testing/selftests/x86/protection_keys.c	2017-02-23 14:23:03.244671815 -0800
> @@ -1123,6 +1123,30 @@ void test_pkey_syscalls_on_non_allocated
>  }
>  
>  /* Assumes that all pkeys other than 'pkey' are unallocated */
> +void test_pkey_syscalls_on_non_allocated_random_pkey(int *ptr, u16 pkey)
> +{
> +	int err;
> +	int nr_tests = 0;
> +
> +	while (nr_tests < 1000) {
> +		int test_pkey = rand();

rand(3) doesn't generate negative numbers. Would be good to cover this
case too.

		int test_pkey = rand() - RAND_MAX/2;

?

Otherwise looks good to me.

-- 
 Kirill A. Shutemov

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/2] selftests, x86, pkeys: test with random, unallocated protection keys
  2017-02-23 22:36   ` Shuah Khan
@ 2017-02-24  7:45     ` Ingo Molnar
  2017-02-24 14:41       ` Shuah Khan
  0 siblings, 1 reply; 9+ messages in thread
From: Ingo Molnar @ 2017-02-24  7:45 UTC (permalink / raw)
  To: Shuah Khan
  Cc: Dave Hansen, linux-kernel, x86, linux-kselftest, Shuah Khan,
	Thomas Gleixner, H. Peter Anvin


* Shuah Khan <shuah@kernel.org> wrote:

> On 02/23/2017 03:26 PM, Dave Hansen wrote:
> > Shuah, I assume you'll take this patch in through the selftests tree.
> 
> Yes I can do that.

No, let's not do that please, we have a fix and a self-tests update, I'd like them 
to be next in the Git space.

I'll apply the testcase too when applying the pkeys fix, ok?

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/2] selftests, x86, pkeys: test with random, unallocated protection keys
  2017-02-24  7:45     ` Ingo Molnar
@ 2017-02-24 14:41       ` Shuah Khan
  2017-02-25  9:10         ` Ingo Molnar
  0 siblings, 1 reply; 9+ messages in thread
From: Shuah Khan @ 2017-02-24 14:41 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Dave Hansen, linux-kernel, x86, linux-kselftest, Shuah Khan,
	Thomas Gleixner, H. Peter Anvin, Shuah Khan

On 02/24/2017 12:45 AM, Ingo Molnar wrote:
> 
> * Shuah Khan <shuah@kernel.org> wrote:
> 
>> On 02/23/2017 03:26 PM, Dave Hansen wrote:
>>> Shuah, I assume you'll take this patch in through the selftests tree.
>>
>> Yes I can do that.
> 
> No, let's not do that please, we have a fix and a self-tests update, I'd like them 
> to be next in the Git space.
> 
> I'll apply the testcase too when applying the pkeys fix, ok?
> 
> Thanks,
> 
> 	Ingo
> 
> 


Yup. I noticed the first patch has to go through x86 tree, Sounds good
to me. Please take both through. I am sending pull request for 4.11-rc1
today. I have a few pkeys patches in there. Hope there won't be any
conflicts.

thanks,
-- Shuah

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/2] selftests, x86, pkeys: test with random, unallocated protection keys
  2017-02-24 14:41       ` Shuah Khan
@ 2017-02-25  9:10         ` Ingo Molnar
  0 siblings, 0 replies; 9+ messages in thread
From: Ingo Molnar @ 2017-02-25  9:10 UTC (permalink / raw)
  To: Shuah Khan
  Cc: Dave Hansen, linux-kernel, x86, linux-kselftest, Shuah Khan,
	Thomas Gleixner, H. Peter Anvin


* Shuah Khan <shuah@kernel.org> wrote:

> On 02/24/2017 12:45 AM, Ingo Molnar wrote:
> > 
> > * Shuah Khan <shuah@kernel.org> wrote:
> > 
> >> On 02/23/2017 03:26 PM, Dave Hansen wrote:
> >>> Shuah, I assume you'll take this patch in through the selftests tree.
> >>
> >> Yes I can do that.
> > 
> > No, let's not do that please, we have a fix and a self-tests update, I'd like them 
> > to be next in the Git space.
> > 
> > I'll apply the testcase too when applying the pkeys fix, ok?
> > 
> > Thanks,
> > 
> > 	Ingo
> > 
> > 
> 
> 
> Yup. I noticed the first patch has to go through x86 tree, Sounds good
> to me. Please take both through. I am sending pull request for 4.11-rc1
> today. I have a few pkeys patches in there. Hope there won't be any
> conflicts.

Ok, I'll wait for your changes to hit upstream, to not create unnecessary 
conflicts.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [tip:x86/urgent] x86/pkeys: Check against max pkey to avoid overflows
  2017-02-23 22:26 [PATCH 1/2] x86, pkeys: check against max pkey to avoid overflows Dave Hansen
  2017-02-23 22:26 ` [PATCH 2/2] selftests, x86, pkeys: test with random, unallocated protection keys Dave Hansen
  2017-02-24  0:07 ` [PATCH 1/2] x86, pkeys: check against max pkey to avoid overflows Kirill A. Shutemov
@ 2017-03-01  9:57 ` tip-bot for Dave Hansen
  2 siblings, 0 replies; 9+ messages in thread
From: tip-bot for Dave Hansen @ 2017-03-01  9:57 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: dave.hansen, hpa, mingo, tglx, linux-kernel

Commit-ID:  58ab9a088ddac4efe823471275859d64f735577e
Gitweb:     http://git.kernel.org/tip/58ab9a088ddac4efe823471275859d64f735577e
Author:     Dave Hansen <dave.hansen@linux.intel.com>
AuthorDate: Thu, 23 Feb 2017 14:26:03 -0800
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Wed, 1 Mar 2017 10:51:50 +0100

x86/pkeys: Check against max pkey to avoid overflows

Kirill reported a warning from UBSAN about undefined behavior when using
protection keys.  He is running on hardware that actually has support for
it, which is not widely available.

The warning triggers because of very large shifts of integers when doing a
pkey_free() of a large, invalid value. This happens because we never check
that the pkey "fits" into the mm_pkey_allocation_map().

I do not believe there is any danger here of anything bad happening
other than some aliasing issues where somebody could do:

	pkey_free(35);

and the kernel would effectively execute:

	pkey_free(8);

While this might be confusing to an app that was doing something stupid, it
has to do something stupid and the effects are limited to the app shooting
itself in the foot.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: stable@vger.kernel.org
Cc: linux-kselftest@vger.kernel.org
Cc: shuah@kernel.org
Cc: kirill.shutemov@linux.intel.com
Link: http://lkml.kernel.org/r/20170223222603.A022ED65@viggo.jf.intel.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/include/asm/pkeys.h | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/arch/x86/include/asm/pkeys.h b/arch/x86/include/asm/pkeys.h
index 34684ad..b3b09b9 100644
--- a/arch/x86/include/asm/pkeys.h
+++ b/arch/x86/include/asm/pkeys.h
@@ -46,6 +46,15 @@ extern int __arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
 static inline
 bool mm_pkey_is_allocated(struct mm_struct *mm, int pkey)
 {
+	/*
+	 * "Allocated" pkeys are those that have been returned
+	 * from pkey_alloc().  pkey 0 is special, and never
+	 * returned from pkey_alloc().
+	 */
+	if (pkey <= 0)
+		return false;
+	if (pkey >= arch_max_pkey())
+		return false;
 	return mm_pkey_allocation_map(mm) & (1U << pkey);
 }
 
@@ -82,12 +91,6 @@ int mm_pkey_alloc(struct mm_struct *mm)
 static inline
 int mm_pkey_free(struct mm_struct *mm, int pkey)
 {
-	/*
-	 * pkey 0 is special, always allocated and can never
-	 * be freed.
-	 */
-	if (!pkey)
-		return -EINVAL;
 	if (!mm_pkey_is_allocated(mm, pkey))
 		return -EINVAL;
 

^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2017-03-01 10:44 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-23 22:26 [PATCH 1/2] x86, pkeys: check against max pkey to avoid overflows Dave Hansen
2017-02-23 22:26 ` [PATCH 2/2] selftests, x86, pkeys: test with random, unallocated protection keys Dave Hansen
2017-02-23 22:36   ` Shuah Khan
2017-02-24  7:45     ` Ingo Molnar
2017-02-24 14:41       ` Shuah Khan
2017-02-25  9:10         ` Ingo Molnar
2017-02-24  0:10   ` Kirill A. Shutemov
2017-02-24  0:07 ` [PATCH 1/2] x86, pkeys: check against max pkey to avoid overflows Kirill A. Shutemov
2017-03-01  9:57 ` [tip:x86/urgent] x86/pkeys: Check " tip-bot for Dave Hansen

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.