Repository navigation
The clock query and the update fetcher give up every capability before they read from the network - #300
Merged
Conversation
…eading the network sntp-offset.py and update-fetch.py run as the net zone's root, which keeps CAP_NET_ADMIN, CAP_NET_RAW and the privilege-separation capabilities for dhcpcd and dnsmasq. Neither script needs any of them, yet a flaw in what parses a time server's reply, TLS or HTTP would have had them all. Each now sets no new privileges and empties its capability sets with capset before it reads a byte, and refuses to run if it cannot. The zones suite runs both in the net zone's user namespace, where its root holds every capability, holds each waiting on a broker socket or a time server that never answers, and reads that it holds none.
… it, and keeps what each process said
… whose loopback is up, and says what a send meets if it ends
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What was wrong.
sntp-offset.pyandupdate-fetch.pyrun as the net zone's root. That root keepsCAP_NET_ADMINandCAP_NET_RAW, plusCAP_SETUID,CAP_SETGIDandCAP_SYS_CHROOTfor dhcpcd's and dnsmasq's privilege drops. Neither script needs any of these, yet both parse what far hosts send: an NTP reply, and TLS and HTTP from the update channel. A flaw in that parsing would have had the firewall, the routes and raw sockets of the zone that carries every other zone's traffic.What changed.
drop_capabilities(). It callsprctl(PR_SET_NO_NEW_PRIVS)and thencapsetwith zeroed effective, permitted and inheritable sets, through ctypes; ambient goes with them. The zone's filter already allows both calls:capsetthroughseccomp::CAP_CALLSfor the keptCAP_SETUID, andprctlin the base list. kryptikd already sets no-new-privs on every zone process, and that is what keeps an emptied set empty across an exec by root. Setting it here makes the scripts hold the same guarantee wherever they run.update-fetch: ...line; the SNTP client exits 1 with nothing on stdout, which the init already reads as no answer.build/guest-tests/zones-check.sh: the new checkfetch-and-sntp-no-capsruns both scripts throughnsenter -t <net init> -U. In the net zone's user namespace, the zone's root holds every capability, so old code keeps them all. The fetcher waits on a broker socket that accepts but never answers, and the SNTP client waits on127.0.0.1:9, which never replies. The check then reads/proc/PID/statusand passes only when each process showsCapInh,CapPrm,CapEffandCapAmball zero andNoNewPrivs: 1.tools/image/zones-test.sh: lists the verdict. It goes on the list's last line, so it merges with Every claim in docs/architecture.md about what zones cannot share or reach has a guest check #280's and The net zone runs on one CPU's worth of time, and the zones suite reads its limit back #295's edits to that list.docs/design/net-zone.md: what the two scripts hold, and the test.How the run proves it. Under the Distro run's zones suite, the guest passes
fetch-and-sntp-no-capsonly with the drop in place. On main's scripts the same processes readCapEff: 000001ffffffffffandNoNewPrivs: 0. Under the real filter, the update suite's network step runs the real fetcher in the real net zone and the release still has to arrive, so a filter that refusedprctlorcapsetwould fail that step too. CI's offline suites (update-fetch.sh,netzone-time.sh) run both scripts unprivileged, where the drop also has to succeed.Merges clean with every open PR except #180 and #207, which already conflict with main in
run-ovmf.sh.