Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
overlord,o/devicestate: restrict cloud-init on Ubuntu Core (#2)
* o/devicestate: add ensureCloudInitRestricted to DeviceManager This function will disable or restrict cloud-init after seeding is complete on an Ubuntu Core system. This is the full implementation of the mitigation of CVE-2020-11933 and https://bugs.launchpad.net/snapd/+bug/1879530. We want to allow some uses of cloud-init to continue to work, but we don't want cloud-init to be able to trigged arbitrarily after first boot because at that point the device should be considered "locked down". Signed-off-by: Ian Johnson <ian.johnson@canonical.com> * o/devicestate/devicemgr: set cloudInitAlreadyRestricted bool, use to skip early If we already restricted cloud-init we can set a manager bool to prevent unnecessary checking again for the duration of the manager. If snapd is restarted for example, it will ping cloud-init again to check the status and re-set the variable. Also add tests around this, including a full call to devicemgr.Ensure() to test that Ensure() calls ensureCloudInitRestricted(). Signed-off-by: Ian Johnson <ian.johnson@canonical.com> * o/devicestate/devicemgr, tests: adjust error msg, test names Signed-off-by: Ian Johnson <ian.johnson@canonical.com> * tests/o/devicestate: disable device registration in cloud-init Ensure() test Signed-off-by: Ian Johnson <ian.johnson@canonical.com> * tests/o/devicestate/cloudinit: simplify tests * Move duplicated setup to the SetUpTest preamble * Use a shared mockLogger instead of creating individual ones * Fix import ordering * Add missing MockCommand restores Signed-off-by: Ian Johnson <ian.johnson@canonical.com> * o/devicestate/devicemgr: adjust EnsureBefore logic to use time instead of count Previously, we were using the number of times we were called with a counter to determine if a specific time had elapsed, but this is fragile since EnsureBefore does not guarantee that we run in the specified time exactly, it ensures only that we will get re-run at some point before the specified time. This means that we could get scheduled to re-run very soon in time and incorrectly conclude that a significant amount of time had elapsed when in fact it had not. As a matter of fact, this bug was actually being relied upon (unknowingly in my defense) in the unit tests, where a call to settle() would just call Ensure repeatedly and cause the logic to assume that the specific time had elapsed. The solution to all of this is to keep track of time instead of count. Here, we save the first time we encounter cloud-init in one of the states we track it in, and check in all future instances if the time has actually elapsed before continuing. This does require significant mocking of time in the unit tests, but otherwise is a good solution. Signed-off-by: Ian Johnson <ian.johnson@canonical.com> * o/devicestate/devicemgr: while waiting in error state, only output msg once This previously would output a message every time EnsureCloudInitRestricted was called before hitting the timeout, but really we should only output it on the first time we find cloud-init in this state. Also add a test for this scenario, with Ensure getting scheduled before the 3 minute timeout has elapsed, so that we also have some test coverage of the timeout logic for error, previously we only had this logic covered for the CloudInitEnabled state. Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
- Loading branch information