Hi.

Any news on that?

On Friday, September 21, 2012, Alexey Suslikov wrote:

> On Fri, Sep 21, 2012 at 10:36 AM, Alexey Suslikov
> <alexey.susli...@gmail.com <javascript:;>> wrote:
> > On Wed, Sep 19, 2012 at 10:24 PM, Ted Unangst 
> > <t...@tedunangst.com<javascript:;>>
> wrote:
> >> On Wed, Sep 19, 2012 at 18:50, Alexey Suslikov wrote:
> >>> On Wednesday, September 19, 2012, Theo de Raadt wrote:
> >>>
> >>>> > arc4random() is also thread-safe (it has interal locking) and very
> >>>> > desirable for other reasons. But no way to save state.
> >>>>
> >>>> The last part of this is intentional.  Saving the state of pseudo
> >>>> random number generators is a stupid concept from the 80's.
> >>>>
> >>>
> >>> I see many rng functions behaving very differently. Is it a good idea
> >>> to create a common locking layer on top of need-to-be-safe rng
> >>> functions? Or we should deal only with original problem (and only
> >>> port random.c code from netbsd)?
> >>
> >> just slap a mutex around it.
> >
> > With the diff below Kannel no longer crashes. Only protecting random()
> > for now.
> >
> > Make random() thread-safe by surrounding real call with a mutex locking.
> > Found by and diff from Roman Kravchuk. Mainly from NetBSD.
>
> Sorry. Here is correct diff.
>
> We kinda unsure about the approach. For now, we follow arc4random pattern.
> Should we use generic _thread_mutex_lock/_thread_mutex_unlock instead?
>
> Index: lib/libc/include/thread_private.h
> ===================================================================
> RCS file: /cvs/src/lib/libc/include/thread_private.h,v
> retrieving revision 1.25
> diff -u -p -r1.25 thread_private.h
> --- lib/libc/include/thread_private.h   16 Oct 2011 06:29:56 -0000
>  1.25
> +++ lib/libc/include/thread_private.h   21 Sep 2012 07:59:34 -0000
> @@ -172,4 +172,16 @@ void       _thread_arc4_unlock(void);
>                                                 _thread_arc4_unlock();\
>                                 } while (0)
>
> +void   _thread_random_lock(void);
> +void   _thread_random_unlock(void);
> +
> +#define _RANDOM_LOCK()         do {                                    \
> +                                       if (__isthreaded)               \
> +                                               _thread_random_lock();  \
> +                               } while (0)
> +#define _RANDOM_UNLOCK()               do {                            \
> +                                       if (__isthreaded)               \
> +                                               _thread_random_unlock();\
> +                               } while (0)
> +
>  #endif /* _THREAD_PRIVATE_H_ */
> Index: lib/libc/stdlib/random.c
> ===================================================================
> RCS file: /cvs/src/lib/libc/stdlib/random.c,v
> retrieving revision 1.17
> diff -u -p -r1.17 random.c
> --- lib/libc/stdlib/random.c    1 Jun 2012 01:01:57 -0000       1.17
> +++ lib/libc/stdlib/random.c    21 Sep 2012 07:59:35 -0000
> @@ -35,6 +35,7 @@
>  #include <stdio.h>
>  #include <stdlib.h>
>  #include <unistd.h>
> +#include "thread_private.h"
>
>  /*
>   * random.c:
> @@ -376,21 +377,38 @@ setstate(char *arg_state)
>   *
>   * Returns a 31-bit random number.
>   */
> -long
> -random(void)
> +static long
> +random_unlocked(void)
>  {
>         int32_t i;
> +       int32_t *f, *r;
>
>         if (rand_type == TYPE_0)
>                 i = state[0] = (state[0] * 1103515245 + 12345) &
> 0x7fffffff;
>         else {
> -               *fptr += *rptr;
> -               i = (*fptr >> 1) & 0x7fffffff;  /* chucking least random
> bit */
> -               if (++fptr >= end_ptr) {
> -                       fptr = state;
> -                       ++rptr;
> -               } else if (++rptr >= end_ptr)
> -                       rptr = state;
> +               /*
> +                * Use local variables rather than static variables for
> speed.
> +                */
> +               f = fptr; r = rptr;
> +               *f += *r;
> +               i = (*f >> 1) & 0x7fffffff;     /* chucking least random
> bit */
> +               if (++f >= end_ptr) {
> +                       f = state;
> +                       ++r;
> +               } else if (++r >= end_ptr)
> +                       r = state;
> +               fptr = f; rptr = r;
>         }
>         return((long)i);
> +}
> +
> +long
> +random(void)
> +{
> +       long r;
> +
> +       _RANDOM_LOCK();
> +       r = random_unlocked();
> +       _RANDOM_UNLOCK();
> +       return (r);
>  }
> Index: lib/libc/thread/unithread_malloc_lock.c
> ===================================================================
> RCS file: /cvs/src/lib/libc/thread/unithread_malloc_lock.c,v
> retrieving revision 1.8
> diff -u -p -r1.8 unithread_malloc_lock.c
> --- lib/libc/thread/unithread_malloc_lock.c     13 Jun 2008 21:18:43 -0000
>      1.8
> +++ lib/libc/thread/unithread_malloc_lock.c     21 Sep 2012 07:59:35 -0000
> @@ -21,6 +21,12 @@ WEAK_PROTOTYPE(_thread_arc4_unlock);
>  WEAK_ALIAS(_thread_arc4_lock);
>  WEAK_ALIAS(_thread_arc4_unlock);
>
> +WEAK_PROTOTYPE(_thread_random_lock);
> +WEAK_PROTOTYPE(_thread_random_unlock);
> +
> +WEAK_ALIAS(_thread_random_lock);
> +WEAK_ALIAS(_thread_random_unlock);
> +
>  void
>  WEAK_NAME(_thread_malloc_lock)(void)
>  {
> @@ -53,6 +59,18 @@ WEAK_NAME(_thread_arc4_lock)(void)
>
>  void
>  WEAK_NAME(_thread_arc4_unlock)(void)
> +{
> +       return;
> +}
> +
> +void
> +WEAK_NAME(_thread_random_lock)(void)
> +{
> +       return;
> +}
> +
> +void
> +WEAK_NAME(_thread_random_unlock)(void)
>  {
>         return;
>  }
> Index: lib/librthread/rthread.c
> ===================================================================
> RCS file: /cvs/src/lib/librthread/rthread.c,v
> retrieving revision 1.66
> diff -u -p -r1.66 rthread.c
> --- lib/librthread/rthread.c    22 Aug 2012 23:43:32 -0000      1.66
> +++ lib/librthread/rthread.c    21 Sep 2012 07:59:36 -0000
> @@ -674,6 +674,8 @@ static void *__libc_overrides[] __used =
>         &__errno,
>         &_thread_arc4_lock,
>         &_thread_arc4_unlock,
> +       &_thread_random_lock,
> +       &_thread_random_unlock,
>         &_thread_atexit_lock,
>         &_thread_atexit_unlock,
>         &_thread_malloc_lock,
> Index: lib/librthread/rthread_fork.c
> ===================================================================
> RCS file: /cvs/src/lib/librthread/rthread_fork.c,v
> retrieving revision 1.6
> diff -u -p -r1.6 rthread_fork.c
> --- lib/librthread/rthread_fork.c       22 Aug 2012 23:43:32 -0000      1.6
> +++ lib/librthread/rthread_fork.c       21 Sep 2012 07:59:36 -0000
> @@ -91,6 +91,7 @@ _dofork(int is_vfork)
>         _thread_atexit_lock();
>         _thread_malloc_lock();
>         _thread_arc4_lock();
> +       _thread_random_lock();
>
>  #if defined(__ELF__)
>         if (_DYNAMIC)
> @@ -107,6 +108,7 @@ _dofork(int is_vfork)
>         _thread_arc4_unlock();
>         _thread_malloc_unlock();
>         _thread_atexit_unlock();
> +       _thread_random_unlock();
>
>  #if defined(__ELF__)
>         if (_DYNAMIC)
> Index: lib/librthread/rthread_libc.c
> ===================================================================
> RCS file: /cvs/src/lib/librthread/rthread_libc.c,v
> retrieving revision 1.10
> diff -u -p -r1.10 rthread_libc.c
> --- lib/librthread/rthread_libc.c       17 Apr 2012 15:10:11 -0000
>  1.10
> +++ lib/librthread/rthread_libc.c       21 Sep 2012 07:59:36 -0000
> @@ -200,3 +200,19 @@ _thread_arc4_unlock(void)
>         _spinunlock(&arc4_lock);
>  }
>
> +/*
> + * random lock
> + */
> +static _spinlock_lock_t random_lock = _SPINLOCK_UNLOCKED;
> +
> +void
> +_thread_random_lock(void)
> +{
> +       _spinlock(&random_lock);
> +}
> +
> +void
> +_thread_random_unlock(void)
> +{
> +       _spinunlock(&random_lock);
> +}

Reply via email to