[lxc-devel] [PATCH] hwaddr templating

Kent R. Spillner kspillner at acm.org
Mon Jan 6 18:42:18 UTC 2014


On Mon, Jan 06, 2014 at 01:54:14PM +0100, Guillaume ZITTA wrote:
> This chage introduce also a common randinit() function that could be
> used to initialize random generator.

Is there any reason to always prefer libc rand() over /dev/urandom?
I realize the strength of the random numbers in this particular
case probably isn't that important but if you want this randinit()
to be more generally useful then perhaps it makes sense to change a
few things now:

> +void randinit(void)
> +{
> +    /*
> +    srand pre-seed function based on /dev/urandom
> +    */
> +    FILE *f;
> +    process_lock();
> +    f = fopen("/dev/urandom", "r");
> +    process_unlock();
> +    if (f) {

When will this ever fail on Linux?  Does Android provide /dev/urandom?

> +        unsigned int seed;
> +        int ret = fread(&seed, sizeof(seed), 1, f);
> +        if (ret != 1)
> +            seed = time(NULL);
> +        process_lock();
> +        fclose(f);
> +        process_unlock();
> +        srand(seed);
> +    } else
> +        srand(time(NULL));
> +}

When reading this diff it just felt a little strange that when /dev/urandom
is working we still only read one byte from it just to seed libc rand().
What if instead of randinit() you introduced a new function that fills a
buffer with the requested number of random ints, e.g.:

int lxc_randints(int *buf, size_t count)
{
    FILE *f;

    f = fopen("/dev/urandom", "r");

    if (f) {
        int ret;

        ret = fread(buf, sizeof(int), count, f);
        /* check ret, handle errors, etc. */
    } else {
        srand(time(NULL));
        do { buf[count] = rand(); } while (count--);
        /* handle errors, etc. */
    }

    return 0;
}

And then rand_complete_hwaddr becomes something like:

static int rand_complete_hwaddr(char *hwaddr)
{
    const char hex[] = "0123456789abcdev";
#define MAC_ADDRESS_HEX_DIGITS 12
    char buf[MAC_ADDRESS_HEX_DIGITS], *curs = hwaddr;
    int i = 0;

    lxc_randints(buf, MAC_ADDRESS_HEX_DIGITS);

    while (*curs != '\0' && i < MAC_ADDRESS_HEX_DIGITS) {
        if (*curs == 'x' || *curs == 'X') {
            if (curs - hwaddr == 1)
                *curs = hex[buf[i] & 0x0E];
            else
                *curs = hex[buf[i] & 0x0F];
        }

        curs++;
        i++;
    }

    return 0;
}


More information about the lxc-devel mailing list