Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/random/randomdev.c
/*- | /*- | ||||
* Copyright (c) 2000-2015 Mark R V Murray | * Copyright (c) 2000-2015 Mark R V Murray | ||||
rwatson: ... | |||||
* All rights reserved. | * All rights reserved. | ||||
* | * | ||||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
* modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
* are met: | * are met: | ||||
* 1. Redistributions of source code must retain the above copyright | * 1. Redistributions of source code must retain the above copyright | ||||
* notice, this list of conditions and the following disclaimer | * notice, this list of conditions and the following disclaimer | ||||
* in this position and unchanged. | * in this position and unchanged. | ||||
▲ Show 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
struct random_algorithm random_alg_context = { | struct random_algorithm random_alg_context = { | ||||
.ra_ident = "Dummy", | .ra_ident = "Dummy", | ||||
.ra_reseed = dummy_random, | .ra_reseed = dummy_random, | ||||
.ra_seeded = (random_alg_seeded_t *)dummy_random_zero, | .ra_seeded = (random_alg_seeded_t *)dummy_random_zero, | ||||
.ra_pre_read = dummy_random, | .ra_pre_read = dummy_random, | ||||
.ra_read = (random_alg_read_t *)dummy_random_zero, | .ra_read = (random_alg_read_t *)dummy_random_zero, | ||||
.ra_post_read = dummy_random, | |||||
.ra_write = (random_alg_write_t *)dummy_random_zero, | .ra_write = (random_alg_write_t *)dummy_random_zero, | ||||
.ra_event_processor = NULL, | .ra_event_processor = NULL, | ||||
.ra_poolcount = 0, | .ra_poolcount = 0, | ||||
}; | }; | ||||
#else /* !defined(RANDOM_DUMMY) */ | #else /* !defined(RANDOM_DUMMY) */ | ||||
LIST_HEAD(sources_head, random_sources); | LIST_HEAD(sources_head, random_sources); | ||||
Show All 14 Lines | randomdev_read(struct cdev *dev __unused, struct uio *uio, int flags) | ||||
uint8_t *random_buf; | uint8_t *random_buf; | ||||
int c, error; | int c, error; | ||||
ssize_t nbytes; | ssize_t nbytes; | ||||
random_buf = malloc(PAGE_SIZE, M_ENTROPY, M_WAITOK); | random_buf = malloc(PAGE_SIZE, M_ENTROPY, M_WAITOK); | ||||
random_alg_context.ra_pre_read(); | random_alg_context.ra_pre_read(); | ||||
/* (Un)Blocking logic */ | /* (Un)Blocking logic */ | ||||
error = 0; | error = 0; | ||||
while (!random_alg_context.ra_seeded() && error == 0) { | while (!random_alg_context.ra_seeded()) { | ||||
if (flags & O_NONBLOCK) { | if (flags & O_NONBLOCK) { | ||||
error = EWOULDBLOCK; | error = EWOULDBLOCK; | ||||
break; | break; | ||||
} | } | ||||
tsleep(&random_alg_context, 0, "randrd", hz/10); | tsleep(&random_alg_context, 0, "randseed", hz/10); | ||||
/* keep tapping away at the pre-read until we seed/unblock. */ | /* keep tapping away at the pre-read until we seed/unblock. */ | ||||
random_alg_context.ra_pre_read(); | random_alg_context.ra_pre_read(); | ||||
printf("random: %s unblock (error = %d)\n", __func__, error); | printf("random: %s unblock wait\n", __func__); | ||||
} | } | ||||
if (error == 0) { | if (error == 0) { | ||||
#if !defined(RANDOM_DUMMY) | #if !defined(RANDOM_DUMMY) | ||||
/* XXX: FIX!! Next line as an atomic operation? */ | /* XXX: FIX!! Next line as an atomic operation? */ | ||||
read_rate += (uio->uio_resid + sizeof(uint32_t))/sizeof(uint32_t); | read_rate += (uio->uio_resid + sizeof(uint32_t))/sizeof(uint32_t); | ||||
#endif | #endif | ||||
nbytes = uio->uio_resid; | nbytes = uio->uio_resid; | ||||
while (uio->uio_resid && !error) { | while (uio->uio_resid && !error) { | ||||
c = MIN(uio->uio_resid, PAGE_SIZE); | c = MIN(uio->uio_resid, PAGE_SIZE); | ||||
random_alg_context.ra_read(random_buf, c); | random_alg_context.ra_read(random_buf, c); | ||||
error = uiomove(random_buf, c, uio); | error = uiomove(random_buf, c, uio); | ||||
} | } | ||||
random_alg_context.ra_post_read(); | |||||
if (nbytes != uio->uio_resid && (error == ERESTART || error == EINTR) ) | if (nbytes != uio->uio_resid && (error == ERESTART || error == EINTR) ) | ||||
/* Return partial read, not error. */ | /* Return partial read, not error. */ | ||||
error = 0; | error = 0; | ||||
} | } | ||||
free(random_buf, M_ENTROPY); | free(random_buf, M_ENTROPY); | ||||
return (error); | return (error); | ||||
} | } | ||||
Show All 17 Lines | |||||
#if !defined(RANDOM_DUMMY) | #if !defined(RANDOM_DUMMY) | ||||
/* XXX: FIX!! Next line as an atomic operation? */ | /* XXX: FIX!! Next line as an atomic operation? */ | ||||
read_rate += (len + sizeof(uint32_t))/sizeof(uint32_t); | read_rate += (len + sizeof(uint32_t))/sizeof(uint32_t); | ||||
#endif | #endif | ||||
read_len = len; | read_len = len; | ||||
total_read = 0; | total_read = 0; | ||||
while (read_len) { | while (read_len) { | ||||
c = MIN(read_len, PAGE_SIZE); | c = MIN(read_len, PAGE_SIZE); | ||||
random_alg_context.ra_read(&local_buf[total_read], c); | random_alg_context.ra_read(&local_buf[total_read], c); | ||||
allanjudeUnsubmitted Not Done Inline Actionsread_random is not taking care that len is a multiple of RANDOM_BLOCKSIZE here this causes ZFS to panic when it tries to generate a GUID to create a new pool. spa_generate_guid tries to read 8 bytes of random via read_random random_fortuna_read() ASSERTs because bytecount (= 8) must be a multiple of 16 allanjude: read_random is not taking care that len is a multiple of RANDOM_BLOCKSIZE here
this causes ZFS… | |||||
markmAuthorUnsubmitted Not Done Inline ActionsFixing now. Thanks! markm: Fixing now. Thanks! | |||||
read_len -= c; | read_len -= c; | ||||
total_read += c; | total_read += c; | ||||
} | } | ||||
memcpy(random_buf, local_buf, len); | memcpy(random_buf, local_buf, len); | ||||
} else | } else | ||||
len = 0; | len = 0; | ||||
random_alg_context.ra_post_read(); | |||||
return (len); | return (len); | ||||
} | } | ||||
/* ARGSUSED */ | /* ARGSUSED */ | ||||
static int | static int | ||||
randomdev_write(struct cdev *dev __unused, struct uio *uio, int flags __unused) | randomdev_write(struct cdev *dev __unused, struct uio *uio, int flags __unused) | ||||
{ | { | ||||
uint8_t *random_buf; | uint8_t *random_buf; | ||||
▲ Show 20 Lines • Show All 192 Lines • Show Last 20 Lines |
...