Skip to content

Commit 28160b6

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 f2e5373 commit 28160b6

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,7 +14,7 @@
1414
#include <linux/fips.h>
1515
#include <linux/kernel.h>
1616
#include <linux/module.h>
17-
#include <linux/mutex.h>
17+
#include <linux/rtmutex.h>
1818
#include <linux/random.h>
1919
#include <linux/seq_file.h>
2020
#include <linux/sched.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;
@@ -145,31 +145,31 @@ int crypto_get_default_rng(void)
145145
{
146146
int err;
147147

148-
mutex_lock(&crypto_default_rng_lock);
148+
rt_mutex_lock(&crypto_default_rng_lock);
149149
err = crypto_get_rng(&crypto_default_rng);
150150
if (!err)
151151
crypto_default_rng_refcnt++;
152-
mutex_unlock(&crypto_default_rng_lock);
152+
rt_mutex_unlock(&crypto_default_rng_lock);
153153

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

158158
void crypto_put_default_rng(void)
159159
{
160-
mutex_lock(&crypto_default_rng_lock);
160+
rt_mutex_lock(&crypto_default_rng_lock);
161161
crypto_default_rng_refcnt--;
162-
mutex_unlock(&crypto_default_rng_lock);
162+
rt_mutex_unlock(&crypto_default_rng_lock);
163163
}
164164
EXPORT_SYMBOL_GPL(crypto_put_default_rng);
165165

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

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

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

181181
out:
182-
mutex_unlock(lock);
182+
rt_mutex_unlock(lock);
183183

184184
return err;
185185
}
@@ -264,7 +264,7 @@ static ssize_t crypto_devrandom_read_iter(struct iov_iter *iter, bool reseed)
264264
* a separate mutex (drbg->drbg_mutex) around the
265265
* reseed-and-generate operation.
266266
*/
267-
mutex_lock(&crypto_reseed_rng_lock);
267+
rt_mutex_lock(&crypto_reseed_rng_lock);
268268

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

276276
ret = crypto_get_rng(&crypto_reseed_rng);
277277
if (ret) {
278-
mutex_unlock(&crypto_reseed_rng_lock);
278+
rt_mutex_unlock(&crypto_reseed_rng_lock);
279279
return ret;
280280
}
281281

@@ -314,7 +314,7 @@ static ssize_t crypto_devrandom_read_iter(struct iov_iter *iter, bool reseed)
314314
}
315315

316316
if (reseed)
317-
mutex_unlock(&crypto_reseed_rng_lock);
317+
rt_mutex_unlock(&crypto_reseed_rng_lock);
318318
else
319319
crypto_put_default_rng();
320320
memzero_explicit(tmp, sizeof(tmp));

0 commit comments

Comments
 (0)