Skip to content

Commit 5d9e780

Browse files
authored
Merge pull request #249 from JohnStarich/bugfix/memfs-chmod-perm-only
Prevent MemMapFs.Chmod from changing all mode bits
2 parents 64b7ddd + d443df9 commit 5d9e780

File tree

2 files changed

+49
-4
lines changed

2 files changed

+49
-4
lines changed

memmap.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,7 @@ func (m *MemMapFs) Mkdir(name string, perm os.FileMode) error {
141141
m.registerWithParent(item)
142142
m.mu.Unlock()
143143

144-
m.Chmod(name, perm|os.ModeDir)
145-
146-
return nil
144+
return m.setFileMode(name, perm|os.ModeDir)
147145
}
148146

149147
func (m *MemMapFs) MkdirAll(path string, perm os.FileMode) error {
@@ -240,7 +238,7 @@ func (m *MemMapFs) OpenFile(name string, flag int, perm os.FileMode) (File, erro
240238
}
241239
}
242240
if chmod {
243-
m.Chmod(name, perm)
241+
return file, m.setFileMode(name, perm)
244242
}
245243
return file, nil
246244
}
@@ -321,6 +319,22 @@ func (m *MemMapFs) Stat(name string) (os.FileInfo, error) {
321319
}
322320

323321
func (m *MemMapFs) Chmod(name string, mode os.FileMode) error {
322+
const chmodBits = os.ModePerm | os.ModeSetuid | os.ModeSetgid | os.ModeSticky // Only a subset of bits are allowed to be changed. Documented under os.Chmod()
323+
mode &= chmodBits
324+
325+
m.mu.RLock()
326+
f, ok := m.getData()[name]
327+
m.mu.RUnlock()
328+
if !ok {
329+
return &os.PathError{Op: "chmod", Path: name, Err: ErrFileNotFound}
330+
}
331+
prevOtherBits := mem.GetFileInfo(f).Mode() & ^chmodBits
332+
333+
mode = prevOtherBits | mode
334+
return m.setFileMode(name, mode)
335+
}
336+
337+
func (m *MemMapFs) setFileMode(name string, mode os.FileMode) error {
324338
name = normalizePath(name)
325339

326340
m.mu.RLock()

memmap_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,3 +472,34 @@ func TestMemFsUnexpectedEOF(t *testing.T) {
472472
t.Fatal("Expected ErrUnexpectedEOF")
473473
}
474474
}
475+
476+
func TestMemFsChmod(t *testing.T) {
477+
t.Parallel()
478+
479+
fs := NewMemMapFs()
480+
const file = "hello"
481+
if err := fs.Mkdir(file, 0700); err != nil {
482+
t.Fatal(err)
483+
}
484+
485+
info, err := fs.Stat(file)
486+
if err != nil {
487+
t.Fatal(err)
488+
}
489+
if info.Mode().String() != "drwx------" {
490+
t.Fatal("mkdir failed to create a directory: mode =", info.Mode())
491+
}
492+
493+
err = fs.Chmod(file, 0)
494+
if err != nil {
495+
t.Error("Failed to run chmod:", err)
496+
}
497+
498+
info, err = fs.Stat(file)
499+
if err != nil {
500+
t.Fatal(err)
501+
}
502+
if info.Mode().String() != "d---------" {
503+
t.Error("chmod should not change file type. New mode =", info.Mode())
504+
}
505+
}

0 commit comments

Comments
 (0)