77
88static void * current_test = NULL ;
99static int syscall_called = 0 ;
10+ static int glib_getrandom_called = 0 ;
1011
1112// ======== Helper macros and functions ========
1213
@@ -45,6 +46,9 @@ static void test_functional(void) {
4546 uint8_t buf1 [20 ] = {}, buf2 [sizeof (buf1 )] = {};
4647 const int ret1 = randombytes (buf1 , sizeof (buf1 ));
4748 const int ret2 = randombytes (buf2 , sizeof (buf2 ));
49+ if (ret1 != 0 || ret2 != 0 ) {
50+ printf ("error: %s\n" , strerror (errno ));
51+ }
4852 assert (ret1 == 0 );
4953 assert (ret2 == 0 );
5054 assert (memcmp (buf1 , buf2 , sizeof (buf1 )) != 0 );
@@ -58,7 +62,7 @@ static void test_empty(void) {
5862 assert (memcmp (buf , zero , sizeof (zero )) == 0 );
5963}
6064
61- static void test_getrandom_partial (void ) {
65+ static void test_getrandom_syscall_partial (void ) {
6266 syscall_called = 0 ;
6367 uint8_t buf [100 ] = {};
6468 const int ret = randombytes (buf , sizeof (buf ));
@@ -69,7 +73,7 @@ static void test_getrandom_partial(void) {
6973 }
7074}
7175
72- static void test_getrandom_interrupted (void ) {
76+ static void test_getrandom_syscall_interrupted (void ) {
7377 syscall_called = 0 ;
7478 uint8_t zero [20 ] = {};
7579 uint8_t buf [sizeof (zero )] = {};
@@ -78,6 +82,26 @@ static void test_getrandom_interrupted(void) {
7882 assert (memcmp (buf , zero , 20 ) != 0 );
7983}
8084
85+ static void test_getrandom_glib_partial (void ) {
86+ glib_getrandom_called = 0 ;
87+ uint8_t buf [100 ] = {};
88+ const int ret = randombytes (buf , sizeof (buf ));
89+ assert (ret == 0 );
90+ assert (glib_getrandom_called >= 5 );
91+ for (int i = 1 ; i < 5 ; i ++ ) {
92+ assert (memcmp (& buf [0 ], & buf [20 * i ], 20 ) != 0 );
93+ }
94+ }
95+
96+ static void test_getrandom_glib_interrupted (void ) {
97+ glib_getrandom_called = 0 ;
98+ uint8_t zero [20 ] = {};
99+ uint8_t buf [sizeof (zero )] = {};
100+ const int ret = randombytes (buf , sizeof (buf ));
101+ assert (ret == 0 );
102+ assert (memcmp (buf , zero , 20 ) != 0 );
103+ }
104+
81105static void test_issue_17 (void ) {
82106 uint8_t buf1 [20 ] = {}, buf2 [sizeof (buf1 )] = {};
83107 const int ret1 = randombytes (buf1 , sizeof (buf1 ));
@@ -109,22 +133,38 @@ static void test_issue_33(void) {
109133
110134// ======== Mock OS functions to simulate uncommon behavior ========
111135
112- #if defined(__linux__ ) && defined(SYS_getrandom )
136+ #if defined(__linux__ ) && defined(__GLIBC__ ) && ((__GLIBC__ > 2 ) || (__GLIBC_MINOR__ > 24 ))
137+ int __wrap_getrandom (char * buf , size_t buflen , int flags ) {
138+ glib_getrandom_called ++ ;
139+ if (current_test == test_getrandom_glib_partial ) {
140+ // Fill only 16 bytes, the caller should retry
141+ const size_t current_buflen = buflen <= 16 ? buflen : 16 ;
142+ return __real_getrandom (buf , current_buflen , flags );
143+ } else if (current_test == test_getrandom_glib_interrupted ) {
144+ if (glib_getrandom_called < 5 ) {
145+ errno = EINTR ;
146+ return -1 ;
147+ }
148+ }
149+ return __real_getrandom (buf , buflen , flags );
150+ }
151+
152+ #elif defined(__linux__ ) && defined(SYS_getrandom )
113153int __wrap_syscall (int n , char * buf , size_t buflen , int flags ) {
114154 syscall_called ++ ;
115- if (current_test == test_getrandom_partial ) {
155+ if (current_test == test_getrandom_syscall_partial ) {
116156 // Fill only 16 bytes, the caller should retry
117157 const size_t current_buflen = buflen <= 16 ? buflen : 16 ;
118158 return __real_syscall (n , buf , current_buflen , flags );
119- } else if (current_test == test_getrandom_interrupted ) {
159+ } else if (current_test == test_getrandom_syscall_interrupted ) {
120160 if (syscall_called < 5 ) {
121161 errno = EINTR ;
122162 return -1 ;
123163 }
124164 }
125165 return __real_syscall (n , buf , buflen , flags );
126166}
127- #endif /* defined(__linux__) && defined(SYS_getrandom) */
167+ #endif /* defined(__linux__) && ( defined(SYS_getrandom) or glibc version > 2.24 ) */
128168
129169#if defined(__linux__ ) && !defined(SYS_getrandom )
130170int __wrap_ioctl (int fd , int code , int * ret ) {
@@ -148,13 +188,22 @@ int main(void) {
148188
149189 RUN_TEST (test_functional )
150190 RUN_TEST (test_empty )
151- #if defined(__linux__ ) && defined(SYS_getrandom )
152- RUN_TEST (test_getrandom_partial )
153- RUN_TEST (test_getrandom_interrupted )
191+ #if defined(__linux__ ) && defined(USE_GLIBC )
192+ RUN_TEST (test_getrandom_glib_partial )
193+ RUN_TEST (test_getrandom_glib_interrupted )
194+ SKIP_TEST (test_getrandom_syscall_partial )
195+ SKIP_TEST (test_getrandom_syscall_interrupted )
196+ #elif defined(__linux__ ) && defined(SYS_getrandom )
197+ SKIP_TEST (test_getrandom_glib_partial )
198+ SKIP_TEST (test_getrandom_glib_interrupted )
199+ RUN_TEST (test_getrandom_syscall_partial )
200+ RUN_TEST (test_getrandom_syscall_interrupted )
154201#else
155- SKIP_TEST (test_getrandom_partial )
156- SKIP_TEST (test_getrandom_interrupted )
157- #endif /* defined(__linux__) && defined(SYS_getrandom) */
202+ SKIP_TEST (test_getrandom_glib_partial )
203+ SKIP_TEST (test_getrandom_glib_interrupted )
204+ SKIP_TEST (test_getrandom_syscall_partial )
205+ SKIP_TEST (test_getrandom_syscall_interrupted )
206+ #endif /* defined(__linux__) && (defined(SYS_getrandom) or glibc version > 2.24) */
158207#if defined(__linux__ ) && !defined(SYS_getrandom )
159208 RUN_TEST (test_issue_17 )
160209 RUN_TEST (test_issue_22 )
0 commit comments