Skip to content

Commit de7e76d

Browse files
kerneltoastPlaidCat
authored andcommitted
crypto: rng - Fix priority inversions due to mutex locks
Since crypto_devrandom_read_iter() is invoked directly by user tasks and is accessible by every task in the system, there are glaring priority inversions on crypto_reseed_rng_lock and crypto_default_rng_lock. Tasks of arbitrary scheduling priority access crypto_devrandom_read_iter(). When a low-priority task owns one of the mutex locks, higher-priority tasks waiting on that mutex lock are stalled until the low-priority task is done. Fix the priority inversions by converting the mutex locks into rt_mutex locks which have PI support. Signed-off-by: Sultan Alsawaf <sultan@ciq.com> Signed-off-by: Jonathan Maple <jmaple@ciq.com>
1 parent 6d1a84f commit de7e76d

File tree

1 file changed

+13
-13
lines changed

1 file changed

+13
-13
lines changed

crypto/rng.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
#include <linux/fips.h>
1515
#include <linux/kernel.h>
1616
#include <linux/module.h>
17-
#include <linux/mutex.h>
1817
#include <linux/random.h>
18+
#include <linux/rtmutex.h>
1919
#include <linux/seq_file.h>
2020
#include <linux/sched.h>
2121
#include <linux/sched/signal.h>
@@ -26,9 +26,9 @@
2626

2727
#include "internal.h"
2828

29-
static ____cacheline_aligned_in_smp DEFINE_MUTEX(crypto_reseed_rng_lock);
29+
static ____cacheline_aligned_in_smp DEFINE_RT_MUTEX(crypto_reseed_rng_lock);
3030
static struct crypto_rng *crypto_reseed_rng;
31-
static ____cacheline_aligned_in_smp DEFINE_MUTEX(crypto_default_rng_lock);
31+
static ____cacheline_aligned_in_smp DEFINE_RT_MUTEX(crypto_default_rng_lock);
3232
struct crypto_rng *crypto_default_rng;
3333
EXPORT_SYMBOL_GPL(crypto_default_rng);
3434
static unsigned int crypto_default_rng_refcnt;
@@ -146,31 +146,31 @@ int crypto_get_default_rng(void)
146146
{
147147
int err;
148148

149-
mutex_lock(&crypto_default_rng_lock);
149+
rt_mutex_lock(&crypto_default_rng_lock);
150150
err = crypto_get_rng(&crypto_default_rng);
151151
if (!err)
152152
crypto_default_rng_refcnt++;
153-
mutex_unlock(&crypto_default_rng_lock);
153+
rt_mutex_unlock(&crypto_default_rng_lock);
154154

155155
return err;
156156
}
157157
EXPORT_SYMBOL_GPL(crypto_get_default_rng);
158158

159159
void crypto_put_default_rng(void)
160160
{
161-
mutex_lock(&crypto_default_rng_lock);
161+
rt_mutex_lock(&crypto_default_rng_lock);
162162
crypto_default_rng_refcnt--;
163-
mutex_unlock(&crypto_default_rng_lock);
163+
rt_mutex_unlock(&crypto_default_rng_lock);
164164
}
165165
EXPORT_SYMBOL_GPL(crypto_put_default_rng);
166166

167167
#if defined(CONFIG_CRYPTO_RNG) || defined(CONFIG_CRYPTO_RNG_MODULE)
168168
static int crypto_del_rng(struct crypto_rng **rngp, unsigned int *refcntp,
169-
struct mutex *lock)
169+
struct rt_mutex *lock)
170170
{
171171
int err = -EBUSY;
172172

173-
mutex_lock(lock);
173+
rt_mutex_lock(lock);
174174
if (refcntp && *refcntp)
175175
goto out;
176176

@@ -180,7 +180,7 @@ static int crypto_del_rng(struct crypto_rng **rngp, unsigned int *refcntp,
180180
err = 0;
181181

182182
out:
183-
mutex_unlock(lock);
183+
rt_mutex_unlock(lock);
184184

185185
return err;
186186
}
@@ -290,7 +290,7 @@ static ssize_t crypto_devrandom_read_iter(struct iov_iter *iter, bool reseed)
290290
* a separate mutex (drbg->drbg_mutex) around the
291291
* reseed-and-generate operation.
292292
*/
293-
mutex_lock(&crypto_reseed_rng_lock);
293+
rt_mutex_lock(&crypto_reseed_rng_lock);
294294

295295
/* If crypto_default_rng is not set, it will be seeded
296296
* at creation in __crypto_get_default_rng and thus no
@@ -301,7 +301,7 @@ static ssize_t crypto_devrandom_read_iter(struct iov_iter *iter, bool reseed)
301301

302302
ret = crypto_get_rng(&crypto_reseed_rng);
303303
if (ret) {
304-
mutex_unlock(&crypto_reseed_rng_lock);
304+
rt_mutex_unlock(&crypto_reseed_rng_lock);
305305
return ret;
306306
}
307307

@@ -340,7 +340,7 @@ static ssize_t crypto_devrandom_read_iter(struct iov_iter *iter, bool reseed)
340340
}
341341

342342
if (reseed)
343-
mutex_unlock(&crypto_reseed_rng_lock);
343+
rt_mutex_unlock(&crypto_reseed_rng_lock);
344344
else
345345
crypto_put_default_rng();
346346
memzero_explicit(tmp, sizeof(tmp));

0 commit comments

Comments
 (0)