diff options
author | Jonathon Reinhart <Jonathon.Reinhart@gmail.com> | 2020-06-30 03:48:06 +0300 |
---|---|---|
committer | Jonathon Reinhart <Jonathon.Reinhart@gmail.com> | 2020-06-30 04:14:20 +0300 |
commit | a96cde76279c16bda790f095520d67950cdb1b95 (patch) | |
tree | b65424be0857adc3abfd98d52119879f9114ddd4 | |
parent | fcaeb9907749cda47d82f8e43dc15b3a99879e8e (diff) |
Update Jail.removeAll() to remove directories in reverse order
Prior to this, in-place jail could not clean up nested directories
because it would try to remove the parents (which were necessarily
created first) before removing the parents, which would fail with a
"directory not empty" error.
The newly-added TestJailIntoCleansNestedDirs() would fail with this
error:
Can't delete jail "/tmp/my-jail-1593477629". Can't delete directory
in jail "/tmp/my-jail-1593477629/way": remove
/tmp/my-jail-1593477629/way: directory not empty
-rw-r--r-- | internal/jail/jail.go | 4 | ||||
-rw-r--r-- | internal/jail/jail_test.go | 28 |
2 files changed, 31 insertions, 1 deletions
diff --git a/internal/jail/jail.go b/internal/jail/jail.go index 22f22eac..a565fada 100644 --- a/internal/jail/jail.go +++ b/internal/jail/jail.go @@ -115,7 +115,9 @@ func (j *Jail) removeAll() error { } } - for _, dest := range j.directories { + // Iterate directories in reverse to remove children before parents + for i := len(j.directories) - 1; i >= 0; i-- { + dest := j.directories[i] if err := os.Remove(dest.path); err != nil { return fmt.Errorf("Can't delete directory in jail %q: %s", dest.path, err) } diff --git a/internal/jail/jail_test.go b/internal/jail/jail_test.go index 27282cae..6736816d 100644 --- a/internal/jail/jail_test.go +++ b/internal/jail/jail_test.go @@ -316,3 +316,31 @@ func TestJailIntoOnlyCleansSubpaths(t *testing.T) { _, err = os.Stat(jailPath) require.NoError(t, err, "/ in jail (corresponding to external directory) was removed") } + +func TestJailIntoCleansNestedDirs(t *testing.T) { + jailPath := tmpJailPath() + require.NoError(t, os.MkdirAll(jailPath, 0755)) + defer os.RemoveAll(jailPath) + + chroot := jail.Into(jailPath) + + // These need to be cleaned up in reverse order + chroot.MkDir("/way", 0755) + chroot.MkDir("/way/down", 0755) + chroot.MkDir("/way/down/here", 0755) + + require.NoError(t, chroot.Build()) + require.NoError(t, chroot.Dispose()) + + verify := func(inPath string) { + _, err := os.Stat(path.Join(jailPath, inPath)) + require.True(t, os.IsNotExist(err), "{} in jail was not removed", inPath) + } + + verify("/way") + verify("/way/down") + verify("/way/down/here") + + _, err := os.Stat(jailPath) + require.NoError(t, err, "/ in jail (corresponding to external directory) was removed") +} |