moby/pkg
Sebastiaan van Stijn 7114360901
pkg/idtools: mkdirAs(): fix infinite loops and repeated "chown"
This fixes an inifinite loop in mkdirAs(), used by `MkdirAllAndChown`,
`MkdirAndChown`, and `MkdirAllAndChownNew`, as well as directories being
chown'd multiple times when relative paths are used.

The for loop in this function was incorrectly assuming that;

1. `filepath.Dir()` would always return the parent directory of any given path
2. traversing any given path to ultimately result in "/"

While this is correct for absolute and "cleaned" paths, both assumptions are
incorrect in some variations of "path";

1. for paths with a trailing path-separator ("some/path/"), or dot ("."),
   `filepath.Dir()` considers the (implicit) "." to be a location _within_ the
   directory, and returns "some/path" as ("parent") directory. This resulted
   in the path itself to be included _twice_ in the list of paths to chown.
2. for relative paths ("./some-path", "../some-path"), "traversing" the path
   would never end in "/", causing the for loop to run indefinitely:

    ```go
    // walk back to "/" looking for directories which do not exist
    // and add them to the paths array for chown after creation
    dirPath := path
    for {
        dirPath = filepath.Dir(dirPath)
        if dirPath == "/" {
            break
        }
        if _, err := os.Stat(dirPath); err != nil && os.IsNotExist(err) {
            paths = append(paths, dirPath)
        }
    }
    ```

A _partial_ mitigation for this would be to use `filepath.Clean()` before using
the path (while `filepath.Dir()` _does_ call `filepath.Clean()`, it only does so
_after_ some processing, so only cleans the result). Doing so would prevent the
double chown from happening, but would not prevent the "final" path to be "."
or ".." (in the relative path case), still causing an infinite loop, or
additional checks for "." / ".." to be needed.

| path           | filepath.Dir(path) | filepath.Dir(filepath.Clean(path)) |
|----------------|--------------------|------------------------------------|
| some-path      | .                  | .                                  |
| ./some-path    | .                  | .                                  |
| ../some-path   | ..                 | ..                                 |
| some/path/     | some/path          | some                               |
| ./some/path/   | some/path          | some                               |
| ../some/path/  | ../some/path       | ../some                            |
| some/path/.    | some/path          | some                               |
| ./some/path/.  | some/path          | some                               |
| ../some/path/. | ../some/path       | ../some                            |
| /some/path/    | /some/path         | /some                              |
| /some/path/.   | /some/path         | /some                              |

Instead, this patch adds a `filepath.Abs()` to the function, so make sure that
paths are both cleaned, and not resulting in an infinite loop.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 1e13247d6d)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-09-27 21:59:47 +02:00
..
aaparser Also trim "~..." from AppArmor versions 2020-10-08 17:03:51 -07:00
archive replace pkg/system Sequential funcs with moby/sys/sequential 2022-08-30 09:34:33 +02:00
authorization refactor: move from io/ioutil to io and os package 2021-08-27 14:56:57 +08:00
broadcaster Various code-cleanup 2018-05-23 17:50:54 +02:00
capabilities Add more import comments 2019-04-10 16:59:33 +02:00
chrootarchive gofmt GoDoc comments with go1.19 2022-07-13 22:42:29 +02:00
containerfs Finish refactor of UID/GID usage to a new struct 2022-03-14 16:28:57 -04:00
devicemapper golangci-lint: update to v1.49.0 2022-09-26 11:58:07 +02:00
directory fix unclosed file-handles in tests 2022-05-31 21:53:38 +02:00
dmesg Use Klogctl from x/sys/unix to read Linux kernel log 2019-08-22 08:25:13 +02:00
fileutils Avoid platform-specific NewPatternMatcher function in TestCompile 2022-01-20 09:08:16 -08:00
fsutils refactor: move from io/ioutil to io and os package 2021-08-27 14:56:57 +08:00
homedir Update to Go 1.17.0, and gofmt with Go 1.17 2021-08-24 23:33:27 +02:00
idtools pkg/idtools: mkdirAs(): fix infinite loops and repeated "chown" 2022-09-27 21:59:47 +02:00
ioutils Merge pull request #42543 from rainrambler/patch-1 2021-09-01 13:26:30 +02:00
jsonmessage test: use T.Setenv to set env vars in tests 2022-04-23 17:44:16 +08:00
longpath Add canonical import comment 2018-02-05 16:51:57 -05:00
loopback Update to Go 1.17.0, and gofmt with Go 1.17 2021-08-24 23:33:27 +02:00
namesgenerator namesgenerator: remove Valentina Tereshkova 2022-09-06 13:58:28 +02:00
parsers Merge pull request #43806 from thaJeztah/22.06_backport_fix_import 2022-07-14 08:19:15 -07:00
pidfile refactor: move from io/ioutil to io and os package 2021-08-27 14:56:57 +08:00
platform all: use unix.ByteSliceToString for utsname fields 2022-05-18 17:13:20 -07:00
plugingetter Move plugin client to separate interface 2018-05-30 15:22:10 -04:00
plugins gofmt GoDoc comments with go1.19 2022-07-13 22:42:29 +02:00
pools bump gotest.tools v3.0.1 for compatibility with Go 1.14 2020-02-11 00:06:42 +01:00
progress refactor: move from io/ioutil to io and os package 2021-08-27 14:56:57 +08:00
pubsub docker stats: fix 'panic: close of closed channel' 2020-10-24 11:48:56 +08:00
reexec Update to Go 1.17.0, and gofmt with Go 1.17 2021-08-24 23:33:27 +02:00
signal pkg/signal: remove DefaultStopSignal const 2021-08-11 10:31:29 +02:00
stack all: replace strings.Replace with strings.ReplaceAll 2022-05-09 19:45:40 +08:00
stdcopy refactor: move from io/ioutil to io and os package 2021-08-27 14:56:57 +08:00
streamformatter bump gotest.tools v3.0.1 for compatibility with Go 1.14 2020-02-11 00:06:42 +01:00
stringid Entropy cannot be saved 2019-06-07 11:54:45 +01:00
sysinfo Fix constant WARNING: No swap limit support on cgroup v2 hosts 2022-05-27 10:51:54 +09:00
system replace pkg/system Sequential funcs with moby/sys/sequential 2022-08-30 09:34:33 +02:00
tailfile refactor: move from io/ioutil to io and os package 2021-08-27 14:56:57 +08:00
tarsum pkg/archive: audit gosec file-traversal lints 2022-02-18 15:42:22 -05:00
truncindex Entropy cannot be saved 2019-06-07 11:54:45 +01:00
urlutil pkg/urlutil: deprecate, and move to builder/remotecontext/urlutil 2022-04-12 19:58:05 +02:00
useragent Add canonical import comment 2018-02-05 16:51:57 -05:00
README.md Rename a few docker to moby 2017-10-25 13:56:12 +02:00

pkg/ is a collection of utility packages used by the Moby project without being specific to its internals.

Utility packages are kept separate from the moby core codebase to keep it as small and concise as possible. If some utilities grow larger and their APIs stabilize, they may be moved to their own repository under the Moby organization, to facilitate re-use by other projects. However that is not the priority.

The directory pkg is named after the same directory in the camlistore project. Since Brad is a core Go maintainer, we thought it made sense to copy his methods for organizing Go code :) Thanks Brad!

Because utility packages are small and neatly separated from the rest of the codebase, they are a good place to start for aspiring maintainers and contributors. Get in touch if you want to help maintain them!