kern: cpuset: plug a unr leak

cpuset_rel_defer() is supposed to be functionally equivalent to
cpuset_rel() but with anything that might sleep deferred until
cpuset_rel_complete -- this setup is used specifically for cpuset_setproc.

Add in the missing unr free to match cpuset_rel. This fixes a leak that
was observed when I wrote a small userland application to try and debug
another issue, which effectively did:

cpuset(&newid);
cpuset(&scratch);

newid gets leaked when scratch is created; it's off the list, so there's
no mechanism for anything else to relinquish it. A more realistic reproducer
would likely be a process that inherits some cpuset that it's the only ref
for, but it creates a new one to modify. Alternatively, administratively
reassigning a process' cpuset that it's the last ref for will have the same
effect.

Discovered through D27498.

MFC after:	1 week
This commit is contained in:
Kyle Evans 2020-12-08 18:44:06 +00:00
parent 95e1f42eb9
commit 9c83dab96c

View File

@ -246,9 +246,14 @@ cpuset_rel_defer(struct setlist *head, struct cpuset *set)
static void
cpuset_rel_complete(struct cpuset *set)
{
cpusetid_t id;
id = set->cs_id;
LIST_REMOVE(set, cs_link);
cpuset_rel(set->cs_parent);
uma_zfree(cpuset_zone, set);
if (id != CPUSET_INVALID)
free_unr(cpuset_unr, id);
}
/*