util: reset GetRandom functions in helpers after fork
Close /dev/urandom and drop cached getrandom() data after forking helper processes to avoid them getting the same sequence of random numbers (e.g. two NTS-KE helpers generating cookies with identical nonces). arc4random() is assumed to be able to detect forks and reseed automatically. This is not strictly necessary with the current code, which does not use the GetRandom functions before the NTS-KE helper processes are forked, but that could change in future. Also, call the reset function before exit to close /dev/urandom in order to avoid valgrind reporting the file object as "still reachable".
This commit is contained in:
parent
09067e06d3
commit
a0a9560258
6 changed files with 48 additions and 9 deletions
2
main.c
2
main.c
|
@ -141,6 +141,8 @@ MAI_CleanupAndExit(void)
|
|||
HSH_Finalise();
|
||||
LOG_Finalise();
|
||||
|
||||
UTI_ResetGetRandomFunctions();
|
||||
|
||||
exit(exit_status);
|
||||
}
|
||||
|
||||
|
|
|
@ -669,6 +669,8 @@ run_helper(uid_t uid, gid_t gid, int scfilter_level)
|
|||
CNF_Finalise();
|
||||
LOG_Finalise();
|
||||
|
||||
UTI_ResetGetRandomFunctions();
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
@ -710,6 +712,8 @@ NKS_PreInitialise(uid_t uid, gid_t gid, int scfilter_level)
|
|||
|
||||
is_helper = 1;
|
||||
|
||||
UTI_ResetGetRandomFunctions();
|
||||
|
||||
snprintf(prefix, sizeof (prefix), "nks#%d:", i + 1);
|
||||
LOG_SetDebugPrefix(prefix);
|
||||
LOG_CloseParentFd();
|
||||
|
|
|
@ -662,6 +662,8 @@ PRV_StartHelper(void)
|
|||
close(fd);
|
||||
}
|
||||
|
||||
UTI_ResetGetRandomFunctions();
|
||||
|
||||
/* ignore signals, the process will exit on OP_QUIT request */
|
||||
UTI_SetQuitSignalsHandler(SIG_IGN, 1);
|
||||
|
||||
|
|
|
@ -670,6 +670,10 @@ test_unit(void)
|
|||
UTI_GetRandomBytesUrandom(buf, j);
|
||||
if (j && buf[j - 1] % 2)
|
||||
c++;
|
||||
if (random() % 10000 == 0) {
|
||||
UTI_ResetGetRandomFunctions();
|
||||
TEST_CHECK(!urandom_file);
|
||||
}
|
||||
}
|
||||
TEST_CHECK(c > 46000 && c < 48000);
|
||||
|
||||
|
@ -678,6 +682,12 @@ test_unit(void)
|
|||
UTI_GetRandomBytes(buf, j);
|
||||
if (j && buf[j - 1] % 2)
|
||||
c++;
|
||||
if (random() % 10000 == 0) {
|
||||
UTI_ResetGetRandomFunctions();
|
||||
#if HAVE_GETRANDOM
|
||||
TEST_CHECK(getrandom_buf_available == 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
TEST_CHECK(c > 46000 && c < 48000);
|
||||
|
||||
|
|
35
util.c
35
util.c
|
@ -1402,29 +1402,32 @@ UTI_DropRoot(uid_t uid, gid_t gid)
|
|||
|
||||
#define DEV_URANDOM "/dev/urandom"
|
||||
|
||||
static FILE *urandom_file = NULL;
|
||||
|
||||
void
|
||||
UTI_GetRandomBytesUrandom(void *buf, unsigned int len)
|
||||
{
|
||||
static FILE *f = NULL;
|
||||
|
||||
if (!f)
|
||||
f = UTI_OpenFile(NULL, DEV_URANDOM, NULL, 'R', 0);
|
||||
if (fread(buf, 1, len, f) != len)
|
||||
if (!urandom_file)
|
||||
urandom_file = UTI_OpenFile(NULL, DEV_URANDOM, NULL, 'R', 0);
|
||||
if (fread(buf, 1, len, urandom_file) != len)
|
||||
LOG_FATAL("Can't read from %s", DEV_URANDOM);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
#ifdef HAVE_GETRANDOM
|
||||
|
||||
static unsigned int getrandom_buf_available = 0;
|
||||
|
||||
static void
|
||||
get_random_bytes_getrandom(char *buf, unsigned int len)
|
||||
{
|
||||
static char rand_buf[256];
|
||||
static unsigned int available = 0, disabled = 0;
|
||||
static unsigned int disabled = 0;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (!available) {
|
||||
if (getrandom_buf_available == 0) {
|
||||
if (disabled)
|
||||
break;
|
||||
|
||||
|
@ -1433,10 +1436,10 @@ get_random_bytes_getrandom(char *buf, unsigned int len)
|
|||
break;
|
||||
}
|
||||
|
||||
available = sizeof (rand_buf);
|
||||
getrandom_buf_available = sizeof (rand_buf);
|
||||
}
|
||||
|
||||
buf[i] = rand_buf[--available];
|
||||
buf[i] = rand_buf[--getrandom_buf_available];
|
||||
}
|
||||
|
||||
if (i < len)
|
||||
|
@ -1460,6 +1463,20 @@ UTI_GetRandomBytes(void *buf, unsigned int len)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
UTI_ResetGetRandomFunctions(void)
|
||||
{
|
||||
if (urandom_file) {
|
||||
fclose(urandom_file);
|
||||
urandom_file = NULL;
|
||||
}
|
||||
#ifdef HAVE_GETRANDOM
|
||||
getrandom_buf_available = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
int
|
||||
UTI_BytesToHex(const void *buf, unsigned int buf_len, char *hex, unsigned int hex_len)
|
||||
{
|
||||
|
|
4
util.h
4
util.h
|
@ -224,6 +224,10 @@ extern void UTI_GetRandomBytesUrandom(void *buf, unsigned int len);
|
|||
generating long-term keys */
|
||||
extern void UTI_GetRandomBytes(void *buf, unsigned int len);
|
||||
|
||||
/* Close /dev/urandom and drop any cached data used by the GetRandom functions
|
||||
to prevent forked processes getting the same sequence of random numbers */
|
||||
extern void UTI_ResetGetRandomFunctions(void);
|
||||
|
||||
/* Print data in hexadecimal format */
|
||||
extern int UTI_BytesToHex(const void *buf, unsigned int buf_len, char *hex, unsigned int hex_len);
|
||||
|
||||
|
|
Loading…
Reference in a new issue