On Mon, 2017-05-15 at 10:45 +0200, Alexander Larsson wrote:
On Fri, 2017-05-12 at 13:23 -0400, Colin Walters wrote:Let's dive into just this bit: On Fri, May 12, 2017, at 06:13 AM, Alexander Larsson wrote:In particular, we need the signature on the summary, because otherwise we'd be vulnerable to a sidegrade attack where you switch one ref to a commit from another ref. If we record the ref in the commit, then we can possibly avoid the sidegrade attack, but that also seems like a weird design, commits are not supposed to be tied to one branch only.I happened to see this go by today: https://alephsecurity.com/2017/05/11/oneplus-ota/ Basically, the OnePlus phone updates are vulnerable to these kinds of sidegrades and in some cases plain downgrades. Now of course, libostree does have a timestamp check, but in practice that only helps a bit - take the Fedora Atomic Host where there are two active refs: fedora-atomic/25/x86_64/docker-host fedora/26/x86_64/atomic-host (Yes, we're renaming it for f26) Right now indeed we aren't signing the summary file, so an attacker capable of MITM of TLS (i.e. until we do cert pinning) could force a downgrade 26 -> 25 while 25 is still getting updates. But on the other hand, 25 is still getting updates, so hopefully it will also have the same security fixes. As soon as it stops being updated, "sidedown" attacks are no longer possible. In Fedora AH today, we do migrate commits across refs indeed. There are really 3: fedora-atomic/25/x86_64/docker-host fedora-atomic/25/x86_64/updates/docker-host fedora-atomic/25/x86_64/updates-testing/docker-host And the first ref is a "promotion" of the second. (updates-testing is currently independent but that's a whole subtopic)I think in practice this is not an issue for flatpak, because we don't change the ref like that as it essentially defines the app id. The promotion we do is really moving it from one repo to the other (i.e. users who want to run the testing version have to install it from there). When we "promote" the commit from the testing repo to the stable repo we create a new commit, both so that we can get it signed by a different key, but also because we want to have the history right on the stable repo (i.e. there might be several testing builds on the testing repo before we migrate it to stable, but we want the stable repo to only have histories, deltas, etc for the one new commit). So, I've basically added a new ostree operation, "flatpak build-commit- from" which creates a new commit, based on an old commit (possibly from a different local repo) which has the same content, but a different commit id. It also adds a reference to the "old commit" in the metadata in order to guarantee that the new commit gets a different sha256 and thus does not inherit the old signatures, etc.But that said...this feels like a "developer/tester" thing. If we expect the vast majority of users to track a single ref, we could indeed inject into the commit the name of the ref, and just relax the check for developer/testing scenario. (e.g. rpm-ostree rebase --security=unbind-ref fedora- atomic/25/x86_64/updates/docker-host which sets a local flag that turns off the "check commit ref" logic for that origin?) Going up a level then, if we had this implemented, it would feel natural then to do ref/repo redirections via commit metadata as well, right?From my perspective it would be fine to encode the ref name in the commit. That way we could support the system-helper for global installation without requiring a signed summary. In fact, you're probably right that this would be needed in the endless model where you're finding versions by broadcasting on the local net, as they will not have the full summary with all the branches. However, I'm still not sure that doing repo redirections via commit metadata is correct. At least not in *all* commits. Its clearly something that defines global properties for the repo, and duplicating it everywhere seems both wasteful and easy to get wrong (missing one ref, updating multiple times in the client, etc). However, in the case of flatpak I could easily imagine this metadata being in the commit metadata for *one* ref, with a well known name, rather than the summary. That way it could be signed, even if the summary is not. So, here is a strawman proposal: * Add new per-commit metadata "ostree.origin-ref", and set it whenever we commit. * Add a new operation to ostree that makes it easy to copy a commit from one ref to another, changing only the origin-ref. * Add a new security mode in the repo config where GPG signatures are required for commits *and* the commits are required to have an ostree.origin-ref that matches the ref that was pulled. * Add a new magic ref name, "ostree/config", where the commit contains metadata that is global configuration for the remote. There is a corresponding [config] group in the config file for the repo and an ostree operation that takes all the configuration data in the config group (plus the gpg key) and commits a new version of the ostree/config ref. (For flatpak I would also want to store our extra global metadata here with custom keys, currently xa.title and xa.default-branch.)
For that to work with the LAN/USB update stuff for flatpaks, the magic ref name would need to be globally unique — so probably `ostree/$originish/config` or something. Otherwise one LAN peer can’t advertise a single repository containing the `ostree/config` refs from two upstream remotes. Philip
* Add a client side operation that update the remote configuration based on a ostree/config commit object. (i.e. update url, add new gpg keys, revoke old gpg keys, etc).
Attachment:
signature.asc
Description: This is a digitally signed message part