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

Prevent overwriting irregular files (cp, save, export commands) #1515

Conversation

sw-pschmied
Copy link
Contributor

@sw-pschmied sw-pschmied commented Nov 13, 2018

Signed-off-by: Philipp Schmied pschmied@schutzwerk.com

- What I did

This fixes #1514.

- How I did it

The function command.ValidateOutputPath was already present in cli/command/image/save.go. I've moved this to cli/command/utils.go in order to use this function to fix the issue for all three commands.

After that, I've added code to this existing function to use a new helper method called ValidateOutputPathFileMode which also resides in cli/command/utils.go. This is being used to check for irregular files/devices and returns an error in case an invalid target is being passed. This is now being called at the start of the functions implementing the cp, export and save commands. For cp operations to a container, the fix only uses the helper method mentioned above, so it's possible to unify this check for all three operations. The helper method also determines whether the target path points to a device or any other invalid/irregular file to display an error message accordingly.

Also, I've added test cases for all commands.

- How to verify it

  • Clone the cli master branch and compile a static docker binary
  • Pull an arbitrary docker image: docker pull ubuntu:latest
  • Invoke docker save ubuntu:latest -o /dev/random
  • Check the output of stat /dev/random indicating /dev/random is now a regular file
  • Perform the steps above using my PR and see that this operation is prevented, yielding failed to save image: invalid output path: "/dev/random" must be a directory or a regular file: Got a device.

- Description for the changelog

cp, save, export: Prevent overwriting irregular files

- A picture of a cute animal (not mandatory but encouraged)

20foup2

@codecov-io
Copy link

codecov-io commented Nov 13, 2018

Codecov Report

Merging #1515 into master will decrease coverage by 1.04%.
The diff coverage is 20%.

@@            Coverage Diff             @@
##           master    #1515      +/-   ##
==========================================
- Coverage   56.13%   55.08%   -1.05%     
==========================================
  Files         306      289      -17     
  Lines       20931    19389    -1542     
==========================================
- Hits        11749    10681    -1068     
+ Misses       8334     8015     -319     
+ Partials      848      693     -155

Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

Thanks! I only had a quick glance over this; left some comments/suggestions

dir := filepath.Dir(path)
if dir != "" && dir != "." {
if _, err := os.Stat(dir); os.IsNotExist(err) {
return errors.Errorf("unable to validate output path: directory %q does not exist", dir)
Copy link
Member

Choose a reason for hiding this comment

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

perhaps this should be "invalid output path" instead of "unable to validate output path" (because we were able to validate it, but it turned out to be an invalid path)

// (if the path exists and doesn't point to a directory)
if fileInfo, err := os.Stat(path); !os.IsNotExist(err) {
if !fileInfo.Mode().IsDir() && !fileInfo.Mode().IsRegular() {
return errors.Errorf("unable to validate output path: %q must be a directory or a regular file", path)
Copy link
Member

Choose a reason for hiding this comment

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

Same here for the "unable to validate.."

Also thinking if we should mention that the target is a "special" file (not sure)

@sw-pschmied
Copy link
Contributor Author

Hi and thanks for your feedback! Applying changes shortly.

@sw-pschmied sw-pschmied force-pushed the 1514-prevent-replacing-irregular-files branch 2 times, most recently from ee5b322 to 416087a Compare November 13, 2018 15:44
@sw-pschmied
Copy link
Contributor Author

I've pushed the changes, made some additional refactoring and updated my original post. The major changes to the post are:

  • Mention and describe the additional helper method ValidateOutputPathFileMode
  • The error message now contains information on the type of invalid target being passed (device / misc irregular file)

@sw-pschmied
Copy link
Contributor Author

ping @thaJeztah - is there else to change?

Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

Sorry for the delay; I've been a bit busy 😅

Left some comments inline, but feedback welcome, as usual 👍 Thanks!

cli/command/container/cp.go Outdated Show resolved Hide resolved
cli/command/container/cp.go Outdated Show resolved Hide resolved
cli/command/container/cp_test.go Outdated Show resolved Hide resolved
cli/command/container/export_test.go Outdated Show resolved Hide resolved
cli/command/utils.go Outdated Show resolved Hide resolved
// helper to `ValidateOutputPath`
func ValidateOutputPathFileMode(fileMode os.FileMode) error {
if fileMode&os.ModeDevice != 0 {
return errors.New("Got a device")
Copy link
Member

Choose a reason for hiding this comment

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

Should probably be lowercase for an error;

Suggested change
return errors.New("Got a device")
return errors.New("got a device")

cli/command/utils.go Outdated Show resolved Hide resolved
@sw-pschmied sw-pschmied force-pushed the 1514-prevent-replacing-irregular-files branch from 416087a to 7f8e0d1 Compare December 3, 2018 08:51
@sw-pschmied
Copy link
Contributor Author

Hi @thaJeztah, I've just pushed my changes. Thanks for the feedback!

@sw-pschmied
Copy link
Contributor Author

ping @thaJeztah :)

Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

LGTM! Sorry for the delay 😅

ping @vdemeester @silvin-lubecki PTAL

func ValidateOutputPathFileMode(fileMode os.FileMode) error {
if fileMode&os.ModeDevice != 0 {
return errors.New("got a device")
} else if fileMode&os.ModeIrregular != 0 {
Copy link
Contributor

Choose a reason for hiding this comment

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

very small nit: I think the else can be removed. The 2 if can even be transformed to a switch:

switch{
case fileMode&os.ModeDevice != 0:
    return errors.New("got a device")
case fileMode&os.ModeIrregular != 0:
    return errors.New("got an irregular file")
}
return nil

}

if err := ValidateOutputPathFileMode(fileInfo.Mode()); err != nil {
return errors.Wrap(err, fmt.Sprintf("invalid output path: %q must be a directory or a regular file", path))
Copy link
Contributor

Choose a reason for hiding this comment

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

small nit: use errors.Wrapf instead.

Copy link
Contributor

@silvin-lubecki silvin-lubecki left a comment

Choose a reason for hiding this comment

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

2 small nits but otherwise LGTM, thank you @sw-pschmied !

Signed-off-by: Philipp Schmied <pschmied@schutzwerk.com>
@sw-pschmied sw-pschmied force-pushed the 1514-prevent-replacing-irregular-files branch from 7f8e0d1 to 7632776 Compare February 7, 2019 08:19
@sw-pschmied
Copy link
Contributor Author

Thanks, I just pushed my changes @silvin-lubecki

Copy link
Collaborator

@vdemeester vdemeester left a comment

Choose a reason for hiding this comment

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

LGTM 🐯

@silvin-lubecki silvin-lubecki merged commit b1d2709 into docker:master Feb 7, 2019
@GordonTheTurtle GordonTheTurtle added this to the 19.03.0 milestone Feb 7, 2019
@silvin-lubecki
Copy link
Contributor

Thanks a lot @sw-pschmied for detecting this issue AND fixing it ! 👍👍

@sw-pschmied sw-pschmied deleted the 1514-prevent-replacing-irregular-files branch February 7, 2019 09:09
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.

cp, save and export allow replacing irregular files
6 participants