diff --git a/private/app_neverallows.te b/private/app_neverallows.te
index 344ecd54449bdef71b4bf31473d706ccef4589fc..1e824046b4f2670daafa993ddbdfb0644d8e98d4 100644
--- a/private/app_neverallows.te
+++ b/private/app_neverallows.te
@@ -274,3 +274,6 @@ neverallow all_untrusted_apps mediaextractor_update_service:service_manager find
 # This will go away in a future Android release
 neverallow { all_untrusted_apps -untrusted_app_25 } proc_tty_drivers:file r_file_perms;
 neverallow all_untrusted_apps proc_tty_drivers:file ~r_file_perms;
+
+# Untrusted apps are not allowed to use cgroups.
+neverallow all_untrusted_apps cgroup:file *;
diff --git a/private/priv_app.te b/private/priv_app.te
index e12cce7657c350106016dd82ef317837cfd51b16..192221db0639f3cead76973d61963b82befc7397 100644
--- a/private/priv_app.te
+++ b/private/priv_app.te
@@ -218,3 +218,6 @@ neverallow priv_app file_type:file link;
 # upon traceur to pass a file descriptor which they can then read
 neverallow priv_app trace_data_file:dir *;
 neverallow priv_app trace_data_file:file { no_w_file_perms open };
+
+# Do not allow priv_app access to cgroups.
+neverallow priv_app cgroup:file *;
diff --git a/private/system_app.te b/private/system_app.te
index 40fec6acfdbad96383351d11657f120a9ddb58dc..4bfcc18f4d0d7e187c5db6f9fedb04f7c66d1593 100644
--- a/private/system_app.te
+++ b/private/system_app.te
@@ -122,6 +122,9 @@ allow system_app {
   proc_version
 }:file r_file_perms;
 
+# Settings app writes to /dev/stune/foreground/tasks.
+allow system_app cgroup:file w_file_perms;
+
 control_logd(system_app)
 read_runtime_log_tags(system_app)
 get_prop(system_app, device_logging_prop)
diff --git a/public/app.te b/public/app.te
index 5a8215211b23ad717200b7232208382b545ba870..800e891b4d7f187f3315de6a27e18d99dc2e85db 100644
--- a/public/app.te
+++ b/public/app.te
@@ -22,10 +22,6 @@ allow appdomain zygote_exec:file rx_file_perms;
 # Notify zygote of death;
 allow appdomain zygote:process sigchld;
 
-# Place process into foreground / background
-allow appdomain cgroup:dir { search write };
-allow appdomain cgroup:file rw_file_perms;
-
 # Read /data/dalvik-cache.
 allow appdomain dalvikcache_data_file:dir { search getattr };
 allow appdomain dalvikcache_data_file:file r_file_perms;
diff --git a/public/domain.te b/public/domain.te
index e9bdb6deccca2e99321a899c368733e400e41477..244e08948e24c4961a91d2cbbb3e274f139a8c44 100644
--- a/public/domain.te
+++ b/public/domain.te
@@ -258,9 +258,34 @@ allow domain selinuxfs:file getattr;
 allow domain sysfs:dir search;
 allow domain selinuxfs:filesystem getattr;
 
-# For /acct/uid/*/tasks.
-allow domain cgroup:dir { search write };
-allow domain cgroup:file w_file_perms;
+# Path resolution access in cgroups.
+allow domain cgroup:dir search;
+allow { coredomain -appdomain } cgroup:dir w_dir_perms;
+allow { coredomain -appdomain } cgroup:file w_file_perms;
+
+# TODO(b/110043362): Clean up cgroup access from app domains.
+allow {
+  # Can not use all_untrusted_apps macro here, so expanding inline.
+  # This list is essentially { appdomain -all_untrusted_apps -priv_app }
+  appdomain
+  -ephemeral_app
+  -isolated_app
+  -mediaprovider
+  -untrusted_app
+  -untrusted_app_25
+  -untrusted_app_27
+  -untrusted_app_all
+  -priv_app
+} cgroup:file w_file_perms;
+auditallow appdomain cgroup:file w_file_perms;
+
+# TODO(b/110043362): Clean up cgroup access from non-system domains.
+allow { domain -coredomain } cgroup:file w_file_perms;
+auditallow {
+  domain
+  -coredomain
+  -vendor_init
+} cgroup:file w_file_perms;
 
 # Almost all processes log tracing information to
 # /sys/kernel/debug/tracing/trace_marker
diff --git a/public/init.te b/public/init.te
index 02a0dfe7c70b07c98127e17d9712bbf8eab3f522..eb27dbd329d544234a255bf6be10495e0f53abc0 100644
--- a/public/init.te
+++ b/public/init.te
@@ -93,7 +93,7 @@ allow init sysfs:dir mounton;
 allow init tmpfs:dir create_dir_perms;
 allow init tmpfs:dir mounton;
 allow init cgroup:dir create_dir_perms;
-r_dir_file(init, cgroup)
+allow init cgroup:file rw_file_perms;
 allow init cpuctl_device:dir { create mounton };
 
 # /config
diff --git a/public/vendor_init.te b/public/vendor_init.te
index 01c2f17fdba49c2445e8d3016c767e7288d65cca..8cd9b473e6c4c4fcc4d9806209702677bb5528e4 100644
--- a/public/vendor_init.te
+++ b/public/vendor_init.te
@@ -15,6 +15,7 @@ allow vendor_init rootfs:lnk_file { create unlink };
 
 # Create cgroups mount points in tmpfs and mount cgroups on them.
 allow vendor_init cgroup:dir create_dir_perms;
+allow vendor_init cgroup:file w_file_perms;
 
 # /config
 allow vendor_init configfs:dir mounton;