Skip to content

Commit f17a9a8

Browse files
committed
Specify better random seed with kernel mechanisms
A better random seed can be obtained by combining getpid(), getppid(), high-resolution timer, and ASLR.
1 parent 4b4cb46 commit f17a9a8

File tree

3 files changed

+73
-6
lines changed

3 files changed

+73
-6
lines changed

qtest.c

+32-2
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,17 @@
1111
#include <strings.h> /* strcasecmp */
1212
#include <sys/stat.h>
1313
#include <sys/wait.h>
14-
#include <time.h>
1514
#include <unistd.h>
1615

16+
#if defined(__APPLE__)
17+
#include <mach/mach_time.h>
18+
#else /* Assume POSIX environments */
19+
#include <time.h>
20+
#endif
21+
1722
#include "dudect/fixture.h"
1823
#include "list.h"
24+
#include "random.h"
1925

2026
/* Shannon entropy */
2127
extern double shannon_entropy(const uint8_t *input_data);
@@ -979,6 +985,26 @@ static bool sanity_check()
979985
return true;
980986
}
981987

988+
uintptr_t os_random(uintptr_t seed)
989+
{
990+
/* ASLR makes the address random */
991+
uintptr_t x = (uintptr_t) &os_random ^ seed;
992+
#if defined(__APPLE__)
993+
x ^= (uintptr_t) mach_absolute_time();
994+
#else
995+
struct timespec time;
996+
clock_gettime(CLOCK_MONOTONIC, &time);
997+
x ^= (uintptr_t) time.tv_sec;
998+
x ^= (uintptr_t) time.tv_nsec;
999+
#endif
1000+
/* Do a few randomization steps */
1001+
uintptr_t max = ((x ^ (x >> 17)) & 0x0F) + 1;
1002+
for (uintptr_t i = 0; i < max; i++)
1003+
x = random_shuffle(x);
1004+
assert(x);
1005+
return x;
1006+
}
1007+
9821008
#define BUFSIZE 256
9831009
int main(int argc, char *argv[])
9841010
{
@@ -1026,7 +1052,11 @@ int main(int argc, char *argv[])
10261052
}
10271053
}
10281054

1029-
srand((unsigned int) (time(NULL)));
1055+
/* A better seed can be obtained by combining getpid() and its parent ID
1056+
* with the Unix time.
1057+
*/
1058+
srand(os_random(getpid() ^ getppid()));
1059+
10301060
queue_init();
10311061
init_cmd();
10321062
console_init();

random.h

+35
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,39 @@ static inline uint8_t randombit(void)
1313
return ret & 1;
1414
}
1515

16+
#if INTPTR_MAX == INT64_MAX
17+
#define M_INTPTR_SHIFT (3)
18+
#elif INTPTR_MAX == INT32_MAX
19+
#define M_INTPTR_SHIFT (2)
20+
#else
21+
#error Platform pointers must be 32 or 64 bits
22+
#endif
23+
24+
#define M_INTPTR_SIZE (1 << M_INTPTR_SHIFT)
25+
26+
static inline uintptr_t random_shuffle(uintptr_t x)
27+
{
28+
/* Ensure we do not get stuck in generating zeros */
29+
if (x == 0)
30+
x = 17;
31+
32+
#if M_INTPTR_SIZE == 8
33+
/* by Sebastiano Vigna, see: <http://xoshiro.di.unimi.it/splitmix64.c> */
34+
x ^= x >> 30;
35+
x *= 0xbf58476d1ce4e5b9UL;
36+
x ^= x >> 27;
37+
x *= 0x94d049bb133111ebUL;
38+
x ^= x >> 31;
39+
#elif M_INTPTR_SIZE == 4
40+
/* by Chris Wellons, see: <https://nullprogram.com/blog/2018/07/31/> */
41+
x ^= x >> 16;
42+
x *= 0x7feb352dUL;
43+
x ^= x >> 15;
44+
x *= 0x846ca68bUL;
45+
x ^= x >> 16;
46+
#endif
47+
48+
return x;
49+
}
50+
1651
#endif

scripts/pre-commit.hook

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
#!/usr/bin/env bash
22

3-
CPPCHECK_suppresses="--inline-suppr harness.c --suppress=unmatchedSuppression:harness.c --suppress=missingIncludeSystem \
4-
--suppress=unusedFunction:linenoise.c \
5-
--suppress=ConfigurationNotChecked:random.c \
3+
CPPCHECK_suppresses="--inline-suppr harness.c --suppress=unmatchedSuppression:harness.c \
4+
--suppress=missingIncludeSystem \
5+
--suppress=noValidConfiguration \
6+
--suppress=unusedFunction \
7+
--suppress=unmatchedSuppression:qtest.c \
68
--suppress=identicalInnerCondition:log2_lshift16.h \
79
--suppress=nullPointerRedundantCheck:report.c \
810
--suppress=nullPointerRedundantCheck:harness.c \
9-
--suppress=nullPointer:qtest.c \
1011
--suppress=nullPointer:queue.c \
12+
--suppress=nullPointer:qtest.c \
1113
--suppress=unmatchedSuppression:queue.c"
1214
CPPCHECK_OPTS="-I. --enable=all --error-exitcode=1 --force $CPPCHECK_suppresses ."
1315

0 commit comments

Comments
 (0)