Skip to content

Commit

Permalink
Merge pull request #249 from JohnStarich/bugfix/memfs-chmod-perm-only
Browse files Browse the repository at this point in the history
Prevent MemMapFs.Chmod from changing all mode bits
  • Loading branch information
0xmichalis committed Jul 13, 2020
2 parents 64b7ddd + d443df9 commit 5d9e780
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 4 deletions.
22 changes: 18 additions & 4 deletions memmap.go
Expand Up @@ -141,9 +141,7 @@ func (m *MemMapFs) Mkdir(name string, perm os.FileMode) error {
m.registerWithParent(item)
m.mu.Unlock()

m.Chmod(name, perm|os.ModeDir)

return nil
return m.setFileMode(name, perm|os.ModeDir)
}

func (m *MemMapFs) MkdirAll(path string, perm os.FileMode) error {
Expand Down Expand Up @@ -240,7 +238,7 @@ func (m *MemMapFs) OpenFile(name string, flag int, perm os.FileMode) (File, erro
}
}
if chmod {
m.Chmod(name, perm)
return file, m.setFileMode(name, perm)
}
return file, nil
}
Expand Down Expand Up @@ -321,6 +319,22 @@ func (m *MemMapFs) Stat(name string) (os.FileInfo, error) {
}

func (m *MemMapFs) Chmod(name string, mode os.FileMode) error {
const chmodBits = os.ModePerm | os.ModeSetuid | os.ModeSetgid | os.ModeSticky // Only a subset of bits are allowed to be changed. Documented under os.Chmod()
mode &= chmodBits

m.mu.RLock()
f, ok := m.getData()[name]
m.mu.RUnlock()
if !ok {
return &os.PathError{Op: "chmod", Path: name, Err: ErrFileNotFound}
}
prevOtherBits := mem.GetFileInfo(f).Mode() & ^chmodBits

mode = prevOtherBits | mode
return m.setFileMode(name, mode)
}

func (m *MemMapFs) setFileMode(name string, mode os.FileMode) error {
name = normalizePath(name)

m.mu.RLock()
Expand Down
31 changes: 31 additions & 0 deletions memmap_test.go
Expand Up @@ -472,3 +472,34 @@ func TestMemFsUnexpectedEOF(t *testing.T) {
t.Fatal("Expected ErrUnexpectedEOF")
}
}

func TestMemFsChmod(t *testing.T) {
t.Parallel()

fs := NewMemMapFs()
const file = "hello"
if err := fs.Mkdir(file, 0700); err != nil {
t.Fatal(err)
}

info, err := fs.Stat(file)
if err != nil {
t.Fatal(err)
}
if info.Mode().String() != "drwx------" {
t.Fatal("mkdir failed to create a directory: mode =", info.Mode())
}

err = fs.Chmod(file, 0)
if err != nil {
t.Error("Failed to run chmod:", err)
}

info, err = fs.Stat(file)
if err != nil {
t.Fatal(err)
}
if info.Mode().String() != "d---------" {
t.Error("chmod should not change file type. New mode =", info.Mode())
}
}

0 comments on commit 5d9e780

Please sign in to comment.