Re: [PATCH v6 1/5] random: Blocking API for accessing nonblocking_pool

Theodore Ts'o
2015-05-18T15:02:55Z

On Mon, May 18, 2015 at 03:26:13PM +0200, Stephan Mueller wrote:
>
> I am just running into an interesting problem with a missing cancel operation:
> a caller instantiates a DRBG handle and invokes the seeding operation. The
> nonblocking_pool is not initialized. Therefore, the callback is put onto the
> list for being processed later.
>
> Now, the caller releases the DRBG handle *before* the callback is triggered.
>
> The callback is triggered with a pointer that is invalid, but the pointer is
> non-NULL. Therefore, I am not sure how to validate the pointer in the callback
> function.

The simplest thing to do is to put a refcount on inside the DRBG
handle structure. The caller instantiates the DRBG handle, and
invokes the the DRBG. The DRBG, since it is kicking off an
asynchronous operation, increments the refcount.

Both the caller and the callback function, before they exit, drop the
refcount, and if they see the refcount is zero, they free the DRBG
handle and the memory where the random seed is to be (or has been)
deposited.

This is the same pattern that the block I/O layer uses with a bio
struct. In the BIO case, it's important since the callback function
could have been called and returned before the caller gets control
back from the bio_submit() call. Or the struct bio may contain an
EOPNOTSUPP error, in which case there will be no callback function
dispatched. So long as everyone handles the refcount rules, it all
works out.

Regards,

- Ted