Module Name:    src
Committed By:   jdc
Date:           Mon Dec  3 19:07:27 UTC 2012

Modified Files:
        src/lib/libpthread [netbsd-6]: pthread.c

Log Message:
Apply patch (requested by riastradh in ticket #735) to fix the unchecked
assumption that sizeof(struct __pthread_st) <= pagesize, as observed in
PR 47271.


To generate a diff of this commit:
cvs rdiff -u -r1.125.4.1 -r1.125.4.2 src/lib/libpthread/pthread.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libpthread/pthread.c
diff -u src/lib/libpthread/pthread.c:1.125.4.1 src/lib/libpthread/pthread.c:1.125.4.2
--- src/lib/libpthread/pthread.c:1.125.4.1	Mon May  7 03:12:33 2012
+++ src/lib/libpthread/pthread.c	Mon Dec  3 19:07:26 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: pthread.c,v 1.125.4.1 2012/05/07 03:12:33 riz Exp $	*/
+/*	$NetBSD: pthread.c,v 1.125.4.2 2012/12/03 19:07:26 jdc Exp $	*/
 
 /*-
  * Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread.c,v 1.125.4.1 2012/05/07 03:12:33 riz Exp $");
+__RCSID("$NetBSD: pthread.c,v 1.125.4.2 2012/12/03 19:07:26 jdc Exp $");
 
 #define	__EXPOSE_STACK	1
 
@@ -1274,22 +1274,32 @@ pthread__stackid_setup(void *base, size_
 {
 	pthread_t t;
 	void *redaddr;
-	size_t pagesize;
+	size_t pagesize, bytes_needed;
 	int ret;
 
 	t = base;
 	pagesize = (size_t)sysconf(_SC_PAGESIZE);
+	bytes_needed = roundup(sizeof(*t), pagesize);
+
+	if (pagesize >= size)
+		return ENOMEM;
+	if (bytes_needed >= (size - pagesize))
+		return ENOMEM;
 
 	/*
 	 * Put a pointer to the pthread in the bottom (but
          * redzone-protected section) of the stack. 
+	 *
+	 * XXX If the stack grows up, the pthread is *not*
+	 * protected by the redzone.
 	 */
-	redaddr = STACK_SHRINK(STACK_MAX(base, size), pagesize);
-	t->pt_stack.ss_size = size - 2 * pagesize;
+	t->pt_stack.ss_size = size - bytes_needed - pagesize;
 #ifdef __MACHINE_STACK_GROWS_UP
-	t->pt_stack.ss_sp = (char *)(void *)base + pagesize;
+	redaddr = STACK_SHRINK(STACK_MAX(base, size), pagesize);
+	t->pt_stack.ss_sp = (char *)(void *)base + bytes_needed;
 #else
-	t->pt_stack.ss_sp = (char *)(void *)base + 2 * pagesize;
+	redaddr = STACK_SHRINK(STACK_MAX(base, size), bytes_needed);
+	t->pt_stack.ss_sp = (char *)(void *)base + bytes_needed + pagesize;
 #endif
 	/* Protect the next-to-bottom stack page as a red zone. */
 	ret = mprotect(redaddr, pagesize, PROT_NONE);

Reply via email to