Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 1 Sep 2019 21:38:08 +0000 (UTC)
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r351672 - head/sys/kern
Message-ID:  <201909012138.x81Lc8in093265@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: markj
Date: Sun Sep  1 21:38:08 2019
New Revision: 351672
URL: https://svnweb.freebsd.org/changeset/base/351672

Log:
  Restrict the input domain set in cpuset_setdomain(2) to all_domains.
  
  To permit larger values of MAXMEMDOM, which is currently 8 on amd64,
  cpuset_setdomain(2) accepts a mask of size 256.  In the kernel, domain
  set masks are 64 bits wide, but can only represent a set of MAXMEMDOM
  domains due to the use of the ds_order table.
  
  Domain sets passed to cpuset_setdomain(2) are restricted to a subset
  of their parent set, which is typically the root set, but before this
  happens we modify the input set to exclude empty domains.
  domainset_empty_vm() and other code which manipulates domain sets
  expect the mask to be a subset of all_domains, so enforce that when
  performing validation of cpuset_setdomain(2) parameters.
  
  Reported and tested by:	pho
  Reviewed by:	kib
  MFC after:	3 days
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D21477

Modified:
  head/sys/kern/kern_cpuset.c

Modified: head/sys/kern/kern_cpuset.c
==============================================================================
--- head/sys/kern/kern_cpuset.c	Sun Sep  1 21:20:31 2019	(r351671)
+++ head/sys/kern/kern_cpuset.c	Sun Sep  1 21:38:08 2019	(r351672)
@@ -2156,6 +2156,14 @@ kern_cpuset_setdomain(struct thread *td, cpulevel_t le
 	DOMAINSET_COPY(mask, &domain.ds_mask);
 	domain.ds_policy = policy;
 
+	/*
+	 * Sanitize the provided mask.
+	 */
+	if (!DOMAINSET_SUBSET(&all_domains, &domain.ds_mask)) {
+		error = EINVAL;
+		goto out;
+	}
+
 	/* Translate preferred policy into a mask and fallback. */
 	if (policy == DOMAINSET_POLICY_PREFER) {
 		/* Only support a single preferred domain. */
@@ -2165,12 +2173,12 @@ kern_cpuset_setdomain(struct thread *td, cpulevel_t le
 		}
 		domain.ds_prefer = DOMAINSET_FFS(&domain.ds_mask) - 1;
 		/* This will be constrained by domainset_shadow(). */
-		DOMAINSET_FILL(&domain.ds_mask);
+		DOMAINSET_COPY(&all_domains, &domain.ds_mask);
 	}
 
 	/*
-	 *  When given an impossible policy, fall back to interleaving
-	 *  across all domains
+	 * When given an impossible policy, fall back to interleaving
+	 * across all domains.
 	 */
 	if (domainset_empty_vm(&domain))
 		domainset_copy(&domainset2, &domain);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201909012138.x81Lc8in093265>