Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 5 Sep 2012 13:47:07 +0100
From:      RW <rwmaillists@googlemail.com>
To:        freebsd-security@freebsd.org
Subject:   Re: svn commit: r239598 - head/etc/rc.d
Message-ID:  <20120905134707.09a71c18@gumby.homeunix.com>
In-Reply-To: <5046D7F0.1000601@FreeBSD.org>
References:  <201208222337.q7MNbORo017642@svn.freebsd.org> <5043E449.8050005@FreeBSD.org> <20120904220126.GA85339@dragon.NUXI.org> <50468326.8070009@FreeBSD.org> <20120905021248.5a17ace9@gumby.homeunix.com> <5046D7F0.1000601@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 04 Sep 2012 21:41:20 -0700
Doug Barton wrote:

> Can you point out where in the source you're seeing these things?


It's in src/sys/dev/random/randomdev_soft.c:

random_yarrow_write()
random_harvest_internal()
random_kthread()

------------------------------------------------------------------

void
random_yarrow_write(void *buf, int count)
{
	int i;
	u_int chunk;

	/*
	 * Break the input up into HARVESTSIZE chunks. The writer has
	too
	 * much control here, so "estimate" the entropy as zero.
	 */
	for (i = 0; i < count; i += HARVESTSIZE) {
		chunk = HARVESTSIZE;
		if (i + chunk >= count)
			chunk = (u_int)(count - i);
		random_harvest_internal(get_cyclecount(), (char *)buf +
	i, chunk, 0, 0, RANDOM_WRITE);
	}
}



/* Entropy harvesting routine. This is supposed to be fast; do
 * not do anything slow in here!
 */
static void
random_harvest_internal(u_int64_t somecounter, const void *entropy,
    u_int count, u_int bits, u_int frac, enum esource origin)
{
	struct harvest *event;

	KASSERT(origin == RANDOM_START || origin == RANDOM_WRITE ||
            origin == RANDOM_KEYBOARD || origin == RANDOM_MOUSE ||
            origin == RANDOM_NET || origin == RANDOM_INTERRUPT ||
            origin == RANDOM_PURE,
	    ("random_harvest_internal: origin %d invalid\n", origin));

	/* Lockless read to avoid lock operations if fifo is full. */
	if (harvestfifo[origin].count >= RANDOM_FIFO_MAX)
		return;

	mtx_lock_spin(&harvest_mtx);

	/*
	 * Don't make the harvest queues too big - help to prevent
	low-grade
	 * entropy swamping
	 */
	if (harvestfifo[origin].count < RANDOM_FIFO_MAX) {
		event = STAILQ_FIRST(&emptyfifo.head);
		if (event != NULL) {
			/* Add the harvested data to the fifo */
			STAILQ_REMOVE_HEAD(&emptyfifo.head, next);
			harvestfifo[origin].count++;
			event->somecounter = somecounter;
			event->size = count;
			event->bits = bits;
			event->frac = frac;
			event->source = origin;

			/* XXXX Come back and make this dynamic! */
			count = MIN(count, HARVESTSIZE);
			memcpy(event->entropy, entropy, count);

			STAILQ_INSERT_TAIL(&harvestfifo[origin].head,
			    event, next);
		}
	}
	mtx_unlock_spin(&harvest_mtx);
}




static void
random_kthread(void *arg __unused)
{
	STAILQ_HEAD(, harvest) local_queue;
	struct harvest *event = NULL;
	int local_count;
	enum esource source;

	STAILQ_INIT(&local_queue);
	local_count = 0;

	/* Process until told to stop */
	for (; random_kthread_control >= 0;) {

		/* Cycle through all the entropy sources */
		mtx_lock_spin(&harvest_mtx);
		for (source = RANDOM_START; source < ENTROPYSOURCE;
		source++) { /*
			 * Drain entropy source records into a
		thread-local
			 * queue for processing while not holding the
		mutex. */
			STAILQ_CONCAT(&local_queue,
		&harvestfifo[source].head); local_count +=
		harvestfifo[source].count; harvestfifo[source].count =
		0; }

		/*
		 * Deal with events, if any, dropping the mutex as we
		process
		 * each event.  Then push the events back into the empty
		 * fifo.
		 */
		if (!STAILQ_EMPTY(&local_queue)) {
			mtx_unlock_spin(&harvest_mtx);
			STAILQ_FOREACH(event, &local_queue, next)
				random_process_event(event);
			mtx_lock_spin(&harvest_mtx);
			STAILQ_CONCAT(&emptyfifo.head, &local_queue);
			emptyfifo.count += local_count;
			local_count = 0;
		}
		mtx_unlock_spin(&harvest_mtx);

		KASSERT(local_count == 0, ("random_kthread: local_count
		%d", local_count));

		/*
		 * If a queue flush was commanded, it has now happened,
		 * and we can mark this by resetting the command.
		 */
		if (random_kthread_control == 1)
			random_kthread_control = 0;

		/* Work done, so don't belabour the issue */
		pause("-", hz / 10);

	}

	random_set_wakeup_exit(&random_kthread_control);
	/* NOTREACHED */
}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120905134707.09a71c18>