Skip to content
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

Fsverity content verification #10007

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

Jenkins-J
Copy link
Contributor

The Linux Kernel fs-verity feature can be utilized to verify the integrity of blob data in the content store. Enabling fs-verity on the blob data allows fs-verity to verify the integrity of the data at the time it is read. A read error will occur if fs-verity detects any accidental corruption of the data.

Here, containerd will enable fs-verity on the content blob files if it determines that both the kernel and the filesystem support fs-verity operations.

Addresses issue #3849 and issue #953.

@k8s-ci-robot
Copy link

Hi @Jenkins-J. Thanks for your PR.

I'm waiting for a containerd member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@Jenkins-J Jenkins-J force-pushed the fsverity-content-verification branch 4 times, most recently from e77afe7 to aa28f9e Compare March 27, 2024 15:14
@Jenkins-J Jenkins-J force-pushed the fsverity-content-verification branch from 26cc644 to 7ab2438 Compare March 27, 2024 18:38
@Jenkins-J Jenkins-J marked this pull request as ready for review March 27, 2024 18:52
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we have a unit test?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to clarify, would you like a unit test of the modified writer Commit method, the functions in the fsverity package, or both?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally both

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, I will work on creating those unit tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AkihiroSuda I've created some tests for the new functionality, please take a look. Thank you.

@AkihiroSuda
Copy link
Member

Please squash the commits


args.blockSize = uint32(blockSize)

_, _, errno := unix.Syscall(syscall.SYS_IOCTL, f.Fd(), uintptr(unix.FS_IOC_ENABLE_VERITY), uintptr(unsafe.Pointer(args)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

content.Provider needs to call FS_IOC_MEASURE_VERITY ?

Copy link
Contributor Author

@Jenkins-J Jenkins-J Mar 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fsverity module will automatically verify the integrity of the data on every read operation of the enabled file. If fsverity detects corruption, the read operation will return an error. The case where we would need to call FS_IOC_MEASURE_VERITY manually is if we wanted to detect intentional, malicious corruption of the blob data. In that case, we would measure the data after fsverity is enabled on the blob, safely store the known-good digest, then when the blob data a is read by the provider, call FS_IOC_MEASURE_VERITY again and compare the returned digest to the known-good value.

I'd be happy to implement this if the malicious corruption of blob data is a case containerd should cover.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it would be nice to cover malicious corruption.
Can be another PR.

Implement calls to the fsverity kernel module, allowing containerd to
enable fsverity on blob data in the content store. This causes fsverity
to veirfy the integrity of blob data when the blob is read.

Signed-off-by: James Jenkins <James.Jenkins@ibm.com>
@Jenkins-J Jenkins-J force-pushed the fsverity-content-verification branch from 7ab2438 to 36e1ad4 Compare March 28, 2024 15:23
@Jenkins-J Jenkins-J force-pushed the fsverity-content-verification branch from efc8f9b to bf8dc69 Compare April 11, 2024 15:54
@fuweid
Copy link
Member

fuweid commented Apr 19, 2024

HI @AkihiroSuda shall we target this to v2.1 release? It's good feature but we still have pending work items in 2.0, like transfer service migration for CRI.

@AkihiroSuda
Copy link
Member

HI @AkihiroSuda shall we target this to v2.1 release?

I think this is safe to have in v2.0, but can be postponed to v2.1 if you have a concern.

It's good feature but we still have pending work items in 2.0, like transfer service migration for CRI.

I'm not sure we can complete this in v2.0, as we will retain schema1 (now disabled by default).
Can we discuss this in another GitHub issue?

@fuweid
Copy link
Member

fuweid commented Apr 19, 2024

I think this is safe to have in v2.0, but can be postponed to v2.1 if you have a concern.

It's in content store code path. But yeah, it looks good and safe to have in 2.0.
Just want to commit existing pending patches first.

I'm not sure we can complete this in v2.0, as we will retain schema1 (now disabled by default). Can we discuss this in another GitHub issue?

Sure.

defer func() {
err := m.Close()
if err != nil {
fmt.Printf("could not close mountinfo\n")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
fmt.Printf("could not close mountinfo\n")
t.Fatalf("could not close mountinfo: %v", err)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AkihiroSuda This change is in a helper function, resolveDevicePath, which does not have access to the testing.T variable t. I've modified it so now the appropriate error message is returned from this function. I can pass the variable t as a parameter to these helper functions instead if you believe the code would be more readable that way.

@Jenkins-J Jenkins-J force-pushed the fsverity-content-verification branch 3 times, most recently from a5d7cda to 5a9bd0d Compare April 25, 2024 17:02
Signed-off-by: James Jenkins <James.Jenkins@ibm.com>
@Jenkins-J Jenkins-J force-pushed the fsverity-content-verification branch from 5a9bd0d to 9ba5d37 Compare April 25, 2024 17:07
@fuweid
Copy link
Member

fuweid commented Apr 26, 2024

Run out of bandwidth this week. Will take a look this after travel.


func TestIsEnabled(t *testing.T) {

testDir := filepath.Join(t.TempDir(), "content")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can use truncate and mkfs.ext4 -O verity to create testable environment for this function.
verity is not default option in most distros so it would help.
It can be handled in the follow-up.

integritySupported bool
supportErr error
)
if integritySupported, supportErr = fsverity.IsSupported(w.s.root); integritySupported {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the IsSupported cache should be handled in content local plugin.
The fsverity.IsSupported is just handled once. If we change the input from A to B, the cache might not be correct.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the implementation to cache IsSupported value in the content plugin.

Cache the result of the IsSupported fsverity
method in the content plugin instead of in the
fsverity package.

Signed-off-by: James Jenkins <James.Jenkins@ibm.com>
startedAt time.Time
updatedAt time.Time
once sync.Once
integritySupported bool
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about moving this to store struct?

type store struct {
      root string
      ls LabelStore
      
      integritySupported bool
}

So that we can just run fsverity.IsSupported once and all the writers from same store can share it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, that makes more sense now. I've made the change.

}

digestFile.Close()
defer os.RemoveAll(integrityDir)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move this line to L57.

return s, err
}

integrityDir := filepath.Join(rootPath, "integrity")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can rename this to .fsverity-check by os.MkdirTemp. So, the node admin will know it's tempdir to verify something.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Thank you for the suggestion.

Move cached fsverity integrity supported value
from the local content writer to the local
content store.

Signed-off-by: James Jenkins <James.Jenkins@ibm.com>
Clean up fsverity IsSupproted function, improving
readability.

Signed-off-by: James Jenkins <James.Jenkins@ibm.com>
Copy link
Member

@fuweid fuweid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@fuweid fuweid requested a review from AkihiroSuda May 9, 2024 08:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants