Re: Moving existing ostree users to a new branch - take 2



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



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]