svn commit: r368681 - stable/12/sys/kern

Kyle Evans kevans at FreeBSD.org
Tue Dec 15 21:53:15 UTC 2020


Author: kevans
Date: Tue Dec 15 21:53:15 2020
New Revision: 368681
URL: https://svnweb.freebsd.org/changeset/base/368681

Log:
  MFC r368462: cpuset_set{affinity,domain}: do not allow empty masks
  
  cpuset_modify() would not currently catch this, because it only checks that
  the new mask is a subset of the root set and circumvents the EDEADLK check
  in cpuset_testupdate().
  
  This change both directly validates the mask coming in since we can
  trivially detect an empty mask, and it updates cpuset_testupdate to catch
  stuff like this going forward by always ensuring we don't end up with an
  empty mask.
  
  The check_mask argument has been renamed because the 'check' verbiage does
  not imply to me that it's actually doing a different operation. We're either
  augmenting the existing mask, or we are replacing it entirely.

Modified:
  stable/12/sys/kern/kern_cpuset.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/kern/kern_cpuset.c
==============================================================================
--- stable/12/sys/kern/kern_cpuset.c	Tue Dec 15 21:52:31 2020	(r368680)
+++ stable/12/sys/kern/kern_cpuset.c	Tue Dec 15 21:53:15 2020	(r368681)
@@ -633,7 +633,7 @@ domainset_shadow(const struct domainset *pdomain,
  * empty as well as RDONLY flags.
  */
 static int
-cpuset_testupdate(struct cpuset *set, cpuset_t *mask, int check_mask)
+cpuset_testupdate(struct cpuset *set, cpuset_t *mask, int augment_mask)
 {
 	struct cpuset *nset;
 	cpuset_t newmask;
@@ -642,13 +642,14 @@ cpuset_testupdate(struct cpuset *set, cpuset_t *mask, 
 	mtx_assert(&cpuset_lock, MA_OWNED);
 	if (set->cs_flags & CPU_SET_RDONLY)
 		return (EPERM);
-	if (check_mask) {
-		if (!CPU_OVERLAP(&set->cs_mask, mask))
-			return (EDEADLK);
+	if (augment_mask) {
 		CPU_COPY(&set->cs_mask, &newmask);
 		CPU_AND(&newmask, mask);
 	} else
 		CPU_COPY(mask, &newmask);
+
+	if (CPU_EMPTY(&newmask))
+		return (EDEADLK);
 	error = 0;
 	LIST_FOREACH(nset, &set->cs_children, cs_siblings) 
 		if ((error = cpuset_testupdate(nset, &newmask, 1)) != 0)
@@ -723,7 +724,7 @@ out:
  */
 static int
 cpuset_testupdate_domain(struct cpuset *set, struct domainset *dset,
-    struct domainset *orig, int *count, int check_mask)
+    struct domainset *orig, int *count, int augment_mask __unused)
 {
 	struct cpuset *nset;
 	struct domainset *domain;
@@ -1923,6 +1924,10 @@ kern_cpuset_setaffinity(struct thread *td, cpulevel_t 
 			}
 
 	}
+	if (CPU_EMPTY(mask)) {
+		error = EDEADLK;
+		goto out;
+	}
 	switch (level) {
 	case CPU_LEVEL_ROOT:
 	case CPU_LEVEL_CPUSET:
@@ -2177,6 +2182,10 @@ kern_cpuset_setdomain(struct thread *td, cpulevel_t le
 				goto out;
 			}
 
+	}
+	if (DOMAINSET_EMPTY(mask)) {
+		error = EDEADLK;
+		goto out;
 	}
 	DOMAINSET_COPY(mask, &domain.ds_mask);
 	domain.ds_policy = policy;


More information about the svn-src-all mailing list