Gentoo Archives: gentoo-dev

From: Brian Harring <ferringb@×××××.com>
To: gentoo-dev@l.g.o
Subject: Re: [gentoo-dev] Git braindump: 1 of N: merging & git signing
Date: Mon, 04 Jun 2012 20:42:23
Message-Id: 20120604204132.GB3692@localhost
In Reply to: Re: [gentoo-dev] Git braindump: 1 of N: merging & git signing by Rich Freeman
On Mon, Jun 04, 2012 at 03:27:03PM -0400, Rich Freeman wrote:
> On Mon, Jun 4, 2012 at 3:10 PM, Brian Harring <ferringb@×××××.com> wrote: > > One thing people need to keep in mind here is that when you sign the > > commit, you're signing off on the history implicitly. ?Directly > > addressing freeman's comment about "people sign the manifest but don't > > look at what they're signing", when it comes to git signage, bluntly, > > people doing that shouldn't have access- if they can't be arsed to > > validate what they're signing, then trusting them w/ the tree is > > probably questionable. > > I suspect that you're missing my point. The argument was made that as > long as merge commits are signed you know that unsigned commits > referenced by them are OK. However, some of those commits might have > been already in gentoo-x86 and I doubt that anybody is going to check > those.
Going over the details on the offchance you're misunderstanding part of it: A signed commit is a signing of the git metadata; tree hash (literally, the state of the tree), committer, author, message, and parent sha1. Each git commit includes it's parent sha1 in it; this gives a locked history for a given commit sha1 (unless someone preimages sha1). What matters is that the leaf node, the final point in the graph, is signed- that's a dev sign off on effectively that they created that particular locked history. Realistically signing of each node is preferable, but the leaf is the minimal required. The dev, prior to signing that, should be verifying what they're adding (moreso, what exists between last signed rev and theirs), they agree to and know of. Specifically, they're asserting their addition. When the dev resync's, part of the process *should* be validating that the new remote ToT is actually signed by a trusted key; aka, another dev. For merge commits, the same applies here- due to the rather nice sha1 hack of git, signing the merge commit has the same angle, the dev signs off on the new addition effectively (for merge commits, moreso that the resultant integration is what they intended). Now to pick at your statement; "the dev is signing off on commits already in x86"; think through this scheme; each dev signs off as they go on their specific changes, validating backwards is doable- meaning you can validate that all commits in the vcs were signed off by trusted folk (ie, dev's). Your argument is either based on misunderstanding how this works (potentially just ignoring the pull validation devs have to do), or assuming that the dev is responsible for signing off on *everything* in the tree's proceeding history just because they're signing a specific history/tree sha. As indicated above, they're signing off essentially on each gap between signing, the delta.
> If I have a perfect commit, I do a git pull and a git push and > the result is a merge that references whatever was in gentoo-x86 > before, whether placed there by dev, or hacker, or whatever. Unless I > go back and review the existing gentoo-x86 history (and likely have to > repeat the process when somebody else does a push before I do), I > can't vouch for what was in there already - just what I'm adding.
For someone to inject something into the history requires basically a sha1 preimage attack, or the dev to be hit by an injection attack, along w/ the dev *skipping* validation of the pull to current ToT. If we require every commit to be signed, that blocks the potential for a careless dev skipping the valdation to sign off on things that were injected. This is a bit honerous, and is why signed pushes were the preference (and is a bit of an abuse what we're doing now).
> The reason I mentioned maifests is that they have the same issue. If > I keyword an arch on foo-1.4.5, I sign the manifest. That doesn't > mean that I checked every file in the package's directory tree for > issues. At most I checked foo-1.4.5, but I can't sign off on just > 1.4.5 - I have to sign off on everything. Also, when I sign off on > 1.4.5, I'm really just signing off for the keyword change, not the > piece of buggy code I didn't write on line 37 of the ebuild.
Manifests aren't particularly comparable, nor is it worth trying to do so. Technically w/ CVS manifests you can isolate down just the delta, and infer that the signage was for that, but the tools don't particularly exist for it, nor is it worth it; cvs just isn't designed sanely to allow for this. With git however, since the signing can be integrated directly into the revs themselves, you *are* directly signing the deltas; as said, w/ cvs technically you are (even if you're signing all of the results). An additional note btw; to be clear, the only manifest file that exists in a git tree is a thin manifest holding checksums for the distilfes involved. If you're thinking of rsync distributed trees (which aren't thin manifests), the plan was to enhance the existing rsync snapshot generation scripts so that they do validation of the history (comparing against the dev keyring), and generate signed manifests for rsync distribution. Any failure in validation == no update to the snapshot. If that doesn't answer your question/concerns, be more explicit please. ~harring