The path we're trying to remove doesn't exist after a successful
chroot+chdir because a / is only appended after pivot_root is
successful and so we can't cleanup anymore with the old path.
Also fix leaking .pivot_root dirs under /var/lib/docker/tmp/docker-builder*
on error.
Fix https://github.com/docker/docker/issues/22587
Introduced by https://github.com/docker/docker/pull/22506
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
| ... | ... |
@@ -43,7 +43,9 @@ func chroot(path string) (err error) {
|
| 43 | 43 |
} |
| 44 | 44 |
|
| 45 | 45 |
errCleanup := os.Remove(pivotDir) |
| 46 |
- if errCleanup != nil {
|
|
| 46 |
+ // pivotDir doesn't exist if pivot_root failed and chroot+chdir was successful |
|
| 47 |
+ // but we already cleaned it up on failed pivot_root |
|
| 48 |
+ if errCleanup != nil && !os.IsNotExist(errCleanup) {
|
|
| 47 | 49 |
errCleanup = fmt.Errorf("Error cleaning up after pivot: %v", errCleanup)
|
| 48 | 50 |
if err == nil {
|
| 49 | 51 |
err = errCleanup |
| ... | ... |
@@ -52,7 +54,10 @@ func chroot(path string) (err error) {
|
| 52 | 52 |
}() |
| 53 | 53 |
|
| 54 | 54 |
if err := syscall.PivotRoot(path, pivotDir); err != nil {
|
| 55 |
- // If pivot fails, fall back to the normal chroot |
|
| 55 |
+ // If pivot fails, fall back to the normal chroot after cleaning up temp dir for pivot_root |
|
| 56 |
+ if err := os.Remove(pivotDir); err != nil {
|
|
| 57 |
+ return fmt.Errorf("Error cleaning up after failed pivot: %v", err)
|
|
| 58 |
+ } |
|
| 56 | 59 |
return realChroot(path) |
| 57 | 60 |
} |
| 58 | 61 |
mounted = true |
| ... | ... |
@@ -84,7 +89,7 @@ func realChroot(path string) error {
|
| 84 | 84 |
return fmt.Errorf("Error after fallback to chroot: %v", err)
|
| 85 | 85 |
} |
| 86 | 86 |
if err := syscall.Chdir("/"); err != nil {
|
| 87 |
- return fmt.Errorf("Error chaning to new root after chroot: %v", err)
|
|
| 87 |
+ return fmt.Errorf("Error changing to new root after chroot: %v", err)
|
|
| 88 | 88 |
} |
| 89 | 89 |
return nil |
| 90 | 90 |
} |