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

metadata: Cached provider codepath may close file before attempting to truncate it #264

Closed
iaburton opened this issue Aug 1, 2024 · 1 comment · Fixed by #273
Closed
Labels
status/ready Merged and either fixed or implemented, and released or likely to be released soon. type/bug Something isn't working

Comments

@iaburton
Copy link

iaburton commented Aug 1, 2024

Version

0.11.0

Description

Hello again,

As mentioned in #247 I've updated to v0.11 and had been using the latest changes to the metadata service with the provided cache provider. It was working well until today when the service was restarted, at which point it attempted to update the mds blob.

It kept failing with truncate <file name>: file already closed

I noticed here that the decoder when passed the file is closing the file when it is finished. However just a few lines below, if the data is out of date and a file needs updating, then doTruncateCopyAndSeekStart is called which attempts to truncate the file that the decoder has already closed.

I tried passing the WithForceUpdate true option as a workaround but that fails with "invalid argument", I suspect this is because the file was Opened with READ only, and truncate is a write-level permission.

I think the suggested fix would be to not defer close the passed readcloser in the decoder (perhaps just pass it as a reader), and also open the file with OpenFile passing RW flags rather than just R flags. I can submit a PR if that helps.

Reproduction

Open an outdated MDS blob with the cached provider, default settings should reproduce it. For reference here is my abridged constructor, I pass a NewFunc because I need to be able to configure PermitZeroAAGUID to the underlying memory provider

wconf.MDS, err = cached.New(
			cached.WithClient(common.CleanHTTP()),
			cached.WithPath(conf.MDSPath),
			cached.WithNew(providerFunc(conf.MDSPermitZeroAAGUID)),
		)

// providerFunc
func providerFunc(permitZeroAAGUID bool) cached.NewFunc {
	// This is the same as the default in webauthn/metadata/providers/cached
	// but with a configurable permit zero.
	return func(mds *metadata.Metadata) (metadata.Provider, error) {
		return memory.New(
			memory.WithMetadata(mds.ToMap()),
			memory.WithValidateEntry(true),
			memory.WithValidateEntryPermitZeroAAGUID(permitZeroAAGUID),
			memory.WithValidateTrustAnchor(true),
			memory.WithValidateStatus(true),
		)
	}
}

Expectations

No response

Documentation

No response

@iaburton iaburton added status/needs-triage Issues that need to be triaged. type/potential-bug Potential Bugs labels Aug 1, 2024
@james-d-elliott
Copy link
Member

Thanks, pretty certain the fix is above.

@james-d-elliott james-d-elliott added type/bug Something isn't working status/ready Merged and either fixed or implemented, and released or likely to be released soon. and removed type/potential-bug Potential Bugs status/needs-triage Issues that need to be triaged. labels Aug 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status/ready Merged and either fixed or implemented, and released or likely to be released soon. type/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants