Skip to content

Commit 2e8bf6e

Browse files
committed
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>
1 parent c1bbefe commit 2e8bf6e

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
@@ -15,8 +15,8 @@
1515
#include <linux/fips.h>
1616
#include <linux/kernel.h>
1717
#include <linux/module.h>
18-
#include <linux/mutex.h>
1918
#include <linux/random.h>
19+
#include <linux/rtmutex.h>
2020
#include <linux/sched/signal.h>
2121
#include <linux/seq_file.h>
2222
#include <linux/slab.h>
@@ -25,9 +25,9 @@
2525

2626
#include "internal.h"
2727

28-
static ____cacheline_aligned_in_smp DEFINE_MUTEX(crypto_reseed_rng_lock);
28+
static ____cacheline_aligned_in_smp DEFINE_RT_MUTEX(crypto_reseed_rng_lock);
2929
static struct crypto_rng *crypto_reseed_rng;
30-
static ____cacheline_aligned_in_smp DEFINE_MUTEX(crypto_default_rng_lock);
30+
static ____cacheline_aligned_in_smp DEFINE_RT_MUTEX(crypto_default_rng_lock);
3131
struct crypto_rng *crypto_default_rng;
3232
EXPORT_SYMBOL_GPL(crypto_default_rng);
3333
static unsigned int crypto_default_rng_refcnt;
@@ -138,31 +138,31 @@ int crypto_get_default_rng(void)
138138
{
139139
int err;
140140

141-
mutex_lock(&crypto_default_rng_lock);
141+
rt_mutex_lock(&crypto_default_rng_lock);
142142
err = crypto_get_rng(&crypto_default_rng);
143143
if (!err)
144144
crypto_default_rng_refcnt++;
145-
mutex_unlock(&crypto_default_rng_lock);
145+
rt_mutex_unlock(&crypto_default_rng_lock);
146146

147147
return err;
148148
}
149149
EXPORT_SYMBOL_GPL(crypto_get_default_rng);
150150

151151
void crypto_put_default_rng(void)
152152
{
153-
mutex_lock(&crypto_default_rng_lock);
153+
rt_mutex_lock(&crypto_default_rng_lock);
154154
crypto_default_rng_refcnt--;
155-
mutex_unlock(&crypto_default_rng_lock);
155+
rt_mutex_unlock(&crypto_default_rng_lock);
156156
}
157157
EXPORT_SYMBOL_GPL(crypto_put_default_rng);
158158

159159
#if defined(CONFIG_CRYPTO_RNG) || defined(CONFIG_CRYPTO_RNG_MODULE)
160160
static int crypto_del_rng(struct crypto_rng **rngp, unsigned int *refcntp,
161-
struct mutex *lock)
161+
struct rt_mutex *lock)
162162
{
163163
int err = -EBUSY;
164164

165-
mutex_lock(lock);
165+
rt_mutex_lock(lock);
166166
if (refcntp && *refcntp)
167167
goto out;
168168

@@ -172,7 +172,7 @@ static int crypto_del_rng(struct crypto_rng **rngp, unsigned int *refcntp,
172172
err = 0;
173173

174174
out:
175-
mutex_unlock(lock);
175+
rt_mutex_unlock(lock);
176176

177177
return err;
178178
}
@@ -282,7 +282,7 @@ static ssize_t crypto_devrandom_read_iter(struct iov_iter *iter, bool reseed)
282282
* a separate mutex (drbg->drbg_mutex) around the
283283
* reseed-and-generate operation.
284284
*/
285-
mutex_lock(&crypto_reseed_rng_lock);
285+
rt_mutex_lock(&crypto_reseed_rng_lock);
286286

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

294294
ret = crypto_get_rng(&crypto_reseed_rng);
295295
if (ret) {
296-
mutex_unlock(&crypto_reseed_rng_lock);
296+
rt_mutex_unlock(&crypto_reseed_rng_lock);
297297
return ret;
298298
}
299299

@@ -331,7 +331,7 @@ static ssize_t crypto_devrandom_read_iter(struct iov_iter *iter, bool reseed)
331331
}
332332

333333
if (reseed)
334-
mutex_unlock(&crypto_reseed_rng_lock);
334+
rt_mutex_unlock(&crypto_reseed_rng_lock);
335335
else
336336
crypto_put_default_rng();
337337
memzero_explicit(tmp, sizeof(tmp));

0 commit comments

Comments
 (0)