delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2006/03/16/12:03:19

X-Spam-Check-By: sourceware.org
From: Jonathan Lennox <lennox AT cs DOT columbia DOT edu>
MIME-Version: 1.0
Message-ID: <17433.39495.950903.287320@metro-north.cs.columbia.edu>
Date: Thu, 16 Mar 2006 12:03:03 -0500
To: cygwin AT cygwin DOT com
Subject: pthread_create leaves valid mutex pointers on the stack
Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com

--BbD1p5SQYv
Content-Type: text/plain; charset=us-ascii
Content-Description: message body text
Content-Transfer-Encoding: 7bit

Cygwin's pthread_create function leaves a pointer to the pthread object's
mutex member on the stack.

If you subsequently call pthread_mutex_init on mutex in an automatic
variable, it's possible for it to reuse this stack slot.  In this case,
pthread_mutex_init observes that the mutex object is a pointer to a valid
mutex object, and fails with EBUSY.

This program illustrates the problem, with cygwin 1.5.19-4 and gcc 3.4.4-1:


--BbD1p5SQYv
Content-Type: text/plain
Content-Disposition: inline;
	filename="PthreadStackMutex.c"
Content-Transfer-Encoding: 7bit

#include <pthread.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>

/* expr is an expression returning 0 on success, or an errno value
 * on failure. */
#define Pth(expr) \
  do { \
	int ret; \
	if ((ret = (expr)) != 0) { \
	  errno = ret; \
	  perror(#expr); \
	  exit(1); \
	} \
  } while (0)


void* thread_function(void* arg)
{
  sleep(1);
  return NULL;
}

#define STACK_ADJUST 74

void stack_function(void)
{
  long adjust[STACK_ADJUST] __attribute__((__unused__));
  pthread_mutex_t mutex[4];

  Pth (pthread_mutex_init(&mutex[0], NULL));
  Pth (pthread_mutex_lock(&mutex[0]));
  Pth (pthread_mutex_unlock(&mutex[0])); 
  Pth (pthread_mutex_destroy(&mutex[0]));
}


int main()
{
  pthread_t thread;
  void *thread_ret;

  Pth (pthread_create(&thread, NULL, &thread_function, NULL));

  stack_function();
  
  Pth (pthread_join(thread, &thread_ret));

  return 0;
}

--BbD1p5SQYv
Content-Type: text/plain; charset=us-ascii
Content-Description: message body and .signature
Content-Transfer-Encoding: 7bit



In general, the idea of verifying objects on their init functions seems
dubious to me -- how can you tell initialized objects from random stack or
heap garbage?  In particular, it seems like this is an area where an
attacker could potentially cause odd effects by causing the pthread objects'
magic numbers to be written to the stack or heap in memory that is
subsequently re-used.

-- 
Jonathan Lennox
lennox at cs dot columbia dot edu


--BbD1p5SQYv
Content-Type: text/plain; charset=us-ascii

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/
--BbD1p5SQYv--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019