linux-stable/drivers/char/hw_random/core.c

727 lines
15 KiB
C
Raw Normal View History

/*
* hw_random/core.c: HWRNG core API
*
* Copyright 2006 Michael Buesch <m@bues.ch>
* Copyright 2005 (c) MontaVista Software, Inc.
*
* Please read Documentation/admin-guide/hw_random.rst for details on use.
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
*/
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/fs.h>
#include <linux/hw_random.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/random.h>
#include <linux/sched.h>
#include <linux/sched/signal.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#define RNG_MODULE_NAME "hw_random"
static struct hwrng *current_rng;
/* the current rng has been explicitly chosen by user via sysfs */
static int cur_rng_set_by_user;
static struct task_struct *hwrng_fill;
/* list of registered rngs */
static LIST_HEAD(rng_list);
/* Protects rng_list and current_rng */
static DEFINE_MUTEX(rng_mutex);
/* Protects rng read functions, data_avail, rng_buffer and rng_fillbuf */
static DEFINE_MUTEX(reading_mutex);
static int data_avail;
static u8 *rng_buffer, *rng_fillbuf;
static unsigned short current_quality;
hwrng: core - treat default_quality as a maximum and default to 1024 Most hw_random devices return entropy which is assumed to be of full quality, but driver authors don't bother setting the quality knob. Some hw_random devices return less than full quality entropy, and then driver authors set the quality knob. Therefore, the entropy crediting should be opt-out rather than opt-in per-driver, to reflect the actual reality on the ground. For example, the two Raspberry Pi RNG drivers produce full entropy randomness, and both EDK2 and U-Boot's drivers for these treat them as such. The result is that EFI then uses these numbers and passes the to Linux, and Linux credits them as boot, thereby initializing the RNG. Yet, in Linux, the quality knob was never set to anything, and so on the chance that Linux is booted without EFI, nothing is ever credited. That's annoying. The same pattern appears to repeat itself throughout various drivers. In fact, very very few drivers have bothered setting quality=1024. Looking at the git history of existing drivers and corresponding mailing list discussion, this conclusion tracks. There's been a decent amount of discussion about drivers that set quality < 1024 -- somebody read and interepreted a datasheet, or made some back of the envelope calculation somehow. But there's been very little, if any, discussion about most drivers where the quality is just set to 1024 or unset (or set to 1000 when the authors misunderstood the API and assumed it was base-10 rather than base-2); in both cases the intent was fairly clear of, "this is a hardware random device; it's fine." So let's invert this logic. A hw_random struct's quality knob now controls the maximum quality a driver can produce, or 0 to specify 1024. Then, the module-wide switch called "default_quality" is changed to represent the maximum quality of any driver. By default it's 1024, and the quality of any particular driver is then given by: min(default_quality, rng->quality ?: 1024); This way, the user can still turn this off for weird reasons (and we can replace whatever driver-specific disabling hacks existed in the past), yet we get proper crediting for relevant RNGs. Cc: Dominik Brodowski <linux@dominikbrodowski.net> Cc: Ard Biesheuvel <ardb@kernel.org> Cc: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2022-11-07 12:24:55 +00:00
static unsigned short default_quality = 1024; /* default to maximum */
module_param(current_quality, ushort, 0644);
MODULE_PARM_DESC(current_quality,
"current hwrng entropy estimation per 1024 bits of input -- obsolete, use rng_quality instead");
module_param(default_quality, ushort, 0644);
MODULE_PARM_DESC(default_quality,
hwrng: core - treat default_quality as a maximum and default to 1024 Most hw_random devices return entropy which is assumed to be of full quality, but driver authors don't bother setting the quality knob. Some hw_random devices return less than full quality entropy, and then driver authors set the quality knob. Therefore, the entropy crediting should be opt-out rather than opt-in per-driver, to reflect the actual reality on the ground. For example, the two Raspberry Pi RNG drivers produce full entropy randomness, and both EDK2 and U-Boot's drivers for these treat them as such. The result is that EFI then uses these numbers and passes the to Linux, and Linux credits them as boot, thereby initializing the RNG. Yet, in Linux, the quality knob was never set to anything, and so on the chance that Linux is booted without EFI, nothing is ever credited. That's annoying. The same pattern appears to repeat itself throughout various drivers. In fact, very very few drivers have bothered setting quality=1024. Looking at the git history of existing drivers and corresponding mailing list discussion, this conclusion tracks. There's been a decent amount of discussion about drivers that set quality < 1024 -- somebody read and interepreted a datasheet, or made some back of the envelope calculation somehow. But there's been very little, if any, discussion about most drivers where the quality is just set to 1024 or unset (or set to 1000 when the authors misunderstood the API and assumed it was base-10 rather than base-2); in both cases the intent was fairly clear of, "this is a hardware random device; it's fine." So let's invert this logic. A hw_random struct's quality knob now controls the maximum quality a driver can produce, or 0 to specify 1024. Then, the module-wide switch called "default_quality" is changed to represent the maximum quality of any driver. By default it's 1024, and the quality of any particular driver is then given by: min(default_quality, rng->quality ?: 1024); This way, the user can still turn this off for weird reasons (and we can replace whatever driver-specific disabling hacks existed in the past), yet we get proper crediting for relevant RNGs. Cc: Dominik Brodowski <linux@dominikbrodowski.net> Cc: Ard Biesheuvel <ardb@kernel.org> Cc: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2022-11-07 12:24:55 +00:00
"default maximum entropy content of hwrng per 1024 bits of input");
static void drop_current_rng(void);
static int hwrng_init(struct hwrng *rng);
static int hwrng_fillfn(void *unused);
static inline int rng_get_data(struct hwrng *rng, u8 *buffer, size_t size,
int wait);
static size_t rng_buffer_size(void)
{
return SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES;
}
static void add_early_randomness(struct hwrng *rng)
{
int bytes_read;
mutex_lock(&reading_mutex);
bytes_read = rng_get_data(rng, rng_fillbuf, 32, 0);
mutex_unlock(&reading_mutex);
if (bytes_read > 0) {
size_t entropy = bytes_read * 8 * rng->quality / 1024;
add_hwgenerator_randomness(rng_fillbuf, bytes_read, entropy, false);
}
}
static inline void cleanup_rng(struct kref *kref)
{
struct hwrng *rng = container_of(kref, struct hwrng, ref);
if (rng->cleanup)
rng->cleanup(rng);
complete(&rng->cleanup_done);
}
static int set_current_rng(struct hwrng *rng)
{
int err;
BUG_ON(!mutex_is_locked(&rng_mutex));
err = hwrng_init(rng);
if (err)
return err;
drop_current_rng();
current_rng = rng;
/* if necessary, start hwrng thread */
if (!hwrng_fill) {
hwrng_fill = kthread_run(hwrng_fillfn, NULL, "hwrng");
if (IS_ERR(hwrng_fill)) {
pr_err("hwrng_fill thread creation failed\n");
hwrng_fill = NULL;
}
}
return 0;
}
static void drop_current_rng(void)
{
BUG_ON(!mutex_is_locked(&rng_mutex));
if (!current_rng)
return;
/* decrease last reference for triggering the cleanup */
kref_put(&current_rng->ref, cleanup_rng);
current_rng = NULL;
}
/* Returns ERR_PTR(), NULL or refcounted hwrng */
static struct hwrng *get_current_rng_nolock(void)
{
if (current_rng)
kref_get(&current_rng->ref);
return current_rng;
}
static struct hwrng *get_current_rng(void)
{
struct hwrng *rng;
if (mutex_lock_interruptible(&rng_mutex))
return ERR_PTR(-ERESTARTSYS);
rng = get_current_rng_nolock();
mutex_unlock(&rng_mutex);
return rng;
}
static void put_rng(struct hwrng *rng)
{
/*
* Hold rng_mutex here so we serialize in case they set_current_rng
* on rng again immediately.
*/
mutex_lock(&rng_mutex);
if (rng)
kref_put(&rng->ref, cleanup_rng);
mutex_unlock(&rng_mutex);
}
static int hwrng_init(struct hwrng *rng)
{
if (kref_get_unless_zero(&rng->ref))
goto skip_init;
if (rng->init) {
int ret;
ret = rng->init(rng);
if (ret)
return ret;
}
kref_init(&rng->ref);
reinit_completion(&rng->cleanup_done);
skip_init:
hwrng: core - treat default_quality as a maximum and default to 1024 Most hw_random devices return entropy which is assumed to be of full quality, but driver authors don't bother setting the quality knob. Some hw_random devices return less than full quality entropy, and then driver authors set the quality knob. Therefore, the entropy crediting should be opt-out rather than opt-in per-driver, to reflect the actual reality on the ground. For example, the two Raspberry Pi RNG drivers produce full entropy randomness, and both EDK2 and U-Boot's drivers for these treat them as such. The result is that EFI then uses these numbers and passes the to Linux, and Linux credits them as boot, thereby initializing the RNG. Yet, in Linux, the quality knob was never set to anything, and so on the chance that Linux is booted without EFI, nothing is ever credited. That's annoying. The same pattern appears to repeat itself throughout various drivers. In fact, very very few drivers have bothered setting quality=1024. Looking at the git history of existing drivers and corresponding mailing list discussion, this conclusion tracks. There's been a decent amount of discussion about drivers that set quality < 1024 -- somebody read and interepreted a datasheet, or made some back of the envelope calculation somehow. But there's been very little, if any, discussion about most drivers where the quality is just set to 1024 or unset (or set to 1000 when the authors misunderstood the API and assumed it was base-10 rather than base-2); in both cases the intent was fairly clear of, "this is a hardware random device; it's fine." So let's invert this logic. A hw_random struct's quality knob now controls the maximum quality a driver can produce, or 0 to specify 1024. Then, the module-wide switch called "default_quality" is changed to represent the maximum quality of any driver. By default it's 1024, and the quality of any particular driver is then given by: min(default_quality, rng->quality ?: 1024); This way, the user can still turn this off for weird reasons (and we can replace whatever driver-specific disabling hacks existed in the past), yet we get proper crediting for relevant RNGs. Cc: Dominik Brodowski <linux@dominikbrodowski.net> Cc: Ard Biesheuvel <ardb@kernel.org> Cc: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2022-11-07 12:24:55 +00:00
rng->quality = min_t(u16, min_t(u16, default_quality, 1024), rng->quality ?: 1024);
current_quality = rng->quality; /* obsolete */
return 0;
}
static int rng_dev_open(struct inode *inode, struct file *filp)
{
/* enforce read-only access to this chrdev */
if ((filp->f_mode & FMODE_READ) == 0)
return -EINVAL;
if (filp->f_mode & FMODE_WRITE)
return -EINVAL;
return 0;
}
static inline int rng_get_data(struct hwrng *rng, u8 *buffer, size_t size,
int wait) {
int present;
BUG_ON(!mutex_is_locked(&reading_mutex));
if (rng->read)
return rng->read(rng, (void *)buffer, size, wait);
if (rng->data_present)
present = rng->data_present(rng, wait);
else
present = 1;
if (present)
return rng->data_read(rng, (u32 *)buffer);
return 0;
}
static ssize_t rng_dev_read(struct file *filp, char __user *buf,
size_t size, loff_t *offp)
{
ssize_t ret = 0;
int err = 0;
int bytes_read, len;
struct hwrng *rng;
while (size) {
rng = get_current_rng();
if (IS_ERR(rng)) {
err = PTR_ERR(rng);
goto out;
}
if (!rng) {
err = -ENODEV;
goto out;
}
if (mutex_lock_interruptible(&reading_mutex)) {
err = -ERESTARTSYS;
goto out_put;
}
if (!data_avail) {
bytes_read = rng_get_data(rng, rng_buffer,
rng_buffer_size(),
!(filp->f_flags & O_NONBLOCK));
if (bytes_read < 0) {
err = bytes_read;
goto out_unlock_reading;
}
data_avail = bytes_read;
}
if (!data_avail) {
if (filp->f_flags & O_NONBLOCK) {
err = -EAGAIN;
goto out_unlock_reading;
}
} else {
len = data_avail;
if (len > size)
len = size;
data_avail -= len;
if (copy_to_user(buf + ret, rng_buffer + data_avail,
len)) {
err = -EFAULT;
goto out_unlock_reading;
}
size -= len;
ret += len;
}
mutex_unlock(&reading_mutex);
put_rng(rng);
if (need_resched())
schedule_timeout_interruptible(1);
if (signal_pending(current)) {
err = -ERESTARTSYS;
goto out;
}
}
out:
return ret ? : err;
out_unlock_reading:
mutex_unlock(&reading_mutex);
out_put:
put_rng(rng);
goto out;
}
static const struct file_operations rng_chrdev_ops = {
.owner = THIS_MODULE,
.open = rng_dev_open,
.read = rng_dev_read,
llseek: automatically add .llseek fop All file_operations should get a .llseek operation so we can make nonseekable_open the default for future file operations without a .llseek pointer. The three cases that we can automatically detect are no_llseek, seq_lseek and default_llseek. For cases where we can we can automatically prove that the file offset is always ignored, we use noop_llseek, which maintains the current behavior of not returning an error from a seek. New drivers should normally not use noop_llseek but instead use no_llseek and call nonseekable_open at open time. Existing drivers can be converted to do the same when the maintainer knows for certain that no user code relies on calling seek on the device file. The generated code is often incorrectly indented and right now contains comments that clarify for each added line why a specific variant was chosen. In the version that gets submitted upstream, the comments will be gone and I will manually fix the indentation, because there does not seem to be a way to do that using coccinelle. Some amount of new code is currently sitting in linux-next that should get the same modifications, which I will do at the end of the merge window. Many thanks to Julia Lawall for helping me learn to write a semantic patch that does all this. ===== begin semantic patch ===== // This adds an llseek= method to all file operations, // as a preparation for making no_llseek the default. // // The rules are // - use no_llseek explicitly if we do nonseekable_open // - use seq_lseek for sequential files // - use default_llseek if we know we access f_pos // - use noop_llseek if we know we don't access f_pos, // but we still want to allow users to call lseek // @ open1 exists @ identifier nested_open; @@ nested_open(...) { <+... nonseekable_open(...) ...+> } @ open exists@ identifier open_f; identifier i, f; identifier open1.nested_open; @@ int open_f(struct inode *i, struct file *f) { <+... ( nonseekable_open(...) | nested_open(...) ) ...+> } @ read disable optional_qualifier exists @ identifier read_f; identifier f, p, s, off; type ssize_t, size_t, loff_t; expression E; identifier func; @@ ssize_t read_f(struct file *f, char *p, size_t s, loff_t *off) { <+... ( *off = E | *off += E | func(..., off, ...) | E = *off ) ...+> } @ read_no_fpos disable optional_qualifier exists @ identifier read_f; identifier f, p, s, off; type ssize_t, size_t, loff_t; @@ ssize_t read_f(struct file *f, char *p, size_t s, loff_t *off) { ... when != off } @ write @ identifier write_f; identifier f, p, s, off; type ssize_t, size_t, loff_t; expression E; identifier func; @@ ssize_t write_f(struct file *f, const char *p, size_t s, loff_t *off) { <+... ( *off = E | *off += E | func(..., off, ...) | E = *off ) ...+> } @ write_no_fpos @ identifier write_f; identifier f, p, s, off; type ssize_t, size_t, loff_t; @@ ssize_t write_f(struct file *f, const char *p, size_t s, loff_t *off) { ... when != off } @ fops0 @ identifier fops; @@ struct file_operations fops = { ... }; @ has_llseek depends on fops0 @ identifier fops0.fops; identifier llseek_f; @@ struct file_operations fops = { ... .llseek = llseek_f, ... }; @ has_read depends on fops0 @ identifier fops0.fops; identifier read_f; @@ struct file_operations fops = { ... .read = read_f, ... }; @ has_write depends on fops0 @ identifier fops0.fops; identifier write_f; @@ struct file_operations fops = { ... .write = write_f, ... }; @ has_open depends on fops0 @ identifier fops0.fops; identifier open_f; @@ struct file_operations fops = { ... .open = open_f, ... }; // use no_llseek if we call nonseekable_open //////////////////////////////////////////// @ nonseekable1 depends on !has_llseek && has_open @ identifier fops0.fops; identifier nso ~= "nonseekable_open"; @@ struct file_operations fops = { ... .open = nso, ... +.llseek = no_llseek, /* nonseekable */ }; @ nonseekable2 depends on !has_llseek @ identifier fops0.fops; identifier open.open_f; @@ struct file_operations fops = { ... .open = open_f, ... +.llseek = no_llseek, /* open uses nonseekable */ }; // use seq_lseek for sequential files ///////////////////////////////////// @ seq depends on !has_llseek @ identifier fops0.fops; identifier sr ~= "seq_read"; @@ struct file_operations fops = { ... .read = sr, ... +.llseek = seq_lseek, /* we have seq_read */ }; // use default_llseek if there is a readdir /////////////////////////////////////////// @ fops1 depends on !has_llseek && !nonseekable1 && !nonseekable2 && !seq @ identifier fops0.fops; identifier readdir_e; @@ // any other fop is used that changes pos struct file_operations fops = { ... .readdir = readdir_e, ... +.llseek = default_llseek, /* readdir is present */ }; // use default_llseek if at least one of read/write touches f_pos ///////////////////////////////////////////////////////////////// @ fops2 depends on !fops1 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @ identifier fops0.fops; identifier read.read_f; @@ // read fops use offset struct file_operations fops = { ... .read = read_f, ... +.llseek = default_llseek, /* read accesses f_pos */ }; @ fops3 depends on !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @ identifier fops0.fops; identifier write.write_f; @@ // write fops use offset struct file_operations fops = { ... .write = write_f, ... + .llseek = default_llseek, /* write accesses f_pos */ }; // Use noop_llseek if neither read nor write accesses f_pos /////////////////////////////////////////////////////////// @ fops4 depends on !fops1 && !fops2 && !fops3 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @ identifier fops0.fops; identifier read_no_fpos.read_f; identifier write_no_fpos.write_f; @@ // write fops use offset struct file_operations fops = { ... .write = write_f, .read = read_f, ... +.llseek = noop_llseek, /* read and write both use no f_pos */ }; @ depends on has_write && !has_read && !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @ identifier fops0.fops; identifier write_no_fpos.write_f; @@ struct file_operations fops = { ... .write = write_f, ... +.llseek = noop_llseek, /* write uses no f_pos */ }; @ depends on has_read && !has_write && !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @ identifier fops0.fops; identifier read_no_fpos.read_f; @@ struct file_operations fops = { ... .read = read_f, ... +.llseek = noop_llseek, /* read uses no f_pos */ }; @ depends on !has_read && !has_write && !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @ identifier fops0.fops; @@ struct file_operations fops = { ... +.llseek = noop_llseek, /* no read or write fn */ }; ===== End semantic patch ===== Signed-off-by: Arnd Bergmann <arnd@arndb.de> Cc: Julia Lawall <julia@diku.dk> Cc: Christoph Hellwig <hch@infradead.org>
2010-08-15 16:52:59 +00:00
.llseek = noop_llseek,
};
static const struct attribute_group *rng_dev_groups[];
static struct miscdevice rng_miscdev = {
.minor = HWRNG_MINOR,
.name = RNG_MODULE_NAME,
.nodename = "hwrng",
.fops = &rng_chrdev_ops,
.groups = rng_dev_groups,
};
static int enable_best_rng(void)
{
struct hwrng *rng, *new_rng = NULL;
int ret = -ENODEV;
BUG_ON(!mutex_is_locked(&rng_mutex));
/* no rng to use? */
if (list_empty(&rng_list)) {
drop_current_rng();
cur_rng_set_by_user = 0;
return 0;
}
/* use the rng which offers the best quality */
list_for_each_entry(rng, &rng_list, list) {
if (!new_rng || rng->quality > new_rng->quality)
new_rng = rng;
}
ret = ((new_rng == current_rng) ? 0 : set_current_rng(new_rng));
if (!ret)
cur_rng_set_by_user = 0;
return ret;
}
static ssize_t rng_current_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
int err;
struct hwrng *rng, *old_rng, *new_rng;
err = mutex_lock_interruptible(&rng_mutex);
if (err)
return -ERESTARTSYS;
old_rng = current_rng;
if (sysfs_streq(buf, "")) {
err = enable_best_rng();
} else {
list_for_each_entry(rng, &rng_list, list) {
if (sysfs_streq(rng->name, buf)) {
err = set_current_rng(rng);
if (!err)
cur_rng_set_by_user = 1;
break;
}
}
}
new_rng = get_current_rng_nolock();
mutex_unlock(&rng_mutex);
if (new_rng) {
if (new_rng != old_rng)
add_early_randomness(new_rng);
put_rng(new_rng);
}
return err ? : len;
}
static ssize_t rng_current_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
ssize_t ret;
struct hwrng *rng;
rng = get_current_rng();
if (IS_ERR(rng))
return PTR_ERR(rng);
ret = snprintf(buf, PAGE_SIZE, "%s\n", rng ? rng->name : "none");
put_rng(rng);
return ret;
}
static ssize_t rng_available_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
int err;
struct hwrng *rng;
err = mutex_lock_interruptible(&rng_mutex);
if (err)
return -ERESTARTSYS;
buf[0] = '\0';
list_for_each_entry(rng, &rng_list, list) {
strlcat(buf, rng->name, PAGE_SIZE);
strlcat(buf, " ", PAGE_SIZE);
}
strlcat(buf, "\n", PAGE_SIZE);
mutex_unlock(&rng_mutex);
return strlen(buf);
}
static ssize_t rng_selected_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
return sysfs_emit(buf, "%d\n", cur_rng_set_by_user);
}
static ssize_t rng_quality_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
ssize_t ret;
struct hwrng *rng;
rng = get_current_rng();
if (IS_ERR(rng))
return PTR_ERR(rng);
if (!rng) /* no need to put_rng */
return -ENODEV;
ret = sysfs_emit(buf, "%hu\n", rng->quality);
put_rng(rng);
return ret;
}
static ssize_t rng_quality_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
u16 quality;
int ret = -EINVAL;
if (len < 2)
return -EINVAL;
ret = mutex_lock_interruptible(&rng_mutex);
if (ret)
return -ERESTARTSYS;
ret = kstrtou16(buf, 0, &quality);
if (ret || quality > 1024) {
ret = -EINVAL;
goto out;
}
if (!current_rng) {
ret = -ENODEV;
goto out;
}
current_rng->quality = quality;
current_quality = quality; /* obsolete */
/* the best available RNG may have changed */
ret = enable_best_rng();
out:
mutex_unlock(&rng_mutex);
return ret ? ret : len;
}
static DEVICE_ATTR_RW(rng_current);
static DEVICE_ATTR_RO(rng_available);
static DEVICE_ATTR_RO(rng_selected);
static DEVICE_ATTR_RW(rng_quality);
static struct attribute *rng_dev_attrs[] = {
&dev_attr_rng_current.attr,
&dev_attr_rng_available.attr,
&dev_attr_rng_selected.attr,
&dev_attr_rng_quality.attr,
NULL
};
ATTRIBUTE_GROUPS(rng_dev);
static void __exit unregister_miscdev(void)
{
misc_deregister(&rng_miscdev);
}
static int __init register_miscdev(void)
{
return misc_register(&rng_miscdev);
}
static int hwrng_fillfn(void *unused)
{
size_t entropy, entropy_credit = 0; /* in 1/1024 of a bit */
long rc;
while (!kthread_should_stop()) {
unsigned short quality;
struct hwrng *rng;
rng = get_current_rng();
if (IS_ERR(rng) || !rng)
break;
mutex_lock(&reading_mutex);
rc = rng_get_data(rng, rng_fillbuf,
rng_buffer_size(), 1);
if (current_quality != rng->quality)
rng->quality = current_quality; /* obsolete */
quality = rng->quality;
mutex_unlock(&reading_mutex);
hwrng: core - let sleep be interrupted when unregistering hwrng There are two deadlock scenarios that need addressing, which cause problems when the computer goes to sleep, the interface is set down, and hwrng_unregister() is called. When the deadlock is hit, sleep is delayed for tens of seconds, causing it to fail. These scenarios are: 1) The hwrng kthread can't be stopped while it's sleeping, because it uses msleep_interruptible() which does not react to kthread_stop. 2) A normal user thread can't be interrupted by hwrng_unregister() while it's sleeping, because hwrng_unregister() is called from elsewhere. We solve both issues by add a completion object called dying that fulfils waiters once we have started the process in hwrng_unregister. At the same time, we should cleanup a common and useless dmesg splat in the same area. Cc: <stable@vger.kernel.org> Reported-by: Gregory Erwin <gregerwin256@gmail.com> Fixes: fcd09c90c3c5 ("ath9k: use hw_random API instead of directly dumping into random.c") Link: https://lore.kernel.org/all/CAO+Okf6ZJC5-nTE_EJUGQtd8JiCkiEHytGgDsFGTEjs0c00giw@mail.gmail.com/ Link: https://lore.kernel.org/lkml/CAO+Okf5k+C+SE6pMVfPf-d8MfVPVq4PO7EY8Hys_DVXtent3HA@mail.gmail.com/ Link: https://bugs.archlinux.org/task/75138 Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Acked-by: Toke Høiland-Jørgensen <toke@toke.dk> Acked-by: Kalle Valo <kvalo@kernel.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2022-07-28 10:22:20 +00:00
if (rc <= 0)
hwrng_msleep(rng, 10000);
put_rng(rng);
hwrng: core - let sleep be interrupted when unregistering hwrng There are two deadlock scenarios that need addressing, which cause problems when the computer goes to sleep, the interface is set down, and hwrng_unregister() is called. When the deadlock is hit, sleep is delayed for tens of seconds, causing it to fail. These scenarios are: 1) The hwrng kthread can't be stopped while it's sleeping, because it uses msleep_interruptible() which does not react to kthread_stop. 2) A normal user thread can't be interrupted by hwrng_unregister() while it's sleeping, because hwrng_unregister() is called from elsewhere. We solve both issues by add a completion object called dying that fulfils waiters once we have started the process in hwrng_unregister. At the same time, we should cleanup a common and useless dmesg splat in the same area. Cc: <stable@vger.kernel.org> Reported-by: Gregory Erwin <gregerwin256@gmail.com> Fixes: fcd09c90c3c5 ("ath9k: use hw_random API instead of directly dumping into random.c") Link: https://lore.kernel.org/all/CAO+Okf6ZJC5-nTE_EJUGQtd8JiCkiEHytGgDsFGTEjs0c00giw@mail.gmail.com/ Link: https://lore.kernel.org/lkml/CAO+Okf5k+C+SE6pMVfPf-d8MfVPVq4PO7EY8Hys_DVXtent3HA@mail.gmail.com/ Link: https://bugs.archlinux.org/task/75138 Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Acked-by: Toke Høiland-Jørgensen <toke@toke.dk> Acked-by: Kalle Valo <kvalo@kernel.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2022-07-28 10:22:20 +00:00
if (rc <= 0)
continue;
/* If we cannot credit at least one bit of entropy,
* keep track of the remainder for the next iteration
*/
entropy = rc * quality * 8 + entropy_credit;
if ((entropy >> 10) == 0)
entropy_credit = entropy;
/* Outside lock, sure, but y'know: randomness. */
add_hwgenerator_randomness((void *)rng_fillbuf, rc,
entropy >> 10, true);
}
hwrng_fill = NULL;
return 0;
}
int hwrng_register(struct hwrng *rng)
{
int err = -EINVAL;
hwrng: core - Fix use-after-free warning in hwrng_register() Commit daae28debcb0 has moved add_early_randomness() out of the rng_mutex and tries to protect the reference of the new rng device by incrementing the reference counter. But in hwrng_register(), the function can be called with a new device that is not set as the current_rng device and the reference has not been initialized. This patch fixes the problem by not using the reference counter when the device is not the current one: the reference counter is only meaningful in the case of the current rng device and a device is not used if it is not the current one (except in hwrng_register()) The problem has been reported by Marek Szyprowski on ARM 32bit Exynos5420-based Chromebook Peach-Pit board: WARNING: CPU: 3 PID: 1 at lib/refcount.c:156 hwrng_register+0x13c/0x1b4 refcount_t: increment on 0; use-after-free. Modules linked in: CPU: 3 PID: 1 Comm: swapper/0 Not tainted 5.4.0-rc1-00061-gdaae28debcb0 Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) [<c01124c8>] (unwind_backtrace) from [<c010dfb8>] (show_stack+0x10/0x14) [<c010dfb8>] (show_stack) from [<c0ae86d8>] (dump_stack+0xa8/0xd4) [<c0ae86d8>] (dump_stack) from [<c0127428>] (__warn+0xf4/0x10c) [<c0127428>] (__warn) from [<c01274b4>] (warn_slowpath_fmt+0x74/0xb8) [<c01274b4>] (warn_slowpath_fmt) from [<c054729c>] (hwrng_register+0x13c/0x1b4) [<c054729c>] (hwrng_register) from [<c0547e54>] (tpm_chip_register+0xc4/0x274) ... Reported-by: Marek Szyprowski <m.szyprowski@samsung.com> Fixes: daae28debcb0 ("hwrng: core - move add_early_randomness() out of rng_mutex") Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Laurent Vivier <lvivier@redhat.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2019-10-14 11:46:32 +00:00
struct hwrng *tmp;
bool is_new_current = false;
if (!rng->name || (!rng->data_read && !rng->read))
goto out;
mutex_lock(&rng_mutex);
/* Must not register two RNGs with the same name. */
err = -EEXIST;
list_for_each_entry(tmp, &rng_list, list) {
if (strcmp(tmp->name, rng->name) == 0)
goto out_unlock;
}
list_add_tail(&rng->list, &rng_list);
init_completion(&rng->cleanup_done);
complete(&rng->cleanup_done);
hwrng: core - let sleep be interrupted when unregistering hwrng There are two deadlock scenarios that need addressing, which cause problems when the computer goes to sleep, the interface is set down, and hwrng_unregister() is called. When the deadlock is hit, sleep is delayed for tens of seconds, causing it to fail. These scenarios are: 1) The hwrng kthread can't be stopped while it's sleeping, because it uses msleep_interruptible() which does not react to kthread_stop. 2) A normal user thread can't be interrupted by hwrng_unregister() while it's sleeping, because hwrng_unregister() is called from elsewhere. We solve both issues by add a completion object called dying that fulfils waiters once we have started the process in hwrng_unregister. At the same time, we should cleanup a common and useless dmesg splat in the same area. Cc: <stable@vger.kernel.org> Reported-by: Gregory Erwin <gregerwin256@gmail.com> Fixes: fcd09c90c3c5 ("ath9k: use hw_random API instead of directly dumping into random.c") Link: https://lore.kernel.org/all/CAO+Okf6ZJC5-nTE_EJUGQtd8JiCkiEHytGgDsFGTEjs0c00giw@mail.gmail.com/ Link: https://lore.kernel.org/lkml/CAO+Okf5k+C+SE6pMVfPf-d8MfVPVq4PO7EY8Hys_DVXtent3HA@mail.gmail.com/ Link: https://bugs.archlinux.org/task/75138 Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Acked-by: Toke Høiland-Jørgensen <toke@toke.dk> Acked-by: Kalle Valo <kvalo@kernel.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2022-07-28 10:22:20 +00:00
init_completion(&rng->dying);
hwrng: core - Fix use-after-free warning in hwrng_register() Commit daae28debcb0 has moved add_early_randomness() out of the rng_mutex and tries to protect the reference of the new rng device by incrementing the reference counter. But in hwrng_register(), the function can be called with a new device that is not set as the current_rng device and the reference has not been initialized. This patch fixes the problem by not using the reference counter when the device is not the current one: the reference counter is only meaningful in the case of the current rng device and a device is not used if it is not the current one (except in hwrng_register()) The problem has been reported by Marek Szyprowski on ARM 32bit Exynos5420-based Chromebook Peach-Pit board: WARNING: CPU: 3 PID: 1 at lib/refcount.c:156 hwrng_register+0x13c/0x1b4 refcount_t: increment on 0; use-after-free. Modules linked in: CPU: 3 PID: 1 Comm: swapper/0 Not tainted 5.4.0-rc1-00061-gdaae28debcb0 Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) [<c01124c8>] (unwind_backtrace) from [<c010dfb8>] (show_stack+0x10/0x14) [<c010dfb8>] (show_stack) from [<c0ae86d8>] (dump_stack+0xa8/0xd4) [<c0ae86d8>] (dump_stack) from [<c0127428>] (__warn+0xf4/0x10c) [<c0127428>] (__warn) from [<c01274b4>] (warn_slowpath_fmt+0x74/0xb8) [<c01274b4>] (warn_slowpath_fmt) from [<c054729c>] (hwrng_register+0x13c/0x1b4) [<c054729c>] (hwrng_register) from [<c0547e54>] (tpm_chip_register+0xc4/0x274) ... Reported-by: Marek Szyprowski <m.szyprowski@samsung.com> Fixes: daae28debcb0 ("hwrng: core - move add_early_randomness() out of rng_mutex") Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Laurent Vivier <lvivier@redhat.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2019-10-14 11:46:32 +00:00
if (!current_rng ||
(!cur_rng_set_by_user && rng->quality > current_rng->quality)) {
/*
* Set new rng as current as the new rng source
* provides better entropy quality and was not
* chosen by userspace.
*/
err = set_current_rng(rng);
if (err)
goto out_unlock;
hwrng: core - Fix use-after-free warning in hwrng_register() Commit daae28debcb0 has moved add_early_randomness() out of the rng_mutex and tries to protect the reference of the new rng device by incrementing the reference counter. But in hwrng_register(), the function can be called with a new device that is not set as the current_rng device and the reference has not been initialized. This patch fixes the problem by not using the reference counter when the device is not the current one: the reference counter is only meaningful in the case of the current rng device and a device is not used if it is not the current one (except in hwrng_register()) The problem has been reported by Marek Szyprowski on ARM 32bit Exynos5420-based Chromebook Peach-Pit board: WARNING: CPU: 3 PID: 1 at lib/refcount.c:156 hwrng_register+0x13c/0x1b4 refcount_t: increment on 0; use-after-free. Modules linked in: CPU: 3 PID: 1 Comm: swapper/0 Not tainted 5.4.0-rc1-00061-gdaae28debcb0 Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) [<c01124c8>] (unwind_backtrace) from [<c010dfb8>] (show_stack+0x10/0x14) [<c010dfb8>] (show_stack) from [<c0ae86d8>] (dump_stack+0xa8/0xd4) [<c0ae86d8>] (dump_stack) from [<c0127428>] (__warn+0xf4/0x10c) [<c0127428>] (__warn) from [<c01274b4>] (warn_slowpath_fmt+0x74/0xb8) [<c01274b4>] (warn_slowpath_fmt) from [<c054729c>] (hwrng_register+0x13c/0x1b4) [<c054729c>] (hwrng_register) from [<c0547e54>] (tpm_chip_register+0xc4/0x274) ... Reported-by: Marek Szyprowski <m.szyprowski@samsung.com> Fixes: daae28debcb0 ("hwrng: core - move add_early_randomness() out of rng_mutex") Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Laurent Vivier <lvivier@redhat.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2019-10-14 11:46:32 +00:00
/* to use current_rng in add_early_randomness() we need
* to take a ref
*/
is_new_current = true;
kref_get(&rng->ref);
}
mutex_unlock(&rng_mutex);
hwrng: core - Fix use-after-free warning in hwrng_register() Commit daae28debcb0 has moved add_early_randomness() out of the rng_mutex and tries to protect the reference of the new rng device by incrementing the reference counter. But in hwrng_register(), the function can be called with a new device that is not set as the current_rng device and the reference has not been initialized. This patch fixes the problem by not using the reference counter when the device is not the current one: the reference counter is only meaningful in the case of the current rng device and a device is not used if it is not the current one (except in hwrng_register()) The problem has been reported by Marek Szyprowski on ARM 32bit Exynos5420-based Chromebook Peach-Pit board: WARNING: CPU: 3 PID: 1 at lib/refcount.c:156 hwrng_register+0x13c/0x1b4 refcount_t: increment on 0; use-after-free. Modules linked in: CPU: 3 PID: 1 Comm: swapper/0 Not tainted 5.4.0-rc1-00061-gdaae28debcb0 Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) [<c01124c8>] (unwind_backtrace) from [<c010dfb8>] (show_stack+0x10/0x14) [<c010dfb8>] (show_stack) from [<c0ae86d8>] (dump_stack+0xa8/0xd4) [<c0ae86d8>] (dump_stack) from [<c0127428>] (__warn+0xf4/0x10c) [<c0127428>] (__warn) from [<c01274b4>] (warn_slowpath_fmt+0x74/0xb8) [<c01274b4>] (warn_slowpath_fmt) from [<c054729c>] (hwrng_register+0x13c/0x1b4) [<c054729c>] (hwrng_register) from [<c0547e54>] (tpm_chip_register+0xc4/0x274) ... Reported-by: Marek Szyprowski <m.szyprowski@samsung.com> Fixes: daae28debcb0 ("hwrng: core - move add_early_randomness() out of rng_mutex") Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Laurent Vivier <lvivier@redhat.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2019-10-14 11:46:32 +00:00
if (is_new_current || !rng->init) {
/*
* Use a new device's input to add some randomness to
* the system. If this rng device isn't going to be
* used right away, its init function hasn't been
* called yet by set_current_rng(); so only use the
* randomness from devices that don't need an init callback
*/
add_early_randomness(rng);
}
hwrng: core - Fix use-after-free warning in hwrng_register() Commit daae28debcb0 has moved add_early_randomness() out of the rng_mutex and tries to protect the reference of the new rng device by incrementing the reference counter. But in hwrng_register(), the function can be called with a new device that is not set as the current_rng device and the reference has not been initialized. This patch fixes the problem by not using the reference counter when the device is not the current one: the reference counter is only meaningful in the case of the current rng device and a device is not used if it is not the current one (except in hwrng_register()) The problem has been reported by Marek Szyprowski on ARM 32bit Exynos5420-based Chromebook Peach-Pit board: WARNING: CPU: 3 PID: 1 at lib/refcount.c:156 hwrng_register+0x13c/0x1b4 refcount_t: increment on 0; use-after-free. Modules linked in: CPU: 3 PID: 1 Comm: swapper/0 Not tainted 5.4.0-rc1-00061-gdaae28debcb0 Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) [<c01124c8>] (unwind_backtrace) from [<c010dfb8>] (show_stack+0x10/0x14) [<c010dfb8>] (show_stack) from [<c0ae86d8>] (dump_stack+0xa8/0xd4) [<c0ae86d8>] (dump_stack) from [<c0127428>] (__warn+0xf4/0x10c) [<c0127428>] (__warn) from [<c01274b4>] (warn_slowpath_fmt+0x74/0xb8) [<c01274b4>] (warn_slowpath_fmt) from [<c054729c>] (hwrng_register+0x13c/0x1b4) [<c054729c>] (hwrng_register) from [<c0547e54>] (tpm_chip_register+0xc4/0x274) ... Reported-by: Marek Szyprowski <m.szyprowski@samsung.com> Fixes: daae28debcb0 ("hwrng: core - move add_early_randomness() out of rng_mutex") Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Laurent Vivier <lvivier@redhat.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2019-10-14 11:46:32 +00:00
if (is_new_current)
put_rng(rng);
return 0;
out_unlock:
mutex_unlock(&rng_mutex);
out:
return err;
}
EXPORT_SYMBOL_GPL(hwrng_register);
void hwrng_unregister(struct hwrng *rng)
{
struct hwrng *old_rng, *new_rng;
int err;
mutex_lock(&rng_mutex);
old_rng = current_rng;
list_del(&rng->list);
hwrng: core - let sleep be interrupted when unregistering hwrng There are two deadlock scenarios that need addressing, which cause problems when the computer goes to sleep, the interface is set down, and hwrng_unregister() is called. When the deadlock is hit, sleep is delayed for tens of seconds, causing it to fail. These scenarios are: 1) The hwrng kthread can't be stopped while it's sleeping, because it uses msleep_interruptible() which does not react to kthread_stop. 2) A normal user thread can't be interrupted by hwrng_unregister() while it's sleeping, because hwrng_unregister() is called from elsewhere. We solve both issues by add a completion object called dying that fulfils waiters once we have started the process in hwrng_unregister. At the same time, we should cleanup a common and useless dmesg splat in the same area. Cc: <stable@vger.kernel.org> Reported-by: Gregory Erwin <gregerwin256@gmail.com> Fixes: fcd09c90c3c5 ("ath9k: use hw_random API instead of directly dumping into random.c") Link: https://lore.kernel.org/all/CAO+Okf6ZJC5-nTE_EJUGQtd8JiCkiEHytGgDsFGTEjs0c00giw@mail.gmail.com/ Link: https://lore.kernel.org/lkml/CAO+Okf5k+C+SE6pMVfPf-d8MfVPVq4PO7EY8Hys_DVXtent3HA@mail.gmail.com/ Link: https://bugs.archlinux.org/task/75138 Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Acked-by: Toke Høiland-Jørgensen <toke@toke.dk> Acked-by: Kalle Valo <kvalo@kernel.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2022-07-28 10:22:20 +00:00
complete_all(&rng->dying);
if (current_rng == rng) {
err = enable_best_rng();
if (err) {
drop_current_rng();
cur_rng_set_by_user = 0;
}
}
new_rng = get_current_rng_nolock();
if (list_empty(&rng_list)) {
mutex_unlock(&rng_mutex);
if (hwrng_fill)
kthread_stop(hwrng_fill);
} else
mutex_unlock(&rng_mutex);
if (new_rng) {
if (old_rng != new_rng)
add_early_randomness(new_rng);
put_rng(new_rng);
}
wait_for_completion(&rng->cleanup_done);
}
EXPORT_SYMBOL_GPL(hwrng_unregister);
static void devm_hwrng_release(struct device *dev, void *res)
{
hwrng_unregister(*(struct hwrng **)res);
}
static int devm_hwrng_match(struct device *dev, void *res, void *data)
{
struct hwrng **r = res;
if (WARN_ON(!r || !*r))
return 0;
return *r == data;
}
int devm_hwrng_register(struct device *dev, struct hwrng *rng)
{
struct hwrng **ptr;
int error;
ptr = devres_alloc(devm_hwrng_release, sizeof(*ptr), GFP_KERNEL);
if (!ptr)
return -ENOMEM;
error = hwrng_register(rng);
if (error) {
devres_free(ptr);
return error;
}
*ptr = rng;
devres_add(dev, ptr);
return 0;
}
EXPORT_SYMBOL_GPL(devm_hwrng_register);
void devm_hwrng_unregister(struct device *dev, struct hwrng *rng)
{
devres_release(dev, devm_hwrng_release, devm_hwrng_match, rng);
}
EXPORT_SYMBOL_GPL(devm_hwrng_unregister);
hwrng: core - let sleep be interrupted when unregistering hwrng There are two deadlock scenarios that need addressing, which cause problems when the computer goes to sleep, the interface is set down, and hwrng_unregister() is called. When the deadlock is hit, sleep is delayed for tens of seconds, causing it to fail. These scenarios are: 1) The hwrng kthread can't be stopped while it's sleeping, because it uses msleep_interruptible() which does not react to kthread_stop. 2) A normal user thread can't be interrupted by hwrng_unregister() while it's sleeping, because hwrng_unregister() is called from elsewhere. We solve both issues by add a completion object called dying that fulfils waiters once we have started the process in hwrng_unregister. At the same time, we should cleanup a common and useless dmesg splat in the same area. Cc: <stable@vger.kernel.org> Reported-by: Gregory Erwin <gregerwin256@gmail.com> Fixes: fcd09c90c3c5 ("ath9k: use hw_random API instead of directly dumping into random.c") Link: https://lore.kernel.org/all/CAO+Okf6ZJC5-nTE_EJUGQtd8JiCkiEHytGgDsFGTEjs0c00giw@mail.gmail.com/ Link: https://lore.kernel.org/lkml/CAO+Okf5k+C+SE6pMVfPf-d8MfVPVq4PO7EY8Hys_DVXtent3HA@mail.gmail.com/ Link: https://bugs.archlinux.org/task/75138 Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Acked-by: Toke Høiland-Jørgensen <toke@toke.dk> Acked-by: Kalle Valo <kvalo@kernel.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2022-07-28 10:22:20 +00:00
long hwrng_msleep(struct hwrng *rng, unsigned int msecs)
{
unsigned long timeout = msecs_to_jiffies(msecs) + 1;
return wait_for_completion_interruptible_timeout(&rng->dying, timeout);
}
EXPORT_SYMBOL_GPL(hwrng_msleep);
long hwrng_yield(struct hwrng *rng)
{
return wait_for_completion_interruptible_timeout(&rng->dying, 1);
}
EXPORT_SYMBOL_GPL(hwrng_yield);
static int __init hwrng_modinit(void)
{
int ret;
/* kmalloc makes this safe for virt_to_page() in virtio_rng.c */
rng_buffer = kmalloc(rng_buffer_size(), GFP_KERNEL);
if (!rng_buffer)
return -ENOMEM;
rng_fillbuf = kmalloc(rng_buffer_size(), GFP_KERNEL);
if (!rng_fillbuf) {
kfree(rng_buffer);
return -ENOMEM;
}
ret = register_miscdev();
if (ret) {
kfree(rng_fillbuf);
kfree(rng_buffer);
}
return ret;
}
static void __exit hwrng_modexit(void)
{
mutex_lock(&rng_mutex);
BUG_ON(current_rng);
kfree(rng_buffer);
kfree(rng_fillbuf);
mutex_unlock(&rng_mutex);
unregister_miscdev();
}
fs_initcall(hwrng_modinit); /* depends on misc_register() */
module_exit(hwrng_modexit);
MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver");
MODULE_LICENSE("GPL");