Preliminary support to intercept getrandom() #275

This commit is contained in:
Wolfgang Hommel
2020-11-15 21:57:10 +01:00
parent dacc5866a7
commit ca2f3fefa1
3 changed files with 77 additions and 1 deletions

View File

@@ -38,6 +38,9 @@
# FAKE_SETTIME
# - Intercept clock_settime(), settimeofday(), and adjtime()
#
# FAKE_RANDOM
# - Intercept getrandom()
#
# FORCE_MONOTONIC_FIX
# - If the test program hangs forever on
# " pthread_cond_timedwait: CLOCK_MONOTONIC test

View File

@@ -122,6 +122,10 @@ struct utimbuf {
};
#endif
#ifdef FAKE_RANDOM
#include <sys/random.h>
#endif
/*
* Per thread variable, which we turn on inside real_* calls to avoid modifying
* time multiple times of for the whole process to prevent faking time
@@ -219,6 +223,10 @@ static int (*real_utimensat) (int dirfd, const char *filename, co
static int (*real_futimens) (int fd, const struct timespec times[2]);
#endif
#ifdef FAKE_RANDOM
static ssize_t (*real_getrandom) (void *buf, size_t buflen, unsigned int flags);
#endif
static int initialized = 0;
/* prototypes */
@@ -1181,7 +1189,7 @@ static void fake_two_timespec(const struct timespec in_times[2], struct timespec
out_times[j] = in_times[j];
}
}
else
else
{
timersub2(&in_times[j], &user_offset, &out_times[j], n);
}
@@ -2412,6 +2420,11 @@ static void ftpl_init(void)
# endif
real___clock_gettime = dlsym(RTLD_NEXT, "__clock_gettime");
#endif
#ifdef FAKE_RANDOM
real_getrandom = dlsym(RTLD_NEXT, "getrandom");
#endif
#ifdef FAKE_PTHREAD
#ifdef __GLIBC__
@@ -3613,6 +3626,41 @@ int adjtime (const struct timeval *delta, struct timeval *olddelta)
}
#endif
#ifdef FAKE_RANDOM
/*
Local copy of
Middle Square Weyl Sequence Random Number Generator
Copyright (c) 2014-2020 Bernard Widynski
License: GNU GPL v3
see https://mswsrng.wixsite.com/rand
adapted to take the seed s as a parameter and return only a byte
*/
inline static uint32_t fakerandom_msws(uint64_t s) {
static uint64_t x = 0, w = 0;
x *= x; x += (w += s);
x = (x>>32) | (x<<32);
return (char) x & 0xFF;
}
ssize_t getrandom(void *buf, size_t buflen, unsigned int flags) {
char *seedstring = getenv("FAKERANDOM_SEED");
char *b = buf;
if (seedstring != NULL) {
long long int seed = strtoll(seedstring, NULL, 0);
for (size_t i = 0; i < buflen; i++) {
b[i] = fakerandom_msws(seed);
}
return buflen;
}
else { /* if no FAKERANDOM_SEED was given, use the original function */
return real_getrandom(buf, buflen, flags);
}
}
#endif
/*
* Editor modelines
*

25
test/getrandom_test.c Normal file
View File

@@ -0,0 +1,25 @@
#include <stdio.h>
#include <sys/random.h>
#include <stdlib.h>
int main(int argc, char **argv) {
char *buf = calloc(100, 1);
size_t buflen = 100;
unsigned flags = GRND_NONBLOCK;
fprintf(stdout, "Before getrandom:\n");
for (int i=0; i < buflen; i++) { fprintf(stdout, "%hhu ", buf[i]); }
fprintf(stdout, "\n");
int result = getrandom(buf, buflen, flags);
fprintf(stdout, "getrandom() result: %d\n", result);
if (result == -1) perror("getrandom() unsuccessful");
fprintf(stdout, "After getrandom:\n");
for (int i=0; i < buflen; i++) { fprintf(stdout, "%hhu ", buf[i]); }
fprintf(stdout, "\n");
free(buf);
return 0;
}