162306a36Sopenharmony_ci=========================== 262306a36Sopenharmony_ciDevice Whitelist Controller 362306a36Sopenharmony_ci=========================== 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci1. Description 662306a36Sopenharmony_ci============== 762306a36Sopenharmony_ci 862306a36Sopenharmony_ciImplement a cgroup to track and enforce open and mknod restrictions 962306a36Sopenharmony_cion device files. A device cgroup associates a device access 1062306a36Sopenharmony_ciwhitelist with each cgroup. A whitelist entry has 4 fields. 1162306a36Sopenharmony_ci'type' is a (all), c (char), or b (block). 'all' means it applies 1262306a36Sopenharmony_cito all types and all major and minor numbers. Major and minor are 1362306a36Sopenharmony_cieither an integer or * for all. Access is a composition of r 1462306a36Sopenharmony_ci(read), w (write), and m (mknod). 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ciThe root device cgroup starts with rwm to 'all'. A child device 1762306a36Sopenharmony_cicgroup gets a copy of the parent. Administrators can then remove 1862306a36Sopenharmony_cidevices from the whitelist or add new entries. A child cgroup can 1962306a36Sopenharmony_cinever receive a device access which is denied by its parent. 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci2. User Interface 2262306a36Sopenharmony_ci================= 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ciAn entry is added using devices.allow, and removed using 2562306a36Sopenharmony_cidevices.deny. For instance:: 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci echo 'c 1:3 mr' > /sys/fs/cgroup/1/devices.allow 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ciallows cgroup 1 to read and mknod the device usually known as 3062306a36Sopenharmony_ci/dev/null. Doing:: 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci echo a > /sys/fs/cgroup/1/devices.deny 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ciwill remove the default 'a *:* rwm' entry. Doing:: 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci echo a > /sys/fs/cgroup/1/devices.allow 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ciwill add the 'a *:* rwm' entry to the whitelist. 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci3. Security 4162306a36Sopenharmony_ci=========== 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ciAny task can move itself between cgroups. This clearly won't 4462306a36Sopenharmony_cisuffice, but we can decide the best way to adequately restrict 4562306a36Sopenharmony_cimovement as people get some experience with this. We may just want 4662306a36Sopenharmony_cito require CAP_SYS_ADMIN, which at least is a separate bit from 4762306a36Sopenharmony_ciCAP_MKNOD. We may want to just refuse moving to a cgroup which 4862306a36Sopenharmony_ciisn't a descendant of the current one. Or we may want to use 4962306a36Sopenharmony_ciCAP_MAC_ADMIN, since we really are trying to lock down root. 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ciCAP_SYS_ADMIN is needed to modify the whitelist or move another 5262306a36Sopenharmony_citask to a new cgroup. (Again we'll probably want to change that). 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ciA cgroup may not be granted more permissions than the cgroup's 5562306a36Sopenharmony_ciparent has. 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci4. Hierarchy 5862306a36Sopenharmony_ci============ 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_cidevice cgroups maintain hierarchy by making sure a cgroup never has more 6162306a36Sopenharmony_ciaccess permissions than its parent. Every time an entry is written to 6262306a36Sopenharmony_cia cgroup's devices.deny file, all its children will have that entry removed 6362306a36Sopenharmony_cifrom their whitelist and all the locally set whitelist entries will be 6462306a36Sopenharmony_cire-evaluated. In case one of the locally set whitelist entries would provide 6562306a36Sopenharmony_cimore access than the cgroup's parent, it'll be removed from the whitelist. 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ciExample:: 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci A 7062306a36Sopenharmony_ci / \ 7162306a36Sopenharmony_ci B 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci group behavior exceptions 7462306a36Sopenharmony_ci A allow "b 8:* rwm", "c 116:1 rw" 7562306a36Sopenharmony_ci B deny "c 1:3 rwm", "c 116:2 rwm", "b 3:* rwm" 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ciIf a device is denied in group A:: 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci # echo "c 116:* r" > A/devices.deny 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ciit'll propagate down and after revalidating B's entries, the whitelist entry 8262306a36Sopenharmony_ci"c 116:2 rwm" will be removed:: 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci group whitelist entries denied devices 8562306a36Sopenharmony_ci A all "b 8:* rwm", "c 116:* rw" 8662306a36Sopenharmony_ci B "c 1:3 rwm", "b 3:* rwm" all the rest 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ciIn case parent's exceptions change and local exceptions are not allowed 8962306a36Sopenharmony_cianymore, they'll be deleted. 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ciNotice that new whitelist entries will not be propagated:: 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci A 9462306a36Sopenharmony_ci / \ 9562306a36Sopenharmony_ci B 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci group whitelist entries denied devices 9862306a36Sopenharmony_ci A "c 1:3 rwm", "c 1:5 r" all the rest 9962306a36Sopenharmony_ci B "c 1:3 rwm", "c 1:5 r" all the rest 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ciwhen adding ``c *:3 rwm``:: 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci # echo "c *:3 rwm" >A/devices.allow 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_cithe result:: 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci group whitelist entries denied devices 10862306a36Sopenharmony_ci A "c *:3 rwm", "c 1:5 r" all the rest 10962306a36Sopenharmony_ci B "c 1:3 rwm", "c 1:5 r" all the rest 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_cibut now it'll be possible to add new entries to B:: 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci # echo "c 2:3 rwm" >B/devices.allow 11462306a36Sopenharmony_ci # echo "c 50:3 r" >B/devices.allow 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_cior even:: 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci # echo "c *:3 rwm" >B/devices.allow 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ciAllowing or denying all by writing 'a' to devices.allow or devices.deny will 12162306a36Sopenharmony_cinot be possible once the device cgroups has children. 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci4.1 Hierarchy (internal implementation) 12462306a36Sopenharmony_ci--------------------------------------- 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_cidevice cgroups is implemented internally using a behavior (ALLOW, DENY) and a 12762306a36Sopenharmony_cilist of exceptions. The internal state is controlled using the same user 12862306a36Sopenharmony_ciinterface to preserve compatibility with the previous whitelist-only 12962306a36Sopenharmony_ciimplementation. Removal or addition of exceptions that will reduce the access 13062306a36Sopenharmony_cito devices will be propagated down the hierarchy. 13162306a36Sopenharmony_ciFor every propagated exception, the effective rules will be re-evaluated based 13262306a36Sopenharmony_cion current parent's access rules. 133