linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] lib/refcount: Document interaction with PID_MAX_LIMIT
@ 2020-03-03 10:54 Jann Horn
  2020-03-03 13:07 ` Ard Biesheuvel
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Jann Horn @ 2020-03-03 10:54 UTC (permalink / raw)
  To: Will Deacon, Kees Cook, Ingo Molnar, Peter Zijlstra
  Cc: kernel list, Elena Reshetova, Ard Biesheuvel, Hanjun Guo,
	Jan Glauber, Kernel Hardening

Document the circumstances under which refcount_t's saturation mechanism
works deterministically.

Signed-off-by: Jann Horn <jannh@google.com>
---

Notes:
    v2:
     - write down the math (Kees)

 include/linux/refcount.h | 23 ++++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/include/linux/refcount.h b/include/linux/refcount.h
index 0ac50cf62d062..0e3ee25eb156a 100644
--- a/include/linux/refcount.h
+++ b/include/linux/refcount.h
@@ -38,11 +38,24 @@
  * atomic operations, then the count will continue to edge closer to 0. If it
  * reaches a value of 1 before /any/ of the threads reset it to the saturated
  * value, then a concurrent refcount_dec_and_test() may erroneously free the
- * underlying object. Given the precise timing details involved with the
- * round-robin scheduling of each thread manipulating the refcount and the need
- * to hit the race multiple times in succession, there doesn't appear to be a
- * practical avenue of attack even if using refcount_add() operations with
- * larger increments.
+ * underlying object.
+ * Linux limits the maximum number of tasks to PID_MAX_LIMIT, which is currently
+ * 0x400000 (and can't easily be raised in the future beyond FUTEX_TID_MASK).
+ * With the current PID limit, if no batched refcounting operations are used and
+ * the attacker can't repeatedly trigger kernel oopses in the middle of refcount
+ * operations, this makes it impossible for a saturated refcount to leave the
+ * saturation range, even if it is possible for multiple uses of the same
+ * refcount to nest in the context of a single task:
+ *
+ *     (UINT_MAX+1-REFCOUNT_SATURATED) / PID_MAX_LIMIT =
+ *     0x40000000 / 0x400000 = 0x100 = 256
+ *
+ * If hundreds of references are added/removed with a single refcounting
+ * operation, it may potentially be possible to leave the saturation range; but
+ * given the precise timing details involved with the round-robin scheduling of
+ * each thread manipulating the refcount and the need to hit the race multiple
+ * times in succession, there doesn't appear to be a practical avenue of attack
+ * even if using refcount_add() operations with larger increments.
  *
  * Memory ordering
  * ===============

base-commit: 98d54f81e36ba3bf92172791eba5ca5bd813989b
-- 
2.25.0.265.gbab2e86ba0-goog


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

* Re: [PATCH v2] lib/refcount: Document interaction with PID_MAX_LIMIT
  2020-03-03 10:54 [PATCH v2] lib/refcount: Document interaction with PID_MAX_LIMIT Jann Horn
@ 2020-03-03 13:07 ` Ard Biesheuvel
  2020-03-03 13:57   ` Jann Horn
  2020-03-03 21:09 ` Kees Cook
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Ard Biesheuvel @ 2020-03-03 13:07 UTC (permalink / raw)
  To: Jann Horn
  Cc: Will Deacon, Kees Cook, Ingo Molnar, Peter Zijlstra, kernel list,
	Elena Reshetova, Hanjun Guo, Jan Glauber, Kernel Hardening

On Tue, 3 Mar 2020 at 11:54, Jann Horn <jannh@google.com> wrote:
>
> Document the circumstances under which refcount_t's saturation mechanism
> works deterministically.
>
> Signed-off-by: Jann Horn <jannh@google.com>

I /think/ the main point of Kees's suggestion was that FUTEX_TID_MASK
is UAPI, so unlikely to change.


> ---
>
> Notes:
>     v2:
>      - write down the math (Kees)
>
>  include/linux/refcount.h | 23 ++++++++++++++++++-----
>  1 file changed, 18 insertions(+), 5 deletions(-)
>
> diff --git a/include/linux/refcount.h b/include/linux/refcount.h
> index 0ac50cf62d062..0e3ee25eb156a 100644
> --- a/include/linux/refcount.h
> +++ b/include/linux/refcount.h
> @@ -38,11 +38,24 @@
>   * atomic operations, then the count will continue to edge closer to 0. If it
>   * reaches a value of 1 before /any/ of the threads reset it to the saturated
>   * value, then a concurrent refcount_dec_and_test() may erroneously free the
> - * underlying object. Given the precise timing details involved with the
> - * round-robin scheduling of each thread manipulating the refcount and the need
> - * to hit the race multiple times in succession, there doesn't appear to be a
> - * practical avenue of attack even if using refcount_add() operations with
> - * larger increments.
> + * underlying object.
> + * Linux limits the maximum number of tasks to PID_MAX_LIMIT, which is currently
> + * 0x400000 (and can't easily be raised in the future beyond FUTEX_TID_MASK).
> + * With the current PID limit, if no batched refcounting operations are used and
> + * the attacker can't repeatedly trigger kernel oopses in the middle of refcount
> + * operations, this makes it impossible for a saturated refcount to leave the
> + * saturation range, even if it is possible for multiple uses of the same
> + * refcount to nest in the context of a single task:
> + *
> + *     (UINT_MAX+1-REFCOUNT_SATURATED) / PID_MAX_LIMIT =
> + *     0x40000000 / 0x400000 = 0x100 = 256
> + *
> + * If hundreds of references are added/removed with a single refcounting
> + * operation, it may potentially be possible to leave the saturation range; but
> + * given the precise timing details involved with the round-robin scheduling of
> + * each thread manipulating the refcount and the need to hit the race multiple
> + * times in succession, there doesn't appear to be a practical avenue of attack
> + * even if using refcount_add() operations with larger increments.
>   *
>   * Memory ordering
>   * ===============
>
> base-commit: 98d54f81e36ba3bf92172791eba5ca5bd813989b
> --
> 2.25.0.265.gbab2e86ba0-goog
>

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

* Re: [PATCH v2] lib/refcount: Document interaction with PID_MAX_LIMIT
  2020-03-03 13:07 ` Ard Biesheuvel
@ 2020-03-03 13:57   ` Jann Horn
  0 siblings, 0 replies; 7+ messages in thread
From: Jann Horn @ 2020-03-03 13:57 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Will Deacon, Kees Cook, Ingo Molnar, Peter Zijlstra, kernel list,
	Elena Reshetova, Hanjun Guo, Jan Glauber, Kernel Hardening

On Tue, Mar 3, 2020 at 2:07 PM Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> On Tue, 3 Mar 2020 at 11:54, Jann Horn <jannh@google.com> wrote:
> >
> > Document the circumstances under which refcount_t's saturation mechanism
> > works deterministically.
> >
> > Signed-off-by: Jann Horn <jannh@google.com>
>
> I /think/ the main point of Kees's suggestion was that FUTEX_TID_MASK
> is UAPI, so unlikely to change.

Yeah, but it has already changed three times in git history:

76b81e2b0e224 ("[PATCH] lightweight robust futexes updates 2"):
0x1fffffff -> 0x3fffffff
d0aa7a70bf03b ("futex_requeue_pi optimization"): 0x3fffffff -> 0x0fffffff
bd197234b0a6 ("Revert "futex_requeue_pi optimization""): 0x0fffffff ->
0x3fffffff

I just sent a patch to fix up a comment that still claimed the mask
was 0x1fffffff... so I didn't want to explicitly write the new value
here.

While making the value *bigger* would probably be a bit hard (and
unnecessary), making it smaller would be fairly easy here - the field
is populated by userspace, so even though the mask is 0x3fffffff,
userspace will never set the upper bits, so they're effectively
reserved bits with value 0.

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

* Re: [PATCH v2] lib/refcount: Document interaction with PID_MAX_LIMIT
  2020-03-03 10:54 [PATCH v2] lib/refcount: Document interaction with PID_MAX_LIMIT Jann Horn
  2020-03-03 13:07 ` Ard Biesheuvel
@ 2020-03-03 21:09 ` Kees Cook
  2020-03-17 22:27 ` Will Deacon
  2020-04-08 12:20 ` [tip: locking/urgent] locking/refcount: " tip-bot2 for Jann Horn
  3 siblings, 0 replies; 7+ messages in thread
From: Kees Cook @ 2020-03-03 21:09 UTC (permalink / raw)
  To: Jann Horn
  Cc: Will Deacon, Ingo Molnar, Peter Zijlstra, kernel list,
	Elena Reshetova, Ard Biesheuvel, Hanjun Guo, Jan Glauber,
	Kernel Hardening

On Tue, Mar 03, 2020 at 11:54:27AM +0100, Jann Horn wrote:
> Document the circumstances under which refcount_t's saturation mechanism
> works deterministically.
> 
> Signed-off-by: Jann Horn <jannh@google.com>

Acked-by: Kees Cook <keescook@chromium.org>

Thanks!

-Kees

> 
> Notes:
>     v2:
>      - write down the math (Kees)
> 
>  include/linux/refcount.h | 23 ++++++++++++++++++-----
>  1 file changed, 18 insertions(+), 5 deletions(-)
> 
> diff --git a/include/linux/refcount.h b/include/linux/refcount.h
> index 0ac50cf62d062..0e3ee25eb156a 100644
> --- a/include/linux/refcount.h
> +++ b/include/linux/refcount.h
> @@ -38,11 +38,24 @@
>   * atomic operations, then the count will continue to edge closer to 0. If it
>   * reaches a value of 1 before /any/ of the threads reset it to the saturated
>   * value, then a concurrent refcount_dec_and_test() may erroneously free the
> - * underlying object. Given the precise timing details involved with the
> - * round-robin scheduling of each thread manipulating the refcount and the need
> - * to hit the race multiple times in succession, there doesn't appear to be a
> - * practical avenue of attack even if using refcount_add() operations with
> - * larger increments.
> + * underlying object.
> + * Linux limits the maximum number of tasks to PID_MAX_LIMIT, which is currently
> + * 0x400000 (and can't easily be raised in the future beyond FUTEX_TID_MASK).
> + * With the current PID limit, if no batched refcounting operations are used and
> + * the attacker can't repeatedly trigger kernel oopses in the middle of refcount
> + * operations, this makes it impossible for a saturated refcount to leave the
> + * saturation range, even if it is possible for multiple uses of the same
> + * refcount to nest in the context of a single task:
> + *
> + *     (UINT_MAX+1-REFCOUNT_SATURATED) / PID_MAX_LIMIT =
> + *     0x40000000 / 0x400000 = 0x100 = 256
> + *
> + * If hundreds of references are added/removed with a single refcounting
> + * operation, it may potentially be possible to leave the saturation range; but
> + * given the precise timing details involved with the round-robin scheduling of
> + * each thread manipulating the refcount and the need to hit the race multiple
> + * times in succession, there doesn't appear to be a practical avenue of attack
> + * even if using refcount_add() operations with larger increments.
>   *
>   * Memory ordering
>   * ===============
> 
> base-commit: 98d54f81e36ba3bf92172791eba5ca5bd813989b
> -- 
> 2.25.0.265.gbab2e86ba0-goog
> 

-- 
Kees Cook

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

* Re: [PATCH v2] lib/refcount: Document interaction with PID_MAX_LIMIT
  2020-03-03 10:54 [PATCH v2] lib/refcount: Document interaction with PID_MAX_LIMIT Jann Horn
  2020-03-03 13:07 ` Ard Biesheuvel
  2020-03-03 21:09 ` Kees Cook
@ 2020-03-17 22:27 ` Will Deacon
  2020-03-24 15:29   ` Peter Zijlstra
  2020-04-08 12:20 ` [tip: locking/urgent] locking/refcount: " tip-bot2 for Jann Horn
  3 siblings, 1 reply; 7+ messages in thread
From: Will Deacon @ 2020-03-17 22:27 UTC (permalink / raw)
  To: Jann Horn
  Cc: Kees Cook, Ingo Molnar, Peter Zijlstra, kernel list,
	Elena Reshetova, Ard Biesheuvel, Hanjun Guo, Jan Glauber,
	Kernel Hardening

On Tue, Mar 03, 2020 at 11:54:27AM +0100, Jann Horn wrote:
> Document the circumstances under which refcount_t's saturation mechanism
> works deterministically.
> 
> Signed-off-by: Jann Horn <jannh@google.com>
> ---
> 
> Notes:
>     v2:
>      - write down the math (Kees)
> 
>  include/linux/refcount.h | 23 ++++++++++++++++++-----
>  1 file changed, 18 insertions(+), 5 deletions(-)
> 
> diff --git a/include/linux/refcount.h b/include/linux/refcount.h
> index 0ac50cf62d062..0e3ee25eb156a 100644
> --- a/include/linux/refcount.h
> +++ b/include/linux/refcount.h
> @@ -38,11 +38,24 @@
>   * atomic operations, then the count will continue to edge closer to 0. If it
>   * reaches a value of 1 before /any/ of the threads reset it to the saturated
>   * value, then a concurrent refcount_dec_and_test() may erroneously free the
> - * underlying object. Given the precise timing details involved with the
> - * round-robin scheduling of each thread manipulating the refcount and the need
> - * to hit the race multiple times in succession, there doesn't appear to be a
> - * practical avenue of attack even if using refcount_add() operations with
> - * larger increments.
> + * underlying object.
> + * Linux limits the maximum number of tasks to PID_MAX_LIMIT, which is currently
> + * 0x400000 (and can't easily be raised in the future beyond FUTEX_TID_MASK).
> + * With the current PID limit, if no batched refcounting operations are used and
> + * the attacker can't repeatedly trigger kernel oopses in the middle of refcount
> + * operations, this makes it impossible for a saturated refcount to leave the
> + * saturation range, even if it is possible for multiple uses of the same
> + * refcount to nest in the context of a single task:
> + *
> + *     (UINT_MAX+1-REFCOUNT_SATURATED) / PID_MAX_LIMIT =
> + *     0x40000000 / 0x400000 = 0x100 = 256
> + *
> + * If hundreds of references are added/removed with a single refcounting
> + * operation, it may potentially be possible to leave the saturation range; but
> + * given the precise timing details involved with the round-robin scheduling of
> + * each thread manipulating the refcount and the need to hit the race multiple
> + * times in succession, there doesn't appear to be a practical avenue of attack
> + * even if using refcount_add() operations with larger increments.
>   *
>   * Memory ordering
>   * ===============
> 
> base-commit: 98d54f81e36ba3bf92172791eba5ca5bd813989b

Acked-by: Will Deacon <will@kernel.org>

Peter -- would you be able to take this through -tip, please?

Will

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

* Re: [PATCH v2] lib/refcount: Document interaction with PID_MAX_LIMIT
  2020-03-17 22:27 ` Will Deacon
@ 2020-03-24 15:29   ` Peter Zijlstra
  0 siblings, 0 replies; 7+ messages in thread
From: Peter Zijlstra @ 2020-03-24 15:29 UTC (permalink / raw)
  To: Will Deacon
  Cc: Jann Horn, Kees Cook, Ingo Molnar, kernel list, Elena Reshetova,
	Ard Biesheuvel, Hanjun Guo, Jan Glauber, Kernel Hardening

On Tue, Mar 17, 2020 at 10:27:18PM +0000, Will Deacon wrote:

> Acked-by: Will Deacon <will@kernel.org>
> 
> Peter -- would you be able to take this through -tip, please?

Got it, I'll stick it in locking/core.

Thanks!

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

* [tip: locking/urgent] locking/refcount: Document interaction with PID_MAX_LIMIT
  2020-03-03 10:54 [PATCH v2] lib/refcount: Document interaction with PID_MAX_LIMIT Jann Horn
                   ` (2 preceding siblings ...)
  2020-03-17 22:27 ` Will Deacon
@ 2020-04-08 12:20 ` tip-bot2 for Jann Horn
  3 siblings, 0 replies; 7+ messages in thread
From: tip-bot2 for Jann Horn @ 2020-04-08 12:20 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Kees Cook, Will Deacon, Jann Horn, Peter Zijlstra (Intel),
	Ingo Molnar, x86, LKML

The following commit has been merged into the locking/urgent branch of tip:

Commit-ID:     a13f58a0cafa7b0416a2898bc3b0defbb305d108
Gitweb:        https://git.kernel.org/tip/a13f58a0cafa7b0416a2898bc3b0defbb305d108
Author:        Jann Horn <jannh@google.com>
AuthorDate:    Tue, 03 Mar 2020 11:54:27 +01:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Wed, 08 Apr 2020 12:05:07 +02:00

locking/refcount: Document interaction with PID_MAX_LIMIT

Document the circumstances under which refcount_t's saturation mechanism
works deterministically.

Acked-by: Kees Cook <keescook@chromium.org>
Acked-by: Will Deacon <will@kernel.org>
Signed-off-by: Jann Horn <jannh@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://lkml.kernel.org/r/20200303105427.260620-1-jannh@google.com
---
 include/linux/refcount.h | 23 ++++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/include/linux/refcount.h b/include/linux/refcount.h
index 0ac50cf..0e3ee25 100644
--- a/include/linux/refcount.h
+++ b/include/linux/refcount.h
@@ -38,11 +38,24 @@
  * atomic operations, then the count will continue to edge closer to 0. If it
  * reaches a value of 1 before /any/ of the threads reset it to the saturated
  * value, then a concurrent refcount_dec_and_test() may erroneously free the
- * underlying object. Given the precise timing details involved with the
- * round-robin scheduling of each thread manipulating the refcount and the need
- * to hit the race multiple times in succession, there doesn't appear to be a
- * practical avenue of attack even if using refcount_add() operations with
- * larger increments.
+ * underlying object.
+ * Linux limits the maximum number of tasks to PID_MAX_LIMIT, which is currently
+ * 0x400000 (and can't easily be raised in the future beyond FUTEX_TID_MASK).
+ * With the current PID limit, if no batched refcounting operations are used and
+ * the attacker can't repeatedly trigger kernel oopses in the middle of refcount
+ * operations, this makes it impossible for a saturated refcount to leave the
+ * saturation range, even if it is possible for multiple uses of the same
+ * refcount to nest in the context of a single task:
+ *
+ *     (UINT_MAX+1-REFCOUNT_SATURATED) / PID_MAX_LIMIT =
+ *     0x40000000 / 0x400000 = 0x100 = 256
+ *
+ * If hundreds of references are added/removed with a single refcounting
+ * operation, it may potentially be possible to leave the saturation range; but
+ * given the precise timing details involved with the round-robin scheduling of
+ * each thread manipulating the refcount and the need to hit the race multiple
+ * times in succession, there doesn't appear to be a practical avenue of attack
+ * even if using refcount_add() operations with larger increments.
  *
  * Memory ordering
  * ===============

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

end of thread, other threads:[~2020-04-08 12:21 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-03 10:54 [PATCH v2] lib/refcount: Document interaction with PID_MAX_LIMIT Jann Horn
2020-03-03 13:07 ` Ard Biesheuvel
2020-03-03 13:57   ` Jann Horn
2020-03-03 21:09 ` Kees Cook
2020-03-17 22:27 ` Will Deacon
2020-03-24 15:29   ` Peter Zijlstra
2020-04-08 12:20 ` [tip: locking/urgent] locking/refcount: " tip-bot2 for Jann Horn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).