diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2019-04-25 10:19:52 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2021-01-31 22:21:03 +0000 |
commit | 81bdd897aed026a470620cfa5c7241ee1d30ca24 (patch) | |
tree | 820b84bae00ab4579f320e8cada740f57719f608 | |
parent | db8c5efa5c9e7994ee17df614ac6e0a027b4c50a (diff) |
lockdep: Swap storage for pin_count and references
As a lockmap takes a reference for every ww_mutex used together, this
can be an arbitrarily large number and under control of userspace --
easily overflowing the arbitrary limit of 4096. However, the pin_count
(used for detecting unexpected lock dropping) is a full 32b despite
nesting being extremely rare (see lockdep_pin_lock).
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20190425092004.9995-33-chris@chris-wilson.co.uk
-rw-r--r-- | include/linux/lockdep.h | 4 | ||||
-rw-r--r-- | kernel/locking/lockdep.c | 11 |
2 files changed, 9 insertions, 6 deletions
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index b9e9adec73e8..93c530aec462 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h @@ -138,8 +138,8 @@ struct held_lock { unsigned int read:2; /* see lock_acquire() comment */ unsigned int check:1; /* see lock_acquire() comment */ unsigned int hardirqs_off:1; - unsigned int references:12; /* 32 bits */ - unsigned int pin_count; + unsigned int pin_count:12; /* 32 bits */ + unsigned int references; }; /* diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index bdaf4829098c..b49290d7aeba 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -5207,11 +5207,14 @@ static struct pin_cookie __lock_pin_lock(struct lockdep_map *lock) if (match_held_lock(hlock, lock)) { /* - * Grab 16bits of randomness; this is sufficient to not - * be guessable and still allows some pin nesting in - * our u32 pin_count. + * Grab 6bits of randomness; this is barely sufficient + * to not be guessable and still allows some 32 levels + * of pin nesting in our u12 pin_count. */ - cookie.val = 1 + (prandom_u32() >> 16); + cookie.val = 1 + (prandom_u32() >> 26); + if (DEBUG_LOCKS_WARN_ON(hlock->pin_count + cookie.val >= 1 << 12)) + return NIL_COOKIE; + hlock->pin_count += cookie.val; return cookie; } |