Skip to content

Commit

Permalink
Switch random() and rand() to arc4random_uniform() if available
Browse files Browse the repository at this point in the history
Keep srandom(seed) also if we use arc4random*()

Update doc tcl-commands.rst

Add dietlibc hints to doc COMPILE-GUIDE
  • Loading branch information
michaelortmann committed Jan 31, 2025
1 parent 028e756 commit 4a13def
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 33 deletions.
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ AX_TYPE_SOCKLEN_T
AX_CREATE_STDINT_H([eggint.h])

# Checks for functions and their arguments.
AC_CHECK_FUNCS([clock_gettime dprintf explicit_bzero memset_explicit explicit_memset getrandom inet_aton memset_s snprintf strlcpy vsnprintf])
AC_CHECK_FUNCS([arc4random_uniform clock_gettime dprintf explicit_bzero memset_explicit explicit_memset getrandom inet_aton memset_s snprintf strlcpy vsnprintf])
AC_FUNC_SELECT_ARGTYPES
EGG_FUNC_B64_NTOP
AC_FUNC_MMAP
Expand Down
14 changes: 13 additions & 1 deletion doc/COMPILE-GUIDE
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Eggdrop Compile Guide and FAQ
Last revised: May 14, 2023
Last revised: Jan 31, 2025
_____________________________________________________________________

Eggdrop Compile Guide and FAQ
Expand Down Expand Up @@ -48,6 +48,9 @@ Last revised: May 14, 2023
13. I get '/usr/bin/ld: cannot find -lpthread' (OpenWrt)
14. I get 'configure: error: C compiler cannot create executables
(Alpine Linux)
15. I get 'checking build system type... Invalid configuration
'x86_64-pc-linux-dietlibc': OS 'dietlibc' not recognized (dietlibc)
16. I get 'error: implicit declaration of function ‘srandom’' (dietlibc)


Compile Guide
Expand Down Expand Up @@ -580,6 +583,15 @@ Last revised: May 14, 2023

Install the musl c library implementation used by Alpine:
apk add musl-dev

15. I get 'checking build system type... Invalid configuration
'x86_64-pc-linux-dietlibc': OS 'dietlibc' not recognized (dietlibc)

./configure --build=x86_64-pc-linux-gnu

16 I get 'error: implicit declaration of function ‘srandom’' (dietlibc)

Add -D_BSD_SOURCE
_____________________________________________________________________

Copyright (C) 1997 Robey Pointer
Expand Down
2 changes: 1 addition & 1 deletion doc/sphinx_source/using/tcl-commands.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2443,7 +2443,7 @@ myip
rand <limit>
^^^^^^^^^^^^

Returns: a random integer between 0 and limit-1. Limit must be greater than 0 and equal to or less than RAND_MAX, which is generally 2147483647. The underlying pseudo-random number generator is not cryptographically secure.
Returns: a random integer between 0 and limit-1. Limit must be greater than 0 and equal to or less than RAND_MAX, which is generally 2147483647. If arc4random_uniform() is available and is a cryptographically secure pseudorandom number generator (CSPRNG) then this function will also be and return uniformly distributed (avoiding modulo bias) values. Otherwise not. In other words, this function rolls the dice as good as it can and probably better than any AI.

Module: core

Expand Down
28 changes: 15 additions & 13 deletions src/eggdrop.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,19 @@
#include <time.h> /* POSIX 2001 */
#include <sys/resource.h> /* getrusage() setrlimit() after time.h because of BSD */

/* On systems with random(), RANDOM_MAX may or may not be defined.
*
* If RANDOM_MAX isn't defined, we use 0x7FFFFFFF (2^31-1), or 2147483647
* since this follows the 4.3BSD and POSIX.1-2001 standards. This of course
* assumes random() uses a 32 bit long int type per the standards.
*/
#ifndef RANDOM_MAX
# define RANDOM_MAX 0x7FFFFFFF /* random() -- 2^31-1 */
#endif

#ifdef HAVE_ARC4RANDOM_UNIFORM
#define randint arc4random_uniform
#else
/* Yikes...who would have thought finding a usable random() would be so much
* trouble?
* Note: random() is *not* thread safe.
Expand All @@ -199,24 +212,13 @@
# undef HAVE_SRANDOM
#endif

/* On systems with random(), RANDOM_MAX may or may not be defined.
*
* If RANDOM_MAX isn't defined, we use 0x7FFFFFFF (2^31-1), or 2147483647
* since this follows the 4.3BSD and POSIX.1-2001 standards. This of course
* assumes random() uses a 32 bit long int type per the standards.
*/
#ifndef RANDOM_MAX
# define RANDOM_MAX 0x7FFFFFFF /* random() -- 2^31-1 */
#endif


/* Use high-order bits for getting the random integer. With a modern
* random() implementation, modulo would probably be sufficient, but on
* systems lacking random(), it may just be a macro for an older rand()
* function.
*/
#define randint(n) (unsigned long) (random() / (RANDOM_MAX + 1.0) * n)

#define randint(n) (uint32_t) (random() / (RANDOM_MAX + 1.0) * n)
#endif /* HAVE_ARC4RANDOM_UNIFORM */

#ifdef TLS
# include <openssl/ssl.h>
Expand Down
9 changes: 9 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,11 @@
#include "modules.h"
#include "bg.h"

#ifndef HAVE_ARC4RANDOM_UNIFORM
#ifdef HAVE_GETRANDOM
# include <sys/random.h>
#endif
#endif /* HAVE_ARC4RANDOM_UNIFORM */

#ifndef _POSIX_SOURCE
# define _POSIX_SOURCE 1 /* Solaris needs this */
Expand Down Expand Up @@ -916,8 +918,13 @@ static void mainloop(int toplevel)
}
}

/* We keep srandom(seed) also if we use arc4random*() because 3rd party modules
* could use random() and rely on eggdrop core seeding it */
static void init_random(void) {
unsigned int seed;
#ifdef HAVE_ARC4RANDOM_UNIFORM
seed = arc4random();
#else
#ifdef HAVE_GETRANDOM
if (getrandom(&seed, sizeof seed, 0) != (sizeof seed)) {
if (errno != ENOSYS) {
Expand All @@ -940,9 +947,11 @@ static void init_random(void) {
}
}
#endif
#endif /* HAVE_ARC4RANDOM_UNIFORM */
srandom(seed);
}


int main(int arg_c, char **arg_v)
{
int i, j, xx;
Expand Down
2 changes: 1 addition & 1 deletion src/mod/blowfish.mod/blowfish.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ static char *encrypt_string_cbc(char *key, char *str)
slen = strlen(str) + 8;
s = nmalloc(slen + 9);
for (i = 0; i < 8; ++i) {
s[i] = (char) (random() % 256);
s[i] = (char) randint(256);
}
strcpy(s + 8, str);
if ((!key) || (!key[0]))
Expand Down
12 changes: 3 additions & 9 deletions src/mod/uptime.mod/uptime.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ static int minutes = 0;
static int seconds = 0;
static int next_seconds = 0;
static int next_minutes = 0;
static int update_interval = 720; /* rand(0..12) hours: ~6 hour average. */
static int update_interval = 12 * 60 * 60; /* randint(0..12) hours: ~6 hour average. */
static time_t next_update = 0;
static int uptimesock;
static int uptimecount;
Expand Down Expand Up @@ -161,10 +161,7 @@ static int init_uptime(void)
}
fcntl(uptimesock, F_SETFL, O_NONBLOCK | fcntl(uptimesock, F_GETFL));

next_minutes = rand() % update_interval; /* Initial update delay */
next_seconds = rand() % 59;
next_update = (time_t) ((time(NULL) / 60 * 60) + (next_minutes * 60) +
next_seconds);
next_update = (time_t) ((time(NULL) / 60 * 60) + randint(update_interval));

return 0;
}
Expand Down Expand Up @@ -251,10 +248,7 @@ void check_secondly()

minutes = 0; /* Reset for the next countdown. */
seconds = 0;
next_minutes = rand() % update_interval;
next_seconds = rand() % 59;
next_update = (time_t) ((time(NULL) / 60 * 60) + (next_minutes * 60) +
next_seconds);
next_update = (time_t) ((time(NULL) / 60 * 60) + randint(update_interval));

/* Go back to checking every minute. */
add_hook(HOOK_MINUTELY, (Function) check_minutely);
Expand Down
8 changes: 1 addition & 7 deletions src/tclmisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -455,8 +455,6 @@ static int tcl_myip STDVAR
static int tcl_rand STDVAR
{
long i;
unsigned long x;
char s[11];

BADARGS(2, 2, " limit");

Expand All @@ -471,11 +469,7 @@ static int tcl_rand STDVAR
return TCL_ERROR;
}

x = randint(i);

egg_snprintf(s, sizeof s, "%lu", x);

Tcl_AppendResult(irp, s, NULL);
Tcl_SetObjResult(interp, Tcl_NewIntObj(randint(i)));
return TCL_OK;
}

Expand Down

0 comments on commit 4a13def

Please sign in to comment.