Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20111216214648.GA23310@openwall.com>
Date: Sat, 17 Dec 2011 01:46:48 +0400
From: Solar Designer <solar@...nwall.com>
To: john-dev@...ts.openwall.com
Subject: Re: 1.7.9's --external + OpenMP fails on Cygwin

On Sat, Dec 17, 2011 at 12:27:51AM +0400, Solar Designer wrote:
> Also, sem_wait() is called on lots of invalid stuff (ASCII strings and
> such) at various times, which surprisingly appears to be harmless - I
> let OllyDbg deliver the exception (on bad pointer read) to the program
> and it just continues running fine (tests pass, etc.)

Apparently, this is a result of:

src/winsup/cygwin/thread.cc:

int
pthread_mutex::init (pthread_mutex_t *mutex,
                     const pthread_mutexattr_t *attr,
                     const pthread_mutex_t initializer)
{
  if (attr && !pthread_mutexattr::is_good_object (attr))
    return EINVAL;

  mutex_initialization_lock.lock ();
  if (initializer == NULL || pthread_mutex::is_initializer (mutex))

Notice how the not yet initialized mutex is checked with
"pthread_mutex::is_initializer (mutex)".  And yes, it catches faults:

inline bool
pthread_mutex::is_initializer (pthread_mutex_t const *mutex)
{
  if (verifyable_object_isvalid (mutex, PTHREAD_MUTEX_MAGIC,
                                 PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP,
                                 PTHREAD_NORMAL_MUTEX_INITIALIZER_NP,
                                 PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP) != VALID_STATIC_OBJECT)
    return false;
  return true;
}

static inline verifyable_object_state
verifyable_object_isvalid (void const *objectptr, thread_magic_t magic, void *static_ptr1,
                           void *static_ptr2, void *static_ptr3)
{
  myfault efault;
  if (efault.faulted (objectptr))
    return INVALID_OBJECT;

  verifyable_object **object = (verifyable_object **) objectptr;

  if ((static_ptr1 && *object == static_ptr1) ||
      (static_ptr2 && *object == static_ptr2) ||
      (static_ptr3 && *object == static_ptr3))
    return VALID_STATIC_OBJECT;
  if ((*object)->magic != magic)
    return INVALID_OBJECT;
  return VALID_OBJECT;
}

This doesn't look reliable to me - what if the uninitialized memory just
happens to contain a pointer to one of the magic values?  Whether this
is what actually happens in the problematic John runs or not I don't know.
Maybe the uninitialized memory happens to contain a previously used mutex.

Alexander

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.