* m4/random.m4 (gl_FUNC_RANDOM): Override on CheriBSD.
* lib/random.c: Include glthread/lock.h.
(__libc_lock_define_initialized, __libc_lock_lock, __libc_lock_unlock):
Define to do real locking.
* modules/random (Depends-on): Add lock.
* doc/posix-functions/random.texi: Mention the multithread-safety
problem.
+2023-11-09 Bruno Haible <bruno@clisp.org>
+
+ random: Fix multithread-safety bug on CheriBSD.
+ * m4/random.m4 (gl_FUNC_RANDOM): Override on CheriBSD.
+ * lib/random.c: Include glthread/lock.h.
+ (__libc_lock_define_initialized, __libc_lock_lock, __libc_lock_unlock):
+ Define to do real locking.
+ * modules/random (Depends-on): Add lock.
+ * doc/posix-functions/random.texi: Mention the multithread-safety
+ problem.
+
2023-11-09 Bruno Haible <bruno@clisp.org>
host-cpu-c-abi: Port to CHERI.
This function is only defined as an inline function on some platforms:
Android 4.4.
@item
-
+This function crashes when used in multithreaded programs on some platforms:
+CheriBSD.
@end itemize
Portability problems not fixed by Gnulib:
#ifdef _LIBC
# include <libc-lock.h>
#else
-/* Allow memory races; that's random enough. */
-# define __libc_lock_define_initialized(class, name)
-# define __libc_lock_lock(name) ((void) 0)
-# define __libc_lock_unlock(name) ((void) 0)
+# include "glthread/lock.h"
+# define __libc_lock_define_initialized gl_lock_define_initialized
+# define __libc_lock_lock gl_lock_lock
+# define __libc_lock_unlock gl_lock_unlock
#endif
/* An improved random number generation package. In addition to the standard
-# random.m4 serial 6
+# random.m4 serial 7
dnl Copyright (C) 2012-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
AC_DEFUN([gl_FUNC_RANDOM],
[
AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+ AC_REQUIRE([AC_CANONICAL_HOST])
dnl We can't use AC_CHECK_FUNC here, because random() is defined as a
dnl static inline function when compiling for Android 4.4 or older.
future*) REPLACE_SETSTATE=1 ;;
esac
fi
- if test $ac_cv_func_initstate = no || test $ac_cv_func_setstate = no; then
+ dnl On CheriBSD, random() lacks locking, leading to an out-of-bounds read
+ dnl inside random_r.
+ if test $ac_cv_func_initstate = no || test $ac_cv_func_setstate = no \
+ || case "$host" in aarch64c-*-freebsd*) true;; *) false;; esac; then
dnl In order to define initstate or setstate, we need to define all the
dnl functions at once.
REPLACE_RANDOM=1
m4/random.m4
Depends-on:
-libc-config [test $HAVE_RANDOM = 0 || test $REPLACE_RANDOM = 1 || test $REPLACE_INITSTATE = 1 || test $REPLACE_SETSTATE = 1]
stdlib
+libc-config [test $HAVE_RANDOM = 0 || test $REPLACE_RANDOM = 1 || test $REPLACE_INITSTATE = 1 || test $REPLACE_SETSTATE = 1]
+lock [test $HAVE_RANDOM = 0 || test $REPLACE_RANDOM = 1 || test $REPLACE_INITSTATE = 1 || test $REPLACE_SETSTATE = 1]
stdint [test $HAVE_RANDOM = 0 || test $REPLACE_RANDOM = 1 || test $REPLACE_INITSTATE = 1 || test $REPLACE_SETSTATE = 1]
random_r [test $HAVE_RANDOM = 0 || test $REPLACE_RANDOM = 1 || test $REPLACE_INITSTATE = 1 || test $REPLACE_SETSTATE = 1]