-
Notifications
You must be signed in to change notification settings - Fork 583
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
many: update secboot and use new key format #14304
many: update secboot and use new key format #14304
Conversation
7183b85
to
63e5383
Compare
948f2b3
to
3060fd6
Compare
3060fd6
to
71aa49c
Compare
0940e30
to
b9e785f
Compare
|
b9e785f
to
d742f96
Compare
golang.org/x/term v0.8.0 // indirect | ||
maze.io/x/crypto v0.0.0-20190131090603-9b94c9afe066 // indirect | ||
) | ||
|
||
// github.com/intel-go was taken over | ||
replace github.com/intel-go/cpuid => github.com/aregm/cpuid v0.0.0-20220614022739-219e067757cb |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need a fix in secboot for this. @chrisccoulson ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I'm going to push this to the @canonical org.
6a8f879
to
dcb925e
Compare
// TODO: when save partition does not have slots, then | ||
// we need to create new partition the old fashion | ||
// way. Or, we should upgrade the save partition | ||
// (which should be safe since the seed should not be | ||
// considered safe to downgrade). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I need to create a spread test for that case first.
- Install with an old snapd.
- Remodel with a newer snapd.
- Factory reset with the new snapd.
It is possible that it is already working, but we are left with some non-slot keys that we should remove.
d274f23
to
eb18dca
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
did an initial pass
renames := map[string]string{ | ||
"default": "factory-reset-old", | ||
"default-fallback": "factory-reset-old-fallback", | ||
"save": "factory-reset-old-save", | ||
} | ||
if err := secboot.RenameOrDeleteKeys(saveNode, renames); err != nil { | ||
return nil, err | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what this bit of code is doing probably needs a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added a comment.
I am wondering if we should remove all the other keys (that is not "default" or "default-fallback"). We do remove the recovery keys. But in the future we will might have other keys. And it is not obvious which ones will need to be removed. Maybe all?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should probably leave a TODO somewhere about the fact that factory reset should indeed remove all extra keys when done?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you, notice that I also replied to some discussions from the previous pass
secboot/bootstrap_container_sb.go
Outdated
func (bc *bootstrappedContainer) AddKey(slotName string, newKey []byte, token bool) (KeyDataWriter, error) { | ||
if slotName == "" { | ||
slotName = "default" | ||
} | ||
if err := sb.AddLUKS2ContainerUnlockKey(bc.devicePath, slotName, sb.DiskUnlockKey(bc.key), sb.DiskUnlockKey(newKey)); err != nil { | ||
return nil, err | ||
} | ||
if !token { | ||
return nil, nil | ||
} | ||
return nil, fmt.Errorf("not implemented") | ||
} | ||
|
||
func (bc *bootstrappedContainer) RemoveBootstrapKey() error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these don't seem exercised by tests
boot/seal.go
Outdated
} { | ||
if container != nil { | ||
if err := container.RemoveBootstrapKey(); err != nil { | ||
// This could be a warning |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shall we log it then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we change it from an error to a warning, yes we should log it. But I do not think we should log here yet since we do return an error.
secboot/secboot_sb.go
Outdated
|
||
// AddBootstrapKeyOnExistingDisk will add a new bootstrap key to on | ||
// an existing encrypted disk. The disk is expected to be unlocked and | ||
// they key is available on . The bootstrap key is temporary and is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
available on ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I t was the keyring. I have pushed a fix.
data/systemd/snapd.service.in
Outdated
@@ -27,6 +27,8 @@ NotifyAccess=all | |||
SuccessExitStatus=42 | |||
RestartPreventExitStatus=42 | |||
KillMode=process | |||
#TODO: test with "shared" | |||
KeyringMode=inherit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wouldn't every process we spawn how have access to the same keyring we inherited from systemd? I suppose with this we could simply call snapd-fde-keymgr without systemd-run too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
Yes, we will call everything else with access to the keyring. But we should really not call anything we cannot trust anyway as we run as root and anything we call could just dispatch anything to systemd. Let's say there is a vulnerability in sfdisk, we are already vulnerable then. Unless we start dropping privileges on whatever we execute.
-
I can follow up with removing
systemd-run
from calling snapd-fde-keymgr. But it is a lot of changes in tests for very little.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it's fine, I don't think there's an urgent need to do anything about snapd-fde-keymgr right now. I think we should look into ensuring that the external things we run are isolated from us in a reasonable manner, and preferably invoked through systemd-run where possible.
bbcdecb
to
f5591f5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
if err != nil { | ||
return fmt.Errorf("cannot list slots in partition save partition: %v", err) | ||
} | ||
for _, slot := range slots { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a possible ordering issue when the target name repeats again as the name to rename from?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is that if renames contains for example A -> B, B -> C
. Then maybe A is renamed to B, or to C depending on the order?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added checks for 2 cases:
- As a precondition, give an internal error if we have something like
a -> b
,b -> c
. We cannot use the same name as a target or source. - Before we do the renaming, we verify that no target name exists in the luks2 container already. This is not an internal error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added also 2 FIXME notes in the caller part of the code. I do not think we need to save the "default" key. And I think we need to delete "default-fallback" if "factory-reset-old-fallback" exists, and not do the rename.
secboot/encrypt_sb.go
Outdated
slots, err := sbListLUKS2ContainerUnlockKeyNames(dev) | ||
if err != nil { | ||
return keys.RecoveryKey{}, fmt.Errorf("cannot find list keys for: %v", err) | ||
} | ||
if len(slots) == 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wonder if this maybe could be refactored into a more explicit function testing for the legacy setup?
or could use a comment maybe
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about adding hasOnlyLegacyKeys := len(slots) == 0
. And use that? I do not see anywhere else in the code where we need that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's fine, with a comment that key slot names were not used previously and lack of them indicates a legacy setup
89166a0
to
7178818
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've left a small number of comments, but this seems to be ok
@@ -100,7 +100,7 @@ var ( | |||
secbootMeasureSnapSystemEpochWhenPossible func() error | |||
secbootMeasureSnapModelWhenPossible func(findModel func() (*asserts.Model, error)) error | |||
secbootUnlockVolumeUsingSealedKeyIfEncrypted func(disk disks.Disk, name string, encryptionKeyFile string, opts *secboot.UnlockVolumeUsingSealedKeyOptions) (secboot.UnlockResult, error) | |||
secbootUnlockEncryptedVolumeUsingKey func(disk disks.Disk, name string, key []byte) (secboot.UnlockResult, error) | |||
secbootUnlockEncryptedVolumeUsingPlatformKey func(disk disks.Disk, name string, key []byte) (secboot.UnlockResult, error) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At some point, then intention is that snap-bootstrap calls plainkey.SetProtectorKeys
, and then there will just be a single API for unlocking data and save.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. Though that will still be here for the key data in files. That is for backward compliance.
I do not think we need that rename in this PR. That was an intermediate state of the spike, but later. I will check if I can revert this.
data/systemd/snapd.service.in
Outdated
@@ -27,6 +27,8 @@ NotifyAccess=all | |||
SuccessExitStatus=42 | |||
RestartPreventExitStatus=42 | |||
KillMode=process | |||
#TODO: test with "shared" | |||
KeyringMode=inherit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shared
should work as well. The main difference is that in inherit
mode, systemd leaves the session keyring pointer untouched (in this case, NULL, because PID1 does nothing to initialise a session keyring), so the kernel initialises it to the kernel created user session keyring associated with the root user on first access. In shared
mode, systemd creates a session keyring with a link to the user keyring in it, so that the user keyring becomes "possessed" and possessor permissions apply when accessing it. In private
mode, the link to the user keyring is missing so the service can access the user keyring with user permissions but not posseessor permissions. The security benefits of this are limited though - the user keyring can be linked in to a private
mode session keyring because the permissions of the user keyring permit user linking. So, even the default private
works here, but snapd would need to add a link to the user keyring from its session keyring, which is just extra work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have set it to shared.
@@ -377,13 +362,20 @@ fi | |||
if opts.encryption { | |||
runOpts.EncryptionType = secboot.EncryptionTypeLUKS | |||
} | |||
|
|||
defer install.MockCryptsetupOpen(func(key secboot.DiskUnlockKey, node, name string) error { | |||
return nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should these mocks test that any of the arguments are the expected values?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
golang.org/x/term v0.8.0 // indirect | ||
maze.io/x/crypto v0.0.0-20190131090603-9b94c9afe066 // indirect | ||
) | ||
|
||
// github.com/intel-go was taken over | ||
replace github.com/intel-go/cpuid => github.com/aregm/cpuid v0.0.0-20220614022739-219e067757cb |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I'm going to push this to the @canonical org.
1b74e68
to
85f269e
Compare
5afd0bc
into
canonical:fde-manager-features
This is the second part of moving to new secboot. This one is where we start using the new format.
This PR is draft as it is on top of #14282 (being split into smaller PRs) and #14253 (the first part of updating secboot).