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

cmd/snap-update-ns: improve wording in many errors #5272

Merged
merged 3 commits into from
Jun 7, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 1 addition & 9 deletions cmd/snap-update-ns/change.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,7 @@ func (c *Change) createPath(path string, pokeHoles bool, sec *Secure) ([]*Change
case "file":
err = sec.MkfileAll(path, mode, uid, gid)
case "symlink":
target := c.Entry.XSnapdSymlink()
if target == "" {
err = fmt.Errorf("cannot create symlink with empty target")
} else {
err = sec.MksymlinkAll(path, mode, uid, gid, target)
}
err = sec.MksymlinkAll(path, mode, uid, gid, c.Entry.XSnapdSymlink())
}
if err2, ok := err.(*ReadOnlyFsError); ok && pokeHoles {
// If the writing failed because the underlying file-system is read-only
Expand All @@ -116,9 +111,6 @@ func (c *Change) createPath(path string, pokeHoles bool, sec *Secure) ([]*Change
// performed the hole poking and thus additional changes must be nil.
_, err = c.createPath(path, false, sec)
}
} else if err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

That's probably ok and means we will not decorate the error with extra message and just return it as is; is this intended?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, as a part of this change the errors produced by things called by createPath internally now return appropriate error messages by themselves.

// TODO: remove this line and teach Mk* functions to return error containing the full path.
err = fmt.Errorf("cannot create path %q: %s", path, err)
}
return changes, err
}
Expand Down
22 changes: 11 additions & 11 deletions cmd/snap-update-ns/change_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ func (s *changeSuite) TestPerformFilesystemMountWithoutMountPointWithErrors(c *C
s.sys.InsertFault(`mkdirat 3 "target" 0755`, errTesting)
chg := &update.Change{Action: update.Mount, Entry: osutil.MountEntry{Name: "device", Dir: "/target", Type: "type"}}
synth, err := chg.Perform(s.sec)
c.Assert(err, ErrorMatches, `cannot create path "/target": cannot create directory "target": testing`)
c.Assert(err, ErrorMatches, `cannot create directory "/target": testing`)
c.Assert(synth, HasLen, 0)
c.Assert(s.sys.Calls(), DeepEquals, []string{
`lstat "/target"`,
Expand Down Expand Up @@ -517,7 +517,7 @@ func (s *changeSuite) TestPerformFilesystemMountWithoutMountPointAndReadOnlyBase

chg := &update.Change{Action: update.Mount, Entry: osutil.MountEntry{Name: "device", Dir: "/rofs/target", Type: "type"}}
synth, err := chg.Perform(s.sec)
c.Assert(err, ErrorMatches, `cannot create writable mimic over "/rofs": cannot create path "/tmp/.snap/rofs": cannot create directory ".snap": testing`)
c.Assert(err, ErrorMatches, `cannot create writable mimic over "/rofs": cannot create directory "/tmp/.snap": testing`)
c.Assert(synth, HasLen, 0)
c.Assert(s.sys.Calls(), DeepEquals, []string{
// sniff mount target
Expand Down Expand Up @@ -780,7 +780,7 @@ func (s *changeSuite) TestPerformDirectoryBindMountWithoutMountPointWithErrors(c
s.sys.InsertFault(`mkdirat 3 "target" 0755`, errTesting)
chg := &update.Change{Action: update.Mount, Entry: osutil.MountEntry{Name: "/source", Dir: "/target", Options: []string{"bind"}}}
synth, err := chg.Perform(s.sec)
c.Assert(err, ErrorMatches, `cannot create path "/target": cannot create directory "target": testing`)
c.Assert(err, ErrorMatches, `cannot create directory "/target": testing`)
c.Assert(synth, HasLen, 0)
c.Assert(s.sys.Calls(), DeepEquals, []string{
`lstat "/target"`,
Expand All @@ -797,7 +797,7 @@ func (s *changeSuite) TestPerformDirectoryBindMountWithoutMountSourceWithErrors(
s.sys.InsertOsLstatResult(`lstat "/target"`, testutil.FileInfoDir)
chg := &update.Change{Action: update.Mount, Entry: osutil.MountEntry{Name: "/source", Dir: "/target", Options: []string{"bind"}}}
synth, err := chg.Perform(s.sec)
c.Assert(err, ErrorMatches, `cannot create path "/source": cannot create directory "source": testing`)
c.Assert(err, ErrorMatches, `cannot create directory "/source": testing`)
c.Assert(synth, HasLen, 0)
c.Assert(s.sys.Calls(), DeepEquals, []string{
`lstat "/target"`,
Expand Down Expand Up @@ -925,7 +925,7 @@ func (s *changeSuite) TestPerformDirectoryBindMountWithoutMountSourceAndReadOnly

chg := &update.Change{Action: update.Mount, Entry: osutil.MountEntry{Name: "/rofs/source", Dir: "/target", Options: []string{"bind"}}}
synth, err := chg.Perform(s.sec)
c.Assert(err, ErrorMatches, `cannot create path "/rofs/source": cannot operate on read-only filesystem at /rofs`)
c.Assert(err, ErrorMatches, `cannot operate on read-only filesystem at /rofs`)
c.Assert(synth, HasLen, 0)
c.Assert(s.sys.Calls(), DeepEquals, []string{
`lstat "/target"`, // -> directory
Expand Down Expand Up @@ -1235,7 +1235,7 @@ func (s *changeSuite) TestPerformFileBindMountWithoutMountPointWithErrors(c *C)
s.sys.InsertFault(`openat 3 "target" O_NOFOLLOW|O_CLOEXEC|O_CREAT|O_EXCL 0755`, errTesting)
chg := &update.Change{Action: update.Mount, Entry: osutil.MountEntry{Name: "/source", Dir: "/target", Options: []string{"bind", "x-snapd.kind=file"}}}
synth, err := chg.Perform(s.sec)
c.Assert(err, ErrorMatches, `cannot create path "/target": cannot open file "target": testing`)
c.Assert(err, ErrorMatches, `cannot open file "/target": testing`)
c.Assert(synth, HasLen, 0)
c.Assert(s.sys.Calls(), DeepEquals, []string{
`lstat "/target"`,
Expand Down Expand Up @@ -1284,7 +1284,7 @@ func (s *changeSuite) TestPerformFileBindMountWithoutMountSourceWithErrors(c *C)
s.sys.InsertOsLstatResult(`lstat "/target"`, testutil.FileInfoFile)
chg := &update.Change{Action: update.Mount, Entry: osutil.MountEntry{Name: "/source", Dir: "/target", Options: []string{"bind", "x-snapd.kind=file"}}}
synth, err := chg.Perform(s.sec)
c.Assert(err, ErrorMatches, `cannot create path "/source": cannot open file "source": testing`)
c.Assert(err, ErrorMatches, `cannot open file "/source": testing`)
c.Assert(synth, HasLen, 0)
c.Assert(s.sys.Calls(), DeepEquals, []string{
`lstat "/target"`,
Expand Down Expand Up @@ -1535,7 +1535,7 @@ func (s *changeSuite) TestPerformCreateSymlinkWithError(c *C) {
s.sys.InsertFault(`symlinkat "/oldname" 3 "name"`, errTesting)
chg := &update.Change{Action: update.Mount, Entry: osutil.MountEntry{Name: "unused", Dir: "/name", Options: []string{"x-snapd.kind=symlink", "x-snapd.symlink=/oldname"}}}
synth, err := chg.Perform(s.sec)
c.Assert(err, ErrorMatches, `cannot create path "/name": cannot create symlink "name": testing`)
c.Assert(err, ErrorMatches, `cannot create symlink "/name": testing`)
c.Assert(synth, HasLen, 0)
c.Assert(s.sys.Calls(), DeepEquals, []string{
`lstat "/name"`,
Expand All @@ -1550,7 +1550,7 @@ func (s *changeSuite) TestPerformCreateSymlinkWithNoTargetError(c *C) {
s.sys.InsertFault(`lstat "/name"`, syscall.ENOENT)
chg := &update.Change{Action: update.Mount, Entry: osutil.MountEntry{Name: "unused", Dir: "/name", Options: []string{"x-snapd.kind=symlink", "x-snapd.symlink="}}}
synth, err := chg.Perform(s.sec)
c.Assert(err, ErrorMatches, `cannot create path "/name": cannot create symlink with empty target`)
c.Assert(err, ErrorMatches, `cannot create symlink with empty target: "/name"`)
c.Assert(synth, HasLen, 0)
c.Assert(s.sys.Calls(), DeepEquals, []string{
`lstat "/name"`,
Expand Down Expand Up @@ -1582,7 +1582,7 @@ func (s *changeSuite) TestPerformCreateSymlinkWithoutBaseDirWithErrors(c *C) {
s.sys.InsertFault(`mkdirat 3 "base" 0755`, errTesting)
chg := &update.Change{Action: update.Mount, Entry: osutil.MountEntry{Name: "unused", Dir: "/base/name", Options: []string{"x-snapd.kind=symlink", "x-snapd.symlink=/oldname"}}}
synth, err := chg.Perform(s.sec)
c.Assert(err, ErrorMatches, `cannot create path "/base/name": cannot create directory "base": testing`)
c.Assert(err, ErrorMatches, `cannot create directory "/base": testing`)
c.Assert(synth, HasLen, 0)
c.Assert(s.sys.Calls(), DeepEquals, []string{
`lstat "/base/name"`,
Expand Down Expand Up @@ -1718,7 +1718,7 @@ func (s *changeSuite) TestPerformCreateSymlinkWithBadSymlinkPresent(c *C) {
s.sys.InsertReadlinkatResult(`readlinkat 4 "" <ptr>`, "/evil")
chg := &update.Change{Action: update.Mount, Entry: osutil.MountEntry{Name: "unused", Dir: "/name", Options: []string{"x-snapd.kind=symlink", "x-snapd.symlink=/oldname"}}}
synth, err := chg.Perform(s.sec)
c.Assert(err, ErrorMatches, `cannot create path "/name": cannot create symbolic link "name": existing symbolic link in the way`)
c.Assert(err, ErrorMatches, `cannot create symbolic link "/name": existing symbolic link in the way`)
c.Assert(synth, HasLen, 0)
c.Assert(s.sys.Calls(), DeepEquals, []string{
`lstat "/name"`,
Expand Down
30 changes: 16 additions & 14 deletions cmd/snap-update-ns/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,7 @@ func (sec *Secure) CheckTrespassing(dirFd int, dirName string, name string) erro
func (sec *Secure) OpenPath(path string) (int, error) {
iter, err := NewPathIterator(path)
if err != nil {
// TODO: Reword the error and adjust the tests.
return -1, fmt.Errorf("cannot split unclean path %q", path)
return -1, fmt.Errorf("cannot open path: %s", err)
}
if !filepath.IsAbs(iter.Path()) {
return -1, fmt.Errorf("path %v is not absolute", iter.Path())
Expand Down Expand Up @@ -188,20 +187,20 @@ func (sec *Secure) MkDir(dirFd int, dirName string, name string, perm os.FileMod
// need to poke the hole.
return -1, &ReadOnlyFsError{Path: dirName}
default:
return -1, fmt.Errorf("cannot create directory %q: %v", name, err)
return -1, fmt.Errorf("cannot create directory %q: %v", filepath.Join(dirName, name), err)
}
}
newFd, err := sysOpenat(dirFd, name, openFlags, 0)
if err != nil {
return -1, fmt.Errorf("cannot open directory %q: %v", name, err)
return -1, fmt.Errorf("cannot open directory %q: %v", filepath.Join(dirName, name), err)
}
if made {
// Chown each segment that we made.
if err := sysFchown(newFd, uid, gid); err != nil {
// Close the FD we opened if we fail here since the caller will get
// an error and won't assume responsibility for the FD.
sysClose(newFd)
return -1, fmt.Errorf("cannot chown directory %q to %d.%d: %v", name, uid, gid, err)
return -1, fmt.Errorf("cannot chown directory %q to %d.%d: %v", filepath.Join(dirName, name), uid, gid, err)
}
}
return newFd, err
Expand Down Expand Up @@ -231,7 +230,7 @@ func (sec *Secure) MkFile(dirFd int, dirName string, name string, perm os.FileMo
// If the file exists then just open it without O_CREAT and O_EXCL
newFd, err = sysOpenat(dirFd, name, openFlags, 0)
if err != nil {
return fmt.Errorf("cannot open file %q: %v", name, err)
return fmt.Errorf("cannot open file %q: %v", filepath.Join(dirName, name), err)
}
made = false
case syscall.EROFS:
Expand All @@ -240,15 +239,15 @@ func (sec *Secure) MkFile(dirFd int, dirName string, name string, perm os.FileMo
// need to poke the hole.
return &ReadOnlyFsError{Path: dirName}
default:
return fmt.Errorf("cannot open file %q: %v", name, err)
return fmt.Errorf("cannot open file %q: %v", filepath.Join(dirName, name), err)
}
}
defer sysClose(newFd)

if made {
// Chown the file if we made it.
if err := sysFchown(newFd, uid, gid); err != nil {
return fmt.Errorf("cannot chown file %q to %d.%d: %v", name, uid, gid, err)
return fmt.Errorf("cannot chown file %q to %d.%d: %v", filepath.Join(dirName, name), uid, gid, err)
}
}

Expand All @@ -271,24 +270,24 @@ func (sec *Secure) MkSymlink(dirFd int, dirName string, name string, oldname str
// Maybe it's the symlink we were hoping to create.
objFd, err = sysOpenat(dirFd, name, syscall.O_CLOEXEC|sys.O_PATH|syscall.O_NOFOLLOW, 0)
if err != nil {
return fmt.Errorf("cannot open existing file %q: %v", name, err)
return fmt.Errorf("cannot open existing file %q: %v", filepath.Join(dirName, name), err)
}
var statBuf syscall.Stat_t
err = sysFstat(objFd, &statBuf)
if err != nil {
return fmt.Errorf("cannot inspect existing file %q: %v", name, err)
return fmt.Errorf("cannot inspect existing file %q: %v", filepath.Join(dirName, name), err)
}
if statBuf.Mode&syscall.S_IFMT != syscall.S_IFLNK {
return fmt.Errorf("cannot create symbolic link %q: existing file in the way", name)
return fmt.Errorf("cannot create symbolic link %q: existing file in the way", filepath.Join(dirName, name))
}
var n int
buf := make([]byte, len(oldname)+2)
n, err = sysReadlinkat(objFd, "", buf)
if err != nil {
return fmt.Errorf("cannot read symbolic link %q: %v", name, err)
return fmt.Errorf("cannot read symbolic link %q: %v", filepath.Join(dirName, name), err)
}
if string(buf[:n]) != oldname {
return fmt.Errorf("cannot create symbolic link %q: existing symbolic link in the way", name)
return fmt.Errorf("cannot create symbolic link %q: existing symbolic link in the way", filepath.Join(dirName, name))
}
return nil
case syscall.EROFS:
Expand All @@ -297,7 +296,7 @@ func (sec *Secure) MkSymlink(dirFd int, dirName string, name string, oldname str
// need to poke the hole.
return &ReadOnlyFsError{Path: dirName}
default:
return fmt.Errorf("cannot create symlink %q: %v", name, err)
return fmt.Errorf("cannot create symlink %q: %v", filepath.Join(dirName, name), err)
}
}

Expand Down Expand Up @@ -399,6 +398,9 @@ func (sec *Secure) MksymlinkAll(path string, perm os.FileMode, uid sys.UserID, g
if strings.HasSuffix(path, "/") {
return fmt.Errorf("cannot create non-file path: %q", path)
}
if oldname == "" {
return fmt.Errorf("cannot create symlink with empty target: %q", path)
}

base, name := filepath.Split(path)
base = filepath.Clean(base) // Needed to chomp the trailing slash.
Expand Down
26 changes: 13 additions & 13 deletions cmd/snap-update-ns/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ func (s *utilsSuite) TestSecureMkdirAllExistingDirsDontChown(c *C) {
func (s *utilsSuite) TestSecureMkdirAllMkdiratError(c *C) {
s.sys.InsertFault(`mkdirat 3 "abs" 0755`, errTesting)
err := s.sec.MkdirAll("/abs", 0755, 123, 456)
c.Assert(err, ErrorMatches, `cannot create directory "abs": testing`)
c.Assert(err, ErrorMatches, `cannot create directory "/abs": testing`)
c.Assert(s.sys.Calls(), DeepEquals, []string{
`open "/" O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY 0`, // -> 3
`mkdirat 3 "abs" 0755`,
Expand All @@ -189,7 +189,7 @@ func (s *utilsSuite) TestSecureMkdirAllMkdiratError(c *C) {
func (s *utilsSuite) TestSecureMkdirAllFchownError(c *C) {
s.sys.InsertFault(`fchown 4 123 456`, errTesting)
err := s.sec.MkdirAll("/path", 0755, 123, 456)
c.Assert(err, ErrorMatches, `cannot chown directory "path" to 123.456: testing`)
c.Assert(err, ErrorMatches, `cannot chown directory "/path" to 123.456: testing`)
c.Assert(s.sys.Calls(), DeepEquals, []string{
`open "/" O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY 0`, // -> 3
`mkdirat 3 "path" 0755`,
Expand All @@ -214,7 +214,7 @@ func (s *utilsSuite) TestSecureMkdirAllOpenRootError(c *C) {
func (s *utilsSuite) TestSecureMkdirAllOpenError(c *C) {
s.sys.InsertFault(`openat 3 "abs" O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY 0`, errTesting)
err := s.sec.MkdirAll("/abs/path", 0755, 123, 456)
c.Assert(err, ErrorMatches, `cannot open directory "abs": testing`)
c.Assert(err, ErrorMatches, `cannot open directory "/abs": testing`)
c.Assert(s.sys.Calls(), DeepEquals, []string{
`open "/" O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY 0`, // -> 3
`mkdirat 3 "abs" 0755`,
Expand Down Expand Up @@ -575,7 +575,7 @@ func (s *utilsSuite) TestSecureMkfileAllOpenat2ndError(c *C) {
s.sys.InsertFault(`openat 3 "abs" O_NOFOLLOW|O_CLOEXEC|O_CREAT|O_EXCL 0755`, syscall.EEXIST)
s.sys.InsertFault(`openat 3 "abs" O_NOFOLLOW|O_CLOEXEC 0`, errTesting)
err := s.sec.MkfileAll("/abs", 0755, 123, 456)
c.Assert(err, ErrorMatches, `cannot open file "abs": testing`)
c.Assert(err, ErrorMatches, `cannot open file "/abs": testing`)
c.Assert(s.sys.Calls(), DeepEquals, []string{
`open "/" O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY 0`, // -> 3
`openat 3 "abs" O_NOFOLLOW|O_CLOEXEC|O_CREAT|O_EXCL 0755`, // -> EEXIST
Expand All @@ -588,7 +588,7 @@ func (s *utilsSuite) TestSecureMkfileAllOpenat2ndError(c *C) {
func (s *utilsSuite) TestSecureMkfileAllOpenatError(c *C) {
s.sys.InsertFault(`openat 3 "abs" O_NOFOLLOW|O_CLOEXEC|O_CREAT|O_EXCL 0755`, errTesting)
err := s.sec.MkfileAll("/abs", 0755, 123, 456)
c.Assert(err, ErrorMatches, `cannot open file "abs": testing`)
c.Assert(err, ErrorMatches, `cannot open file "/abs": testing`)
c.Assert(s.sys.Calls(), DeepEquals, []string{
`open "/" O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY 0`, // -> 3
`openat 3 "abs" O_NOFOLLOW|O_CLOEXEC|O_CREAT|O_EXCL 0755`, // -> err
Expand All @@ -600,7 +600,7 @@ func (s *utilsSuite) TestSecureMkfileAllOpenatError(c *C) {
func (s *utilsSuite) TestSecureMkfileAllFchownError(c *C) {
s.sys.InsertFault(`fchown 4 123 456`, errTesting)
err := s.sec.MkfileAll("/path", 0755, 123, 456)
c.Assert(err, ErrorMatches, `cannot chown file "path" to 123.456: testing`)
c.Assert(err, ErrorMatches, `cannot chown file "/path" to 123.456: testing`)
c.Assert(s.sys.Calls(), DeepEquals, []string{
`open "/" O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY 0`, // -> 3
`openat 3 "path" O_NOFOLLOW|O_CLOEXEC|O_CREAT|O_EXCL 0755`, // -> 4
Expand All @@ -624,7 +624,7 @@ func (s *utilsSuite) TestSecureMkfileAllOpenRootError(c *C) {
func (s *utilsSuite) TestSecureMkfileAllOpenError(c *C) {
s.sys.InsertFault(`openat 3 "abs" O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY 0`, errTesting)
err := s.sec.MkfileAll("/abs/path", 0755, 123, 456)
c.Assert(err, ErrorMatches, `cannot open directory "abs": testing`)
c.Assert(err, ErrorMatches, `cannot open directory "/abs": testing`)
c.Assert(s.sys.Calls(), DeepEquals, []string{
`open "/" O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY 0`, // -> 3
`mkdirat 3 "abs" 0755`,
Expand Down Expand Up @@ -683,21 +683,21 @@ func (s *realSystemSuite) TestSecureMksymlinkAllForReal(c *C) {

// Create a different symlink and see that it fails now
err = s.sec.MksymlinkAll(f1, 0755, sys.FlagID, sys.FlagID, "other")
c.Assert(err, ErrorMatches, `cannot create symbolic link "symlink": existing symbolic link in the way`)
c.Assert(err, ErrorMatches, `cannot create symbolic link ".*/symlink": existing symbolic link in the way`)

// Create an file and check that it clashes with a symlink we attempt to create.
f2 := filepath.Join(d, "file")
err = s.sec.MkfileAll(f2, 0755, sys.FlagID, sys.FlagID)
c.Assert(err, IsNil)
err = s.sec.MksymlinkAll(f2, 0755, sys.FlagID, sys.FlagID, "oldname")
c.Assert(err, ErrorMatches, `cannot create symbolic link "file": existing file in the way`)
c.Assert(err, ErrorMatches, `cannot create symbolic link ".*/file": existing file in the way`)

// Create an file and check that it clashes with a symlink we attempt to create.
f3 := filepath.Join(d, "dir")
err = s.sec.MkdirAll(f3, 0755, sys.FlagID, sys.FlagID)
c.Assert(err, IsNil)
err = s.sec.MksymlinkAll(f3, 0755, sys.FlagID, sys.FlagID, "oldname")
c.Assert(err, ErrorMatches, `cannot create symbolic link "dir": existing file in the way`)
c.Assert(err, ErrorMatches, `cannot create symbolic link ".*/dir": existing file in the way`)

err = s.sec.MksymlinkAll("/", 0755, sys.FlagID, sys.FlagID, "oldname")
c.Assert(err, ErrorMatches, `cannot create non-file path: "/"`)
Expand Down Expand Up @@ -791,15 +791,15 @@ func (s *realSystemSuite) TestSecureOpenPathUncleanPath(c *C) {

fd, err := s.sec.OpenPath(base + "//test")
c.Check(fd, Equals, -1)
c.Check(err, ErrorMatches, "cannot split unclean path .*")
c.Check(err, ErrorMatches, `cannot open path: cannot iterate over unclean path ".*//test"`)

fd, err = s.sec.OpenPath(base + "/./test")
c.Check(fd, Equals, -1)
c.Check(err, ErrorMatches, "cannot split unclean path .*")
c.Check(err, ErrorMatches, `cannot open path: cannot iterate over unclean path ".*/./test"`)

fd, err = s.sec.OpenPath(base + "/test/../test")
c.Check(fd, Equals, -1)
c.Check(err, ErrorMatches, "cannot split unclean path .*")
c.Check(err, ErrorMatches, `cannot open path: cannot iterate over unclean path ".*/test/../test"`)
}

func (s *realSystemSuite) TestSecureOpenPathFile(c *C) {
Expand Down