1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-18 10:35:55 +00:00

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

size kernel is using.
This commit is contained in:
David Xu 2010-10-27 09:59:43 +00:00
parent 4a5478709b
commit 67753965a8
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=214413

View File

@ -141,19 +141,14 @@ _pthread_attr_get_np(pthread_t pthread, pthread_attr_t *dstattr)
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_attr_t *pattr, size_t cpusetsize,
}
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 pthread_attr_t *pattr, size_t cpusetsize,
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);