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);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to