-
Notifications
You must be signed in to change notification settings - Fork 263
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
VHD with dm-verity #985
VHD with dm-verity #985
Conversation
I assume that
for the test failure is related to something I didn't do correctly related to go.mod when adding the new dependency. Is this because I didn't vendor the new dependency? |
.github/workflows/ci.yml
Outdated
- run: go build ./cmd/dmverity-vhd | ||
- run: go build ./cmd/roothash |
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 didn't add these to the artifact upload that appears directly below this, should I? I'm not sure what happens with those artifacts so I left out for now.
@@ -95,17 +95,17 @@ const ( | |||
inodeFirst = 11 | |||
inodeLostAndFound = inodeFirst | |||
|
|||
blockSize = 4096 | |||
blocksPerGroup = blockSize * 8 | |||
BlockSize = 4096 |
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.
Made BlockSize
exported as this value needs to be the same both during ext4 creation and when generating the dm-verity information.
for the error, did you try |
@anmaxvl I did not because I wasnt sure what to do. Will do that now. |
that worked @anmaxvl. thanks. |
ext4/dmverity/dmverity.go
Outdated
DataBlocks uint64 | ||
} | ||
|
||
func Tree(data []byte) []byte { |
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.
not in scope of this PR, but this should probably be some sort of a Reader
and we'd read the VHD data sequentially in blocks, rather than everything into memory?
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.
Perhaps. I went with the "easiest thing to get working". I'm not really sure whether it should be or not.
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 its a Reader then you need to write the tree somewhere... for the most common use case that would mean, writing the tree somewhere to save a probably small amount of memory so you can read the tree from that location to write it to its final location. Not really sure that is a win. It's more complicated, unlike to have much memory pressure and would be doing extra IO.
This should be squashed on merge maintaining only the first commit comment. Do you normally do that via the GitHub UI or should I be handling that locally and then force pushing? |
@SeanTAllen we normally do that locally and force push |
nextLevel.Write(padding) | ||
|
||
currentLevel = nextLevel | ||
layers = append(layers, currentLevel.Bytes()) |
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.
Why don't we write the first layer?
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.
the first layer is the VHD data itself, so we're skipping it here.
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 do you mean by "first layer" @katiewasnothere?
} | ||
rootHash := hash2(dmvSB.Salt[:dmvSB.SaltSize], block) | ||
return &VerityInfo{ | ||
RootDigest: fmt.Sprintf("%x", rootHash), |
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.
instead of doing an sprintf, you can use golang's built in string
func to convert a byte slice to a string.
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.
string() will have it try and be decoded as valid utf-8 I think. Here's a run with the alpine image in the README for both methods.
fmt.Sprintf("%x", rootHash)
: ea1303202ccc2e71b4f40d13537c0dda1058b232293d42c6cd18258df0210642
Convert via string(): �►X�2)=B��↑%��!♠B
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.
It seems like this was intentional
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.
yeah, this was intentional. I initially did try to just convert via string
.
return &VerityInfo{ | ||
RootDigest: fmt.Sprintf("%x", rootHash), | ||
Algorithm: string(bytes.Trim(dmvSB.Algorithm[:], "\x00")), | ||
Salt: fmt.Sprintf("%x", dmvSB.Salt[:dmvSB.SaltSize]), |
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.
same here, you can use the string
func
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.
#985 (comment) Same as this. I'd assume this was intentional but someone chime in
@SeanTAllen We'd generally prefer to have any dependency additions/updates in a separate commit from changes themselves. Makes it a lot easier to track down |
cmd/dmverity-vhd/main.go
Outdated
if err != nil { | ||
return nil, errors.Wrapf(err, "failed to set remote") | ||
} | ||
if verbose { |
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.
nit: maybe a wrapper func to get rid of the eight if verbose
's. Or I guess we could use logrus and set the log level to debug if verbose was specified and log these with logrus.Debug
.
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'd still like to see the new dependency for the dmverity-vhd binary vendored in in a separate commit, but the changes lgtm.
@microsoft/containerplat , PTaL |
- allow for the creation of dmverity superblocks - getting the complete merkle tree - getting a roothash from an existing tree tar2ext4 now takes an additional option to include tree information in the generated VHD. Information will be stored as: ext4 / verity superblock / merkle tree / VHD footer assuming that all optional content is included. At time, the salt value for all verity code is hardcoded. It could be changed later as with the usage of a superblock, we no longer need to know the salt on the use side as it will be obainted from the superblock. The included `cmd/dmverity-vhd` and `cmd/roothash` commands can be used for testing. dmverity-hd takes the name of a docker image which it will download and for each layer, it will generate a VHD in the provided output directory. The layer VHDs are named after the SHA for the given layer. dmverity-vhd outputs the name of each vhd created. roothash takes the nane of a docker image which it will download and for each layer, it will output the roothash for the layer. For example: ``` > ./dmverity-vhd -i alpine:3.10 -o test test/483b65c07faaf8ee7f1f57c6d7de0eda9dfd61a34f03337926650b8178db5286 > ./roothash -i alpine:3.10 680edf0d62d42085f446efc20f34d02f5d21f4a2eec1ab79506809321105a13a > dumpe2fs test/483b65c07faaf8ee7f1f57c6d7de0eda9dfd61a34f03337926650b8178db5286 dumpe2fs 1.45.5 (07-Jan-2020) Filesystem volume name: <none> Last mounted on: <not available> Filesystem UUID: <none> Filesystem magic number: 0xEF53 Filesystem revision #: 1 (dynamic) Filesystem features: ext_attr sparse_super2 filetype extent flex_bg large_file huge_file extra_isize read-only Default mount options: (none) Filesystem state: clean Errors behavior: Continue Filesystem OS type: Linux Inode count: 496 Block count: 1544 Reserved block count: 0 Free blocks: 7 Free inodes: 3 First block: 0 Block size: 4096 Fragment size: 4096 Blocks per group: 32768 Fragments per group: 32768 Inodes per group: 496 Inode blocks per group: 31 Flex block group size: 2147483648 Last mount time: n/a Last write time: Wed Dec 31 19:00:00 1969 Mount count: 0 Maximum mount count: 0 Last checked: Wed Dec 31 19:00:00 1969 Check interval: 0 (<none>) Reserved blocks uid: 0 (user root) Reserved blocks gid: 0 (group root) First inode: 11 Inode size: 256 Required extra isize: 24 Desired extra isize: 24 Group 0: (Blocks 0-1543) Primary superblock at 0, Group descriptors at 1-1 Block bitmap at 1542 (+1542) Inode bitmap at 1543 (+1543) Inode table at 1511-1541 (+1511) 7 free blocks, 3 free inodes, 90 directories Free blocks: 2-8 Free inodes: 494-496 > veritysetup verify --data-blocks=1544 \ --hash-offset=6324224 \ test/483b65c07faaf8ee7f1f57c6d7de0eda9dfd61a34f03337926650b8178db5286 \ test/483b65c07faaf8ee7f1f57c6d7de0eda9dfd61a34f03337926650b8178db5286 \ 680edf0d62d42085f446efc20f34d02f5d21f4a2eec1ab79506809321105a13a ``` where no output from the verifysetup command means that everything is working as expected.
additionally combine dmverity-vhd and roothash into a single app with corresponding subcommands. Signed-off-by: Maksim An <[email protected]>
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
* Adds a dm-verity integrity option to VHDs created from tar files. - allow for the creation of dmverity superblocks - getting the complete merkle tree - getting a roothash from an existing tree tar2ext4 now takes an additional option to include tree information in the generated VHD. Information will be stored as: ext4 / verity superblock / merkle tree / VHD footer assuming that all optional content is included. At time, the salt value for all verity code is hardcoded. It could be changed later as with the usage of a superblock, we no longer need to know the salt on the use side as it will be obainted from the superblock. The included `cmd/dmverity-vhd` and `cmd/roothash` commands can be used for testing. dmverity-hd takes the name of a docker image which it will download and for each layer, it will generate a VHD in the provided output directory. The layer VHDs are named after the SHA for the given layer. dmverity-vhd outputs the name of each vhd created. roothash takes the nane of a docker image which it will download and for each layer, it will output the roothash for the layer. For example: ``` > ./dmverity-vhd -i alpine:3.10 -o test test/483b65c07faaf8ee7f1f57c6d7de0eda9dfd61a34f03337926650b8178db5286 > ./roothash -i alpine:3.10 680edf0d62d42085f446efc20f34d02f5d21f4a2eec1ab79506809321105a13a > dumpe2fs test/483b65c07faaf8ee7f1f57c6d7de0eda9dfd61a34f03337926650b8178db5286 dumpe2fs 1.45.5 (07-Jan-2020) Filesystem volume name: <none> Last mounted on: <not available> Filesystem UUID: <none> Filesystem magic number: 0xEF53 Filesystem revision #: 1 (dynamic) Filesystem features: ext_attr sparse_super2 filetype extent flex_bg large_file huge_file extra_isize read-only Default mount options: (none) Filesystem state: clean Errors behavior: Continue Filesystem OS type: Linux Inode count: 496 Block count: 1544 Reserved block count: 0 Free blocks: 7 Free inodes: 3 First block: 0 Block size: 4096 Fragment size: 4096 Blocks per group: 32768 Fragments per group: 32768 Inodes per group: 496 Inode blocks per group: 31 Flex block group size: 2147483648 Last mount time: n/a Last write time: Wed Dec 31 19:00:00 1969 Mount count: 0 Maximum mount count: 0 Last checked: Wed Dec 31 19:00:00 1969 Check interval: 0 (<none>) Reserved blocks uid: 0 (user root) Reserved blocks gid: 0 (group root) First inode: 11 Inode size: 256 Required extra isize: 24 Desired extra isize: 24 Group 0: (Blocks 0-1543) Primary superblock at 0, Group descriptors at 1-1 Block bitmap at 1542 (+1542) Inode bitmap at 1543 (+1543) Inode table at 1511-1541 (+1511) 7 free blocks, 3 free inodes, 90 directories Free blocks: 2-8 Free inodes: 494-496 > veritysetup verify --data-blocks=1544 \ --hash-offset=6324224 \ test/483b65c07faaf8ee7f1f57c6d7de0eda9dfd61a34f03337926650b8178db5286 \ test/483b65c07faaf8ee7f1f57c6d7de0eda9dfd61a34f03337926650b8178db5286 \ 680edf0d62d42085f446efc20f34d02f5d21f4a2eec1ab79506809321105a13a ``` where no output from the verifysetup command means that everything is working as expected. * vendor new dependencies * create a new cli app for dmverity-vhd additionally combine dmverity-vhd and roothash into a single app with corresponding subcommands. Signed-off-by: Maksim An <[email protected]> Co-authored-by: Maksim An <[email protected]>
Adds a dm-verity integrity option to VHDs created from tar files.
tar2ext4 now takes an additional option to include tree information in the
generated VHD. Information will be stored as:
ext4 / verity superblock / merkle tree / VHD footer
assuming that all optional content is included.
At time, the salt value for all verity code is hardcoded. It could be
changed later as with the usage of a superblock, we no longer need
to know the salt on the use side as it will be obainted from the superblock.
The included
cmd/dmverity-vhd
cli app can be used for testing.create
takes the name of a docker image which it will downloadand for each layer, it will generate a VHD in the provided output directory.
The layer VHDs are named after the SHA for the given layer.
create
outputs the name of each vhd created.roothash
takes the nane of a docker image which it will downloadand for each layer, it will output the roothash for the layer.
For example:
where no output from the verifysetup command means that everything is working as expected.