Make UtilRandomString() more secure.

Two ways this is more secure:

1. The seed is only generated once, not every time the function is called.
2. All threads share the same seed, which means timing attacks aren't
   possible.

Because we are using a mutex, performance may suffer slightly.
This commit is contained in:
Jordan Bancino 2023-01-07 00:18:44 +00:00
parent 7cd9fe8bd7
commit 8323eb38c9

View file

@ -32,6 +32,7 @@
#include <math.h> #include <math.h>
#include <time.h> #include <time.h>
#include <unistd.h>
#include <errno.h> #include <errno.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -399,14 +400,13 @@ UtilGetLine(char **linePtr, size_t * n, FILE * stream)
char * char *
UtilRandomString(size_t len) UtilRandomString(size_t len)
{ {
static const char charset[] = static const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; static pthread_mutex_t seedLock = PTHREAD_MUTEX_INITIALIZER;
static unsigned int seed = 0;
char *str; char *str;
size_t i; size_t i;
unsigned int seed = UtilServerTs() * (unsigned long) pthread_self();
if (!len) if (!len)
{ {
return NULL; return NULL;
@ -418,11 +418,20 @@ UtilRandomString(size_t len)
return NULL; return NULL;
} }
pthread_mutex_lock(&seedLock);
if (!seed)
{
seed = UtilServerTs() ^ getpid() ^ (unsigned long) pthread_self();
}
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
{ {
str[i] = charset[rand_r(&seed) % (sizeof(charset) - 1)]; str[i] = charset[rand_r(&seed) % (sizeof(charset) - 1)];
} }
pthread_mutex_unlock(&seedLock);
str[len] = '\0'; str[len] = '\0';
return str; return str;
} }