Fix lock ordering issue when enumerating cgroup tasks.

The control files enumerating tasks and threads residing in cgroupfs
incorrectly locks cgroupfs.filesystem.tasksMu before
kernel.TaskSet.mu.

The contents of these control files are inherently racy anyways, so
use a snapshot of the tasks in the cgroup and drop tasksMu before
resolving pids/tids (which acquires TaskSet.mu).

PiperOrigin-RevId: 378767060
This commit is contained in:
Rahat Mahmood
2021-06-10 17:09:17 -07:00
committed by gVisor bot
parent 0058fca32e
commit 3fcbad5093
2 changed files with 16 additions and 10 deletions
+13 -8
View File
@@ -133,6 +133,17 @@ func (c *cgroupInode) Controllers() []kernel.CgroupController {
return c.fs.kcontrollers
}
// tasks returns a snapshot of the tasks inside the cgroup.
func (c *cgroupInode) tasks() []*kernel.Task {
c.fs.tasksMu.RLock()
defer c.fs.tasksMu.RUnlock()
ts := make([]*kernel.Task, 0, len(c.ts))
for t := range c.ts {
ts = append(ts, t)
}
return ts
}
// Enter implements kernel.CgroupImpl.Enter.
func (c *cgroupInode) Enter(t *kernel.Task) {
c.fs.tasksMu.Lock()
@@ -163,10 +174,7 @@ func (d *cgroupProcsData) Generate(ctx context.Context, buf *bytes.Buffer) error
pgids := make(map[kernel.ThreadID]struct{})
d.fs.tasksMu.RLock()
defer d.fs.tasksMu.RUnlock()
for task := range d.ts {
for _, task := range d.tasks() {
// Map dedups pgid, since iterating over all tasks produces multiple
// entries for the group leaders.
if pgid := currPidns.IDOfThreadGroup(task.ThreadGroup()); pgid != 0 {
@@ -205,10 +213,7 @@ func (d *tasksData) Generate(ctx context.Context, buf *bytes.Buffer) error {
var pids []kernel.ThreadID
d.fs.tasksMu.RLock()
defer d.fs.tasksMu.RUnlock()
for task := range d.ts {
for _, task := range d.tasks() {
if pid := currPidns.IDOfTask(task); pid != 0 {
pids = append(pids, pid)
}
+3 -2
View File
@@ -49,8 +49,9 @@
//
// kernel.CgroupRegistry.mu
// cgroupfs.filesystem.mu
// Task.mu
// cgroupfs.filesystem.tasksMu.
// kernel.TaskSet.mu
// kernel.Task.mu
// cgroupfs.filesystem.tasksMu.
package cgroupfs
import (