diff options
author | Kyle Evans <kevans@FreeBSD.org> | 2020-12-15 21:51:45 +0000 |
---|---|---|
committer | Kyle Evans <kevans@FreeBSD.org> | 2020-12-15 21:51:45 +0000 |
commit | 64b4d0ba0b4e35589a88c6035d6675ce1770c01d (patch) | |
tree | 4965f544dbfde03fe049531bc8b66ff112aa2d5b | |
parent | e4e8ecaf63ba6f2767680a7b4666461243d88749 (diff) | |
download | src-test2-64b4d0ba0b4e35589a88c6035d6675ce1770c01d.tar.gz src-test2-64b4d0ba0b4e35589a88c6035d6675ce1770c01d.zip |
MFC r368460: 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.
Notes
Notes:
svn path=/stable/12/; revision=368679
-rw-r--r-- | sys/kern/kern_cpuset.c | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/sys/kern/kern_cpuset.c b/sys/kern/kern_cpuset.c index c82f776c37f1..7e1e3c4da2d4 100644 --- a/sys/kern/kern_cpuset.c +++ b/sys/kern/kern_cpuset.c @@ -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); } /* |