Since cgroup_mutex is being acquired when reading from a world readable cgroup.stat control file, it is possible that repeated reading of cgroup.stat may be used as a denial of service (DoS) attack vector by unprivileged users to greatly hinder cgroup related operations in a system. To prevent this, we are limiting the reading of cgroup.stat file from unprivileged users to at most 8 times per second. Signed-off-by: Waiman Long <longman@xxxxxxxxxx> --- kernel/cgroup/cgroup.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 18c982a06446..56ac9f14d100 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -3668,12 +3668,22 @@ static int cgroup_events_show(struct seq_file *seq, void *v) static int cgroup_stat_show(struct seq_file *seq, void *v) { + static unsigned long unpriv_timestamp; struct cgroup *cgroup = seq_css(seq)->cgroup; struct cgroup_subsys_state *css; int ssid; + /* + * Unprivileged users can only read cgroup.stat up to 8 times + * per second to avoid potential DoS attack. + */ + if (!capable(CAP_SYS_ADMIN) && + time_before(jiffies, unpriv_timestamp + (HZ >> 3))) + msleep(HZ >> 3); + /* cgroup_mutex required for for_each_css() */ cgroup_lock(); + unpriv_timestamp = jiffies; seq_printf(seq, "nr_descendants %d\n", cgroup->nr_descendants); seq_printf(seq, "nr_dying_descendants %d\n", -- 2.39.3