github.com/tetratelabs/wazero@v1.2.1/internal/sysfs/chown_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 TestChown(t *testing.T) {
    16  	tmpDir := t.TempDir()
    17  
    18  	dir := path.Join(tmpDir, "dir")
    19  	require.NoError(t, os.Mkdir(dir, 0o0777))
    20  
    21  	dirF := requireOpenFile(t, dir, syscall.O_RDONLY, 0)
    22  	defer dirF.Close()
    23  
    24  	dirSt, errno := dirF.Stat()
    25  	require.EqualErrno(t, 0, errno)
    26  
    27  	// Similar to TestChown in os_unix_test.go, we can't expect to change
    28  	// owner unless root, and with another user. Instead, test gid.
    29  	gid := os.Getgid()
    30  	groups, err := os.Getgroups()
    31  	require.NoError(t, err)
    32  
    33  	t.Run("-1 parameters means leave alone", func(t *testing.T) {
    34  		require.EqualErrno(t, 0, Chown(dir, -1, -1))
    35  		checkUidGid(t, dir, dirSt.Uid, dirSt.Gid)
    36  	})
    37  
    38  	t.Run("change gid, but not uid", func(t *testing.T) {
    39  		require.EqualErrno(t, 0, Chown(dir, -1, gid))
    40  		checkUidGid(t, dir, dirSt.Uid, uint32(gid))
    41  	})
    42  
    43  	// Now, try any other groups of the current user.
    44  	for _, g := range groups {
    45  		g := g
    46  		t.Run(fmt.Sprintf("change to gid %d", g), func(t *testing.T) {
    47  			// Test using our Chown
    48  			require.EqualErrno(t, 0, Chown(dir, -1, g))
    49  			checkUidGid(t, dir, dirSt.Uid, uint32(g))
    50  
    51  			// Revert back
    52  			require.EqualErrno(t, 0, dirF.Chown(-1, gid))
    53  			checkUidGid(t, dir, dirSt.Uid, uint32(gid))
    54  		})
    55  	}
    56  
    57  	t.Run("not found", func(t *testing.T) {
    58  		require.EqualErrno(t, syscall.ENOENT, Chown(path.Join(tmpDir, "a"), -1, gid))
    59  	})
    60  }
    61  
    62  func TestDefaultFileChown(t *testing.T) {
    63  	tmpDir := t.TempDir()
    64  
    65  	dir := path.Join(tmpDir, "dir")
    66  	require.NoError(t, os.Mkdir(dir, 0o0777))
    67  
    68  	dirF := requireOpenFile(t, dir, syscall.O_RDONLY, 0)
    69  	defer dirF.Close()
    70  
    71  	dirSt, errno := dirF.Stat()
    72  	require.EqualErrno(t, 0, errno)
    73  
    74  	// Similar to TestChownFile in os_unix_test.go, we can't expect to change
    75  	// owner unless root, and with another user. Instead, test gid.
    76  	gid := os.Getgid()
    77  	groups, err := os.Getgroups()
    78  	require.NoError(t, err)
    79  
    80  	t.Run("-1 parameters means leave alone", func(t *testing.T) {
    81  		require.EqualErrno(t, 0, dirF.Chown(-1, -1))
    82  		checkUidGid(t, dir, dirSt.Uid, dirSt.Gid)
    83  	})
    84  
    85  	t.Run("change gid, but not uid", func(t *testing.T) {
    86  		require.EqualErrno(t, 0, dirF.Chown(-1, gid))
    87  		checkUidGid(t, dir, dirSt.Uid, uint32(gid))
    88  	})
    89  
    90  	// Now, try any other groups of the current user.
    91  	for _, g := range groups {
    92  		g := g
    93  		t.Run(fmt.Sprintf("change to gid %d", g), func(t *testing.T) {
    94  			// Test using our Chown
    95  			require.EqualErrno(t, 0, dirF.Chown(-1, g))
    96  			checkUidGid(t, dir, dirSt.Uid, uint32(g))
    97  
    98  			// Revert back
    99  			require.EqualErrno(t, 0, dirF.Chown(-1, gid))
   100  			checkUidGid(t, dir, dirSt.Uid, uint32(gid))
   101  		})
   102  	}
   103  
   104  	t.Run("closed", func(t *testing.T) {
   105  		require.EqualErrno(t, 0, dirF.Close())
   106  		require.EqualErrno(t, syscall.EBADF, dirF.Chown(-1, gid))
   107  	})
   108  }
   109  
   110  func TestLchown(t *testing.T) {
   111  	tmpDir := t.TempDir()
   112  
   113  	dir := path.Join(tmpDir, "dir")
   114  	require.NoError(t, os.Mkdir(dir, 0o0777))
   115  
   116  	dirF := requireOpenFile(t, dir, syscall.O_RDONLY, 0)
   117  	defer dirF.Close()
   118  
   119  	dirSt, errno := dirF.Stat()
   120  	require.EqualErrno(t, 0, errno)
   121  
   122  	link := path.Join(tmpDir, "link")
   123  	require.NoError(t, os.Symlink(dir, link))
   124  
   125  	linkF := requireOpenFile(t, link, syscall.O_RDONLY, 0)
   126  	defer linkF.Close()
   127  
   128  	linkSt, errno := linkF.Stat()
   129  	require.EqualErrno(t, 0, errno)
   130  
   131  	// Similar to TestLchown in os_unix_test.go, we can't expect to change
   132  	// owner unless root, and with another user. Instead, test gid.
   133  	gid := os.Getgid()
   134  	groups, err := os.Getgroups()
   135  	require.NoError(t, err)
   136  
   137  	t.Run("-1 parameters means leave alone", func(t *testing.T) {
   138  		require.EqualErrno(t, 0, Lchown(link, -1, -1))
   139  		checkUidGid(t, link, linkSt.Uid, linkSt.Gid)
   140  	})
   141  
   142  	t.Run("change gid, but not uid", func(t *testing.T) {
   143  		require.EqualErrno(t, 0, Chown(dir, -1, gid))
   144  		checkUidGid(t, link, linkSt.Uid, uint32(gid))
   145  		// Make sure the target didn't change.
   146  		checkUidGid(t, dir, dirSt.Uid, dirSt.Gid)
   147  	})
   148  
   149  	// Now, try any other groups of the current user.
   150  	for _, g := range groups {
   151  		g := g
   152  		t.Run(fmt.Sprintf("change to gid %d", g), func(t *testing.T) {
   153  			// Test using our Lchown
   154  			require.EqualErrno(t, 0, Lchown(link, -1, g))
   155  			checkUidGid(t, link, linkSt.Uid, uint32(g))
   156  			// Make sure the target didn't change.
   157  			checkUidGid(t, dir, dirSt.Uid, dirSt.Gid)
   158  
   159  			// Revert back
   160  			require.EqualErrno(t, 0, Lchown(link, -1, gid))
   161  			checkUidGid(t, link, linkSt.Uid, uint32(gid))
   162  		})
   163  	}
   164  
   165  	t.Run("not found", func(t *testing.T) {
   166  		require.EqualErrno(t, syscall.ENOENT, Lchown(path.Join(tmpDir, "a"), -1, gid))
   167  	})
   168  }