lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Mon, 21 Sep 2020 09:58:32 +0200 From: Nicolai Stange <nstange@...e.de> To: "Theodore Y. Ts'o" <tytso@....edu> Cc: linux-crypto@...r.kernel.org, LKML <linux-kernel@...r.kernel.org>, Arnd Bergmann <arnd@...db.de>, Greg Kroah-Hartman <gregkh@...uxfoundation.org>, "Eric W. Biederman" <ebiederm@...ssion.com>, "Alexander E. Patrakov" <patrakov@...il.com>, "Ahmed S. Darwish" <darwish.07@...il.com>, Willy Tarreau <w@....eu>, Matthew Garrett <mjg59@...f.ucam.org>, Vito Caputo <vcaputo@...garu.com>, Andreas Dilger <adilger.kernel@...ger.ca>, Jan Kara <jack@...e.cz>, Ray Strode <rstrode@...hat.com>, William Jon McCann <mccann@....edu>, zhangjs <zachary@...shancloud.com>, Andy Lutomirski <luto@...nel.org>, Florian Weimer <fweimer@...hat.com>, Lennart Poettering <mzxreary@...inter.de>, Peter Matthias <matthias.peter@....bund.de>, Marcelo Henrique Cerri <marcelo.cerri@...onical.com>, Roman Drahtmueller <draht@...altsekun.de>, Neil Horman <nhorman@...hat.com>, Randy Dunlap <rdunlap@...radead.org>, Julia Lawall <julia.lawall@...ia.fr>, Dan Carpenter <dan.carpenter@...cle.com>, Andy Lavr <andy.lavr@...il.com>, Eric Biggers <ebiggers@...nel.org>, "Jason A. Donenfeld" <Jason@...c4.com>, Stephan Müller <smueller@...onox.de>, Torsten Duwe <duwe@...e.de>, Petr Tesarik <ptesarik@...e.cz>, Nicolai Stange <nstange@...e.de> Subject: [RFC PATCH 16/41] random: convert random_ioctl() to queued_entropy API In an effort to drop credit_entropy_bits_safe() in favor of the new queue_entropy()/dispatch_queued_entropy() API, convert random_ioctl() from the former to the latter. Implement two helpers: - queue_entropy_bits_safe(), which checks the entropy passed from userspace for extreme values in analogy to what credit_entropy_bits_safe() did - discard_queue_entropy(), which is invoked from random_ioctly() to discard the entropy queued prior to the write_pool() call in case the latter fails. Use them to convert the two call sites of credit_entropy_bits_safe() in random_ioctl() to the new API. As a side effect, the pool entropy watermark as tracked over the duration of the write_pool() operation is now taken correctly taken into account when calulating the amount of new entropy to dispatch to the pool based on the latter's fill level. Signed-off-by: Nicolai Stange <nstange@...e.de> --- drivers/char/random.c | 57 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index 78e65367ea86..03eadefabbca 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -737,7 +737,9 @@ struct queued_entropy { * dispatch. However, any such sequence of invocations must eventually * be followed by exactly one call to either of __dequeue_entropy(), * __dispatch_queued_entropy_fast() or dispatch_queued_entropy() - * when the actual pool mixing has completed. + * when the actual pool mixing has completed. Alternatively, + * discard_queued_entropy() may be called in case the mixing has + * failed. * __queue_entropy() must be called with r->lock held. * * Entropy extraction is a two-step process: @@ -813,6 +815,26 @@ static void queue_entropy(struct entropy_store *r, struct queued_entropy *q, spin_unlock_irqrestore(&r->lock, flags); } +/* + * Queue entropy which comes from userspace and might take extreme + * values. + */ +static int queue_entropy_bits_safe(struct entropy_store *r, + struct queued_entropy *q, + int nbits) +{ + const int nbits_max = r->poolinfo->poolwords * 32; + + if (nbits < 0) + return -EINVAL; + + /* Cap the value to avoid overflows */ + nbits = min(nbits, nbits_max); + + queue_entropy(r, q, nbits << ENTROPY_SHIFT); + return 0; +} + /* * Dequeue previously queued entropy and return the pool entropy * watermark to be used in pool_entropy_delta(). @@ -950,6 +972,22 @@ static void dispatch_queued_entropy(struct entropy_store *r, } } +/* + * Discard queued entropy. May be called when e.g. a write_pool() + * operation failed and the corresponding previously queued entropy + * should not get dispatched to the pool. + */ +static void discard_queued_entropy(struct entropy_store *r, + struct queued_entropy *q) +{ + unsigned long flags; + int pool_watermark; + + spin_lock_irqsave(&r->lock, flags); + __dequeue_entropy(r, q, &pool_watermark); + spin_unlock_irqrestore(&r->lock, flags); +} + /* * Credit the entropy store with n bits of entropy. * Use credit_entropy_bits_safe() if the value comes from userspace @@ -2272,6 +2310,7 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg) int size, ent_count; int __user *p = (int __user *)arg; int retval; + struct queued_entropy q = { 0 }; switch (cmd) { case RNDGETENTCNT: @@ -2285,7 +2324,11 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg) return -EPERM; if (get_user(ent_count, p)) return -EFAULT; - return credit_entropy_bits_safe(&input_pool, ent_count); + retval = queue_entropy_bits_safe(&input_pool, &q, ent_count); + if (retval < 0) + return retval; + dispatch_queued_entropy(&input_pool, &q); + return 0; case RNDADDENTROPY: if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -2295,11 +2338,17 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg) return -EINVAL; if (get_user(size, p++)) return -EFAULT; + retval = queue_entropy_bits_safe(&input_pool, &q, ent_count); + if (retval < 0) + return retval; retval = write_pool(&input_pool, (const char __user *)p, size); - if (retval < 0) + if (retval < 0) { + discard_queued_entropy(&input_pool, &q); return retval; - return credit_entropy_bits_safe(&input_pool, ent_count); + } + discard_queued_entropy(&input_pool, &q); + return 0; case RNDZAPENTCNT: case RNDCLEARPOOL: /* -- 2.26.2
Powered by blists - more mailing lists