Page MenuHomeFreeBSD

D34849.id105532.diff
No OneTemporary

D34849.id105532.diff

Index: lib/libc/gen/sched_getaffinity.c
===================================================================
--- lib/libc/gen/sched_getaffinity.c
+++ lib/libc/gen/sched_getaffinity.c
@@ -33,24 +33,15 @@
int
sched_getaffinity(pid_t pid, size_t cpusetsz, cpuset_t *cpuset)
{
- /*
- * Be more Linux-compatible:
- * - return EINVAL in passed size is less than size of cpuset_t
- * in advance, instead of ERANGE from the syscall
- * - if passed size is larger than the size of cpuset_t, be
- * permissive by claming it back to sizeof(cpuset_t) and
- * zeroing the rest.
- */
- if (cpusetsz < sizeof(cpuset_t)) {
+ int error;
+
+ error = cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
+ pid == 0 ? -1 : pid, cpusetsz, cpuset);
+ if (error == -1 && errno == ERANGE)
errno = EINVAL;
- return (-1);
- }
- if (cpusetsz > sizeof(cpuset_t)) {
- memset((char *)cpuset + sizeof(cpuset_t), 0,
- cpusetsz - sizeof(cpuset_t));
- cpusetsz = sizeof(cpuset_t);
- }
+ if (error == 0)
+ return (cpusetsz < sizeof(cpuset_t) ? cpusetsz :
+ sizeof(cpuset_t));
- return (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
- pid == 0 ? -1 : pid, cpusetsz, cpuset));
+ return (error);
}
Index: lib/libc/gen/sched_setaffinity.c
===================================================================
--- lib/libc/gen/sched_setaffinity.c
+++ lib/libc/gen/sched_setaffinity.c
@@ -33,18 +33,10 @@
int
sched_setaffinity(pid_t pid, size_t cpusetsz, const cpuset_t *cpuset)
{
- cpuset_t c;
int error;
- if (cpusetsz > sizeof(cpuset_t)) {
- errno = EINVAL;
- return (-1);
- } else {
- memset(&c, 0, sizeof(c));
- memcpy(&c, cpuset, cpusetsz);
- }
error = cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
- pid == 0 ? -1 : pid, sizeof(cpuset_t), &c);
+ pid == 0 ? -1 : pid, cpusetsz, cpuset);
if (error == -1 && errno == EDEADLK)
errno = EINVAL;
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 27, 2022
.Dt CPUSET_GETAFFINITY 2
.Os
.Sh NAME
@@ -71,14 +71,19 @@
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
+If the user-supplied mask is not large enough to fit all of the matching CPUs,
.Fn cpuset_getaffinity
-even if the result set would fit within the user supplied set.
+fails with
+.Er ERANGE .
Calls to
.Fn cpuset_setaffinity
-tolerate small sets with no restrictions.
+tolerate masks of any size with no restrictions.
+The kernel uses a meaningful part of the mask, where the upper bound is
+the maximum CPU id present in the system.
+If bits for non-existing CPUs are set, calls to
+.Fn cpuset_setaffinity
+fails with
+.Er EINVAL .
.Pp
The supplied mask should have a size of
.Fa setsize
@@ -144,7 +149,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 of the matching 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 27, 2022
.Dt PTHREAD_ATTR_AFFINITY_NP 3
.Os
.Sh NAME
@@ -51,14 +51,19 @@
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.
+If the user-supplied mask is not large enough to fit all of the matching CPUs,
+.Fn cpuset_getaffinity
+fails with
+.Er ERANGE .
Calls to
-.Fn pthread_attr_setaffinity_np
-tolerate small sets with no restrictions.
+.Fn cpuset_setaffinity
+tolerate masks of any size with no restrictions.
+The kernel uses a meaningful part of the mask, where the upper bound is
+the maximum CPU id present in the system.
+If bits for non-existing CPUs are set, calls to
+.Fn cpuset_setaffinity
+fails with
+.Er EINVAL .
.Pp
The supplied mask should have a size of
.Fa cpusetsize
@@ -119,10 +124,6 @@
The
.Fa cpusetp
specified a CPU that was outside the set supported by the kernel.
-.It Bq Er ERANGE
-The
-.Fa cpusetsize
-is too small.
.It Bq Er ENOMEM
Insufficient memory exists to store the cpuset mask.
.El
Index: sys/kern/kern_cpuset.c
===================================================================
--- sys/kern/kern_cpuset.c
+++ sys/kern/kern_cpuset.c
@@ -1896,13 +1896,10 @@
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);
- size = cpusetsize;
- mask = malloc(size, M_TEMP, M_WAITOK | M_ZERO);
+ mask = malloc(sizeof(cpuset_t), M_TEMP, M_WAITOK | M_ZERO);
error = cpuset_which(which, id, &p, &ttd, &set);
if (error)
goto out;
@@ -1972,8 +1969,33 @@
cpuset_rel(set);
if (p)
PROC_UNLOCK(p);
- if (error == 0)
+ if (error == 0) {
+ if (cpusetsize < howmany(CPU_FLS(mask), NBBY)) {
+ error = ERANGE;
+ goto out;
+ }
+ size = min(cpusetsize, sizeof(cpuset_t));
error = copyout(mask, maskp, size);
+ if (error != 0)
+ goto out;
+ if (cpusetsize > size) {
+ char *end;
+ char *cp;
+ int rv;
+
+ end = cp = (char *)&maskp->__bits;
+ end += cpusetsize;
+ cp += size;
+ while (cp != end) {
+ rv = subyte(cp, 0);
+ if (rv == -1) {
+ error = EFAULT;
+ goto out;
+ }
+ cp++;
+ }
+ }
+ }
out:
free(mask, M_TEMP);
return (error);
@@ -2006,31 +2028,38 @@
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;
+ const char *end, *cp;
+ int val;
+ end = cp = (const char *)&maskp->__bits;
end += cpusetsize;
cp += sizeof(cpuset_t);
- while (cp != end)
- if (*cp++ != 0) {
+
+ while (cp != end) {
+ val = fubyte(cp);
+ if (val == -1) {
+ error = EFAULT;
+ goto out;
+ }
+ if (val != 0) {
error = EINVAL;
goto out;
}
+ cp++;
+ }
}
if (CPU_EMPTY(mask)) {
error = EDEADLK;

File Metadata

Mime Type
text/plain
Expires
Sun, Feb 8, 6:47 PM (21 h, 26 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28485976
Default Alt Text
D34849.id105532.diff (6 KB)

Event Timeline