svn commit: r214413 - head/lib/libthr/thread

David Xu davidxu at FreeBSD.org
Wed Oct 27 09:59:43 UTC 2010


Author: davidxu
Date: Wed Oct 27 09:59:43 2010
New Revision: 214413
URL: http://svn.freebsd.org/changeset/base/214413

Log:
  Check small set and reject it, this is how kernel did. Always use the
  size kernel is using.

Modified:
  head/lib/libthr/thread/thr_attr.c

Modified: head/lib/libthr/thread/thr_attr.c
==============================================================================
--- head/lib/libthr/thread/thr_attr.c	Wed Oct 27 09:29:03 2010	(r214412)
+++ head/lib/libthr/thread/thr_attr.c	Wed Oct 27 09:59:43 2010	(r214413)
@@ -141,19 +141,14 @@ _pthread_attr_get_np(pthread_t pthread, 
 	struct pthread *curthread;
 	struct pthread_attr attr, *dst;
 	int	ret;
-	size_t	cpusetsize;
+	size_t	kern_size;
 
 	if (pthread == NULL || dstattr == NULL || (dst = *dstattr) == NULL)
 		return (EINVAL);
-	cpusetsize = _get_kern_cpuset_size();
-	if (dst->cpusetsize < cpusetsize) {
-		char *newset = realloc(dst->cpuset, cpusetsize);
-		if (newset == NULL)
-			return (errno);
-		memset(newset + dst->cpusetsize, 0, cpusetsize -
-			dst->cpusetsize);
-		dst->cpuset = (cpuset_t *)newset;
-		dst->cpusetsize = cpusetsize;
+	kern_size = _get_kern_cpuset_size();
+	if (dst->cpuset == NULL) {
+		dst->cpuset = calloc(1, kern_size);
+		dst->cpusetsize = kern_size;
 	}
 	curthread = _get_curthread();
 	if ((ret = _thr_find_thread(curthread, pthread, /*include dead*/0)) != 0)
@@ -606,27 +601,25 @@ _pthread_attr_setaffinity_np(pthread_att
 			}
 			return (0);
 		}
-			
-		if (cpusetsize > attr->cpusetsize) {
-			size_t kern_size = _get_kern_cpuset_size();
-			if (cpusetsize > kern_size) {
-				size_t i;
-				for (i = kern_size; i < cpusetsize; ++i) {
-					if (((char *)cpusetp)[i])
-						return (EINVAL);
-				}
+		size_t kern_size = _get_kern_cpuset_size();
+		/* Kernel rejects small set, we check it here too. */ 
+		if (cpusetsize < kern_size)
+			return (ERANGE);
+		if (cpusetsize > kern_size) {
+			/* Kernel checks invalid bits, we check it here too. */
+			size_t i;
+			for (i = kern_size; i < cpusetsize; ++i) {
+				if (((char *)cpusetp)[i])
+					return (EINVAL);
 			}
-			void *newset = realloc(attr->cpuset, cpusetsize);
-       			if (newset == NULL)
-		            return (ENOMEM);
-			attr->cpuset = newset;
-			attr->cpusetsize = cpusetsize;
-		} else {
-			memset(((char *)attr->cpuset) + cpusetsize, 0,
-				attr->cpusetsize - cpusetsize);
-			attr->cpusetsize = cpusetsize;
 		}
-		memcpy(attr->cpuset, cpusetp, cpusetsize);
+		if (attr->cpuset == NULL) {
+			attr->cpuset = calloc(1, kern_size);
+			if (attr->cpuset == NULL)
+				return (errno);
+			attr->cpusetsize = kern_size;
+		}
+		memcpy(attr->cpuset, cpusetp, kern_size);
 		ret = 0;
 	}
 	return (ret);
@@ -642,16 +635,18 @@ _pthread_attr_getaffinity_np(const pthre
 
 	if (pattr == NULL || (attr = (*pattr)) == NULL)
 		ret = EINVAL;
-	else if (attr->cpuset != NULL) {
-		memcpy(cpusetp, attr->cpuset, MIN(cpusetsize, attr->cpusetsize));
-		if (cpusetsize > attr->cpusetsize)
-			memset(((char *)cpusetp) + attr->cpusetsize, 0, 
-				cpusetsize - attr->cpusetsize);
-	} else {
+	else {
+		/* Kernel rejects small set, we check it here too. */ 
 		size_t kern_size = _get_kern_cpuset_size();
-		memset(cpusetp, -1, MIN(cpusetsize, kern_size));
+		if (cpusetsize < kern_size)
+			return (ERANGE);
+		if (attr->cpuset != NULL)
+			memcpy(cpusetp, attr->cpuset, MIN(cpusetsize,
+			   attr->cpusetsize));
+		else
+			memset(cpusetp, -1, kern_size);
 		if (cpusetsize > kern_size)
-			memset(((char *)cpusetp) + kern_size, 0,
+			memset(((char *)cpusetp) + kern_size, 0, 
 				cpusetsize - kern_size);
 	}
 	return (ret);


More information about the svn-src-all mailing list