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 );
@@ -78,6 +82,26 @@ static void test_getrandom_syscall_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,7 +133,23 @@ 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 ++ ;
115155 if (current_test == test_getrandom_syscall_partial ) {
@@ -124,7 +164,7 @@ int __wrap_syscall(int n, char *buf, size_t buflen, int flags) {
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,19 @@ int main(void) {
148188
149189 RUN_TEST (test_functional )
150190 RUN_TEST (test_empty )
151- #if defined(__linux__ ) && defined(__GLIBC__ ) && ((__GLIBC__ > 2 ) || (__GLIBC_MINOR__ > 24 ))
191+ #if defined(__linux__ ) && defined(USE_GLIBC )
192+ RUN_TEST (test_getrandom_glib_partial )
193+ RUN_TEST (test_getrandom_glib_interrupted )
152194 SKIP_TEST (test_getrandom_syscall_partial )
153195 SKIP_TEST (test_getrandom_syscall_interrupted )
154196#elif defined(__linux__ ) && defined(SYS_getrandom )
197+ SKIP_TEST (test_getrandom_glib_partial )
198+ SKIP_TEST (test_getrandom_glib_interrupted )
155199 RUN_TEST (test_getrandom_syscall_partial )
156200 RUN_TEST (test_getrandom_syscall_interrupted )
157201#else
202+ SKIP_TEST (test_getrandom_glib_partial )
203+ SKIP_TEST (test_getrandom_glib_interrupted )
158204 SKIP_TEST (test_getrandom_syscall_partial )
159205 SKIP_TEST (test_getrandom_syscall_interrupted )
160206#endif /* defined(__linux__) && (defined(SYS_getrandom) or glibc version > 2.24) */
0 commit comments