Index: lib/libc/sys/cpuset_getaffinity.2 =================================================================== --- lib/libc/sys/cpuset_getaffinity.2 +++ lib/libc/sys/cpuset_getaffinity.2 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 23, 2017 +.Dd April 20, 2022 .Dt CPUSET_GETAFFINITY 2 .Os .Sh NAME @@ -71,11 +71,9 @@ are composed using the .Dv CPU_SET macros. -The kernel tolerates large sets as long as all CPUs specified -in the set exist. -Sets smaller than the kernel uses generate an error on calls to -.Fn cpuset_getaffinity -even if the result set would fit within the user supplied set. +Sets smaller than the kernel can use to fit all active CPUs generate an +error on calls to +.Fn cpuset_getaffinity . Calls to .Fn cpuset_setaffinity tolerate small sets with no restrictions. @@ -144,7 +142,7 @@ .It Bq Er ERANGE The .Fa cpusetsize -was either preposterously large or smaller than the kernel set size. +was smaller than needed to fit all active CPUs. .It Bq Er EPERM The calling process did not have the credentials required to complete the operation. Index: share/man/man3/pthread_attr_affinity_np.3 =================================================================== --- share/man/man3/pthread_attr_affinity_np.3 +++ share/man/man3/pthread_attr_affinity_np.3 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 12, 2021 +.Dd April 20, 2022 .Dt PTHREAD_ATTR_AFFINITY_NP 3 .Os .Sh NAME @@ -51,11 +51,9 @@ are composed using the .Dv CPU_SET macros. -The kernel tolerates large sets as long as all CPUs specified -in the set exist. -Sets smaller than the kernel uses generate an error on calls to -.Fn pthread_attr_getaffinity_np -even if the result set would fit within the user supplied set. +Sets smaller than the kernel can use to fit all active CPUs generate an +error on calls to +.Fn pthread_attr_getaffinity_np . Calls to .Fn pthread_attr_setaffinity_np tolerate small sets with no restrictions. Index: sys/kern/kern_cpuset.c =================================================================== --- sys/kern/kern_cpuset.c +++ sys/kern/kern_cpuset.c @@ -1896,13 +1896,13 @@ int error; size_t size; - if (cpusetsize < sizeof(cpuset_t) || cpusetsize > CPU_MAXSIZE / NBBY) + if (cpusetsize * NBBY < smp_cpus) return (ERANGE); error = cpuset_check_capabilities(td, level, which, id); if (error != 0) return (error); - size = cpusetsize; - mask = malloc(size, M_TEMP, M_WAITOK | M_ZERO); + size = min(cpusetsize, sizeof(cpuset_t)); + mask = malloc(sizeof(cpuset_t), M_TEMP, M_WAITOK | M_ZERO); error = cpuset_which(which, id, &p, &ttd, &set); if (error) goto out; @@ -2006,32 +2006,16 @@ struct proc *p; cpuset_t *mask; int error; + size_t size; - if (cpusetsize < sizeof(cpuset_t) || cpusetsize > CPU_MAXSIZE / NBBY) - return (ERANGE); error = cpuset_check_capabilities(td, level, which, id); if (error != 0) return (error); - mask = malloc(cpusetsize, M_TEMP, M_WAITOK | M_ZERO); - error = copyin(maskp, mask, cpusetsize); + size = min(cpusetsize, sizeof(cpuset_t)); + mask = malloc(sizeof(cpuset_t), M_TEMP, M_WAITOK | M_ZERO); + error = copyin(maskp, mask, size); if (error) goto out; - /* - * Verify that no high bits are set. - */ - if (cpusetsize > sizeof(cpuset_t)) { - char *end; - char *cp; - - end = cp = (char *)&mask->__bits; - end += cpusetsize; - cp += sizeof(cpuset_t); - while (cp != end) - if (*cp++ != 0) { - error = EINVAL; - goto out; - } - } if (CPU_EMPTY(mask)) { error = EDEADLK; goto out;