Skip to content

Commit e605b36

Browse files
committed
cgroup: fix cgroup_subsys_state leak for seq_files
If a cgroup file implements either read_map() or read_seq_string(), such file is served using seq_file by overriding file->f_op to cgroup_seqfile_operations, which also overrides the release method to single_release() from cgroup_file_release(). Because cgroup_file_open() didn't use to acquire any resources, this used to be fine, but since f7d5881 ("cgroup: pin cgroup_subsys_state when opening a cgroupfs file"), cgroup_file_open() pins the css (cgroup_subsys_state) which is put by cgroup_file_release(). The patch forgot to update the release path for seq_files and each open/release cycle leaks a css reference. Fix it by updating cgroup_file_release() to also handle seq_files and using it for seq_file release path too. Signed-off-by: Tejun Heo <[email protected]> Cc: [email protected] # v3.12
1 parent 0fc0287 commit e605b36

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

kernel/cgroup.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ static void cgroup_destroy_css_killed(struct cgroup *cgrp);
199199
static int cgroup_destroy_locked(struct cgroup *cgrp);
200200
static int cgroup_addrm_files(struct cgroup *cgrp, struct cftype cfts[],
201201
bool is_add);
202+
static int cgroup_file_release(struct inode *inode, struct file *file);
202203

203204
/**
204205
* cgroup_css - obtain a cgroup's css for the specified subsystem
@@ -2429,7 +2430,7 @@ static const struct file_operations cgroup_seqfile_operations = {
24292430
.read = seq_read,
24302431
.write = cgroup_file_write,
24312432
.llseek = seq_lseek,
2432-
.release = single_release,
2433+
.release = cgroup_file_release,
24332434
};
24342435

24352436
static int cgroup_file_open(struct inode *inode, struct file *file)
@@ -2490,6 +2491,8 @@ static int cgroup_file_release(struct inode *inode, struct file *file)
24902491
ret = cft->release(inode, file);
24912492
if (css->ss)
24922493
css_put(css);
2494+
if (file->f_op == &cgroup_seqfile_operations)
2495+
single_release(inode, file);
24932496
return ret;
24942497
}
24952498

0 commit comments

Comments
 (0)