github.com/tetratelabs/wazero@v1.2.1/internal/sysfs/dirfs_unix_test.go (about) 1 //go:build !windows 2 3 package sysfs 4 5 import ( 6 "fmt" 7 "os" 8 "path" 9 "syscall" 10 "testing" 11 12 "github.com/tetratelabs/wazero/internal/testing/require" 13 ) 14 15 func TestDirFS_Chown(t *testing.T) { 16 tmpDir := t.TempDir() 17 testFS := NewDirFS(tmpDir) 18 19 require.EqualErrno(t, 0, testFS.Mkdir("dir", 0o0777)) 20 dirF, errno := testFS.OpenFile("dir", syscall.O_RDONLY, 0) 21 require.EqualErrno(t, 0, errno) 22 23 dirSt, errno := dirF.Stat() 24 require.EqualErrno(t, 0, errno) 25 26 // Similar to TestChown in os_unix_test.go, we can't expect to change 27 // owner unless root, and with another user. Instead, test gid. 28 gid := os.Getgid() 29 groups, err := os.Getgroups() 30 require.NoError(t, err) 31 32 t.Run("-1 parameters means leave alone", func(t *testing.T) { 33 require.EqualErrno(t, 0, testFS.Chown("dir", -1, -1)) 34 checkUidGid(t, path.Join(tmpDir, "dir"), dirSt.Uid, dirSt.Gid) 35 }) 36 37 t.Run("change gid, but not uid", func(t *testing.T) { 38 require.EqualErrno(t, 0, testFS.Chown("dir", -1, gid)) 39 checkUidGid(t, path.Join(tmpDir, "dir"), dirSt.Uid, uint32(gid)) 40 }) 41 42 // Now, try any other groups of the current user. 43 for _, g := range groups { 44 g := g 45 t.Run(fmt.Sprintf("change to gid %d", g), func(t *testing.T) { 46 // Test using our Chown 47 require.EqualErrno(t, 0, testFS.Chown("dir", -1, g)) 48 checkUidGid(t, path.Join(tmpDir, "dir"), dirSt.Uid, uint32(g)) 49 50 // Revert back 51 require.EqualErrno(t, 0, dirF.Chown(-1, gid)) 52 checkUidGid(t, path.Join(tmpDir, "dir"), dirSt.Uid, uint32(gid)) 53 }) 54 } 55 56 t.Run("not found", func(t *testing.T) { 57 require.EqualErrno(t, syscall.ENOENT, testFS.Chown("a", -1, gid)) 58 }) 59 } 60 61 func TestDirFS_Lchown(t *testing.T) { 62 tmpDir := t.TempDir() 63 testFS := NewDirFS(tmpDir) 64 65 require.EqualErrno(t, 0, testFS.Mkdir("dir", 0o0777)) 66 dirF, errno := testFS.OpenFile("dir", syscall.O_RDONLY, 0) 67 require.EqualErrno(t, 0, errno) 68 69 dirSt, errno := dirF.Stat() 70 require.EqualErrno(t, 0, errno) 71 72 require.EqualErrno(t, 0, testFS.Symlink("dir", "link")) 73 linkF, errno := testFS.OpenFile("link", syscall.O_RDONLY, 0) 74 require.EqualErrno(t, 0, errno) 75 76 linkSt, errno := linkF.Stat() 77 require.EqualErrno(t, 0, errno) 78 79 // Similar to TestLchown in os_unix_test.go, we can't expect to change 80 // owner unless root, and with another user. Instead, test gid. 81 gid := os.Getgid() 82 groups, err := os.Getgroups() 83 require.NoError(t, err) 84 85 t.Run("-1 parameters means leave alone", func(t *testing.T) { 86 require.EqualErrno(t, 0, testFS.Lchown("link", -1, -1)) 87 checkUidGid(t, path.Join(tmpDir, "link"), linkSt.Uid, linkSt.Gid) 88 }) 89 90 t.Run("change gid, but not uid", func(t *testing.T) { 91 require.EqualErrno(t, 0, testFS.Chown("dir", -1, gid)) 92 checkUidGid(t, path.Join(tmpDir, "link"), linkSt.Uid, uint32(gid)) 93 // Make sure the target didn't change. 94 checkUidGid(t, path.Join(tmpDir, "dir"), dirSt.Uid, dirSt.Gid) 95 }) 96 97 // Now, try any other groups of the current user. 98 for _, g := range groups { 99 g := g 100 t.Run(fmt.Sprintf("change to gid %d", g), func(t *testing.T) { 101 // Test using our Lchown 102 require.EqualErrno(t, 0, testFS.Lchown("link", -1, g)) 103 checkUidGid(t, path.Join(tmpDir, "link"), linkSt.Uid, uint32(g)) 104 // Make sure the target didn't change. 105 checkUidGid(t, path.Join(tmpDir, "dir"), dirSt.Uid, dirSt.Gid) 106 107 // Revert back 108 require.EqualErrno(t, 0, testFS.Lchown("link", -1, gid)) 109 checkUidGid(t, path.Join(tmpDir, "link"), linkSt.Uid, uint32(gid)) 110 }) 111 } 112 113 t.Run("not found", func(t *testing.T) { 114 require.EqualErrno(t, syscall.ENOENT, testFS.Lchown("a", -1, gid)) 115 }) 116 } 117 118 // checkUidGid uses lstat to ensure the comparison is against the file, not the 119 // target of a symbolic link. 120 func checkUidGid(t *testing.T, path string, uid, gid uint32) { 121 ls, err := os.Lstat(path) 122 require.NoError(t, err) 123 sys := ls.Sys().(*syscall.Stat_t) 124 require.Equal(t, uid, sys.Uid) 125 require.Equal(t, gid, sys.Gid) 126 }