Source file src/os/root_unix_test.go

     1  // Copyright 2025 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build unix || (js && wasm) || wasip1
     6  
     7  package os_test
     8  
     9  import (
    10  	"fmt"
    11  	"os"
    12  	"path/filepath"
    13  	"runtime"
    14  	"syscall"
    15  	"testing"
    16  )
    17  
    18  func TestRootChown(t *testing.T) {
    19  	if runtime.GOOS == "wasip1" {
    20  		t.Skip("Chown not supported on " + runtime.GOOS)
    21  	}
    22  
    23  	// Look up the current default uid/gid.
    24  	f := newFile(t)
    25  	dir, err := f.Stat()
    26  	if err != nil {
    27  		t.Fatal(err)
    28  	}
    29  	sys := dir.Sys().(*syscall.Stat_t)
    30  
    31  	groups, err := os.Getgroups()
    32  	if err != nil {
    33  		t.Fatal(err)
    34  	}
    35  	groups = append(groups, os.Getgid())
    36  	for _, test := range rootTestCases {
    37  		test.run(t, func(t *testing.T, target string, root *os.Root) {
    38  			if target != "" {
    39  				if err := os.WriteFile(target, nil, 0o666); err != nil {
    40  					t.Fatal(err)
    41  				}
    42  			}
    43  			for _, gid := range groups {
    44  				err := root.Chown(test.open, -1, gid)
    45  				if errEndsTest(t, err, test.wantError, "root.Chown(%q, -1, %v)", test.open, gid) {
    46  					return
    47  				}
    48  				checkUidGid(t, target, int(sys.Uid), gid)
    49  			}
    50  		})
    51  	}
    52  }
    53  
    54  func TestRootLchown(t *testing.T) {
    55  	if runtime.GOOS == "wasip1" {
    56  		t.Skip("Lchown not supported on " + runtime.GOOS)
    57  	}
    58  
    59  	// Look up the current default uid/gid.
    60  	f := newFile(t)
    61  	dir, err := f.Stat()
    62  	if err != nil {
    63  		t.Fatal(err)
    64  	}
    65  	sys := dir.Sys().(*syscall.Stat_t)
    66  
    67  	groups, err := os.Getgroups()
    68  	if err != nil {
    69  		t.Fatal(err)
    70  	}
    71  	groups = append(groups, os.Getgid())
    72  	for _, test := range rootTestCases {
    73  		test.run(t, func(t *testing.T, target string, root *os.Root) {
    74  			wantError := test.wantError
    75  			if test.ltarget != "" {
    76  				wantError = false
    77  				target = filepath.Join(root.Name(), test.ltarget)
    78  			} else if target != "" {
    79  				if err := os.WriteFile(target, nil, 0o666); err != nil {
    80  					t.Fatal(err)
    81  				}
    82  			}
    83  			for _, gid := range groups {
    84  				err := root.Lchown(test.open, -1, gid)
    85  				if errEndsTest(t, err, wantError, "root.Lchown(%q, -1, %v)", test.open, gid) {
    86  					return
    87  				}
    88  				checkUidGid(t, target, int(sys.Uid), gid)
    89  			}
    90  		})
    91  	}
    92  }
    93  
    94  func TestRootConsistencyChown(t *testing.T) {
    95  	if runtime.GOOS == "wasip1" {
    96  		t.Skip("Chown not supported on " + runtime.GOOS)
    97  	}
    98  	groups, err := os.Getgroups()
    99  	if err != nil {
   100  		t.Fatal(err)
   101  	}
   102  	var gid int
   103  	if len(groups) == 0 {
   104  		gid = os.Getgid()
   105  	} else {
   106  		gid = groups[0]
   107  	}
   108  	for _, test := range rootConsistencyTestCases {
   109  		test.run(t, func(t *testing.T, path string, r *os.Root) (string, error) {
   110  			chown := os.Chown
   111  			lstat := os.Lstat
   112  			if r != nil {
   113  				chown = r.Chown
   114  				lstat = r.Lstat
   115  			}
   116  			err := chown(path, -1, gid)
   117  			if err != nil {
   118  				return "", err
   119  			}
   120  			fi, err := lstat(path)
   121  			if err != nil {
   122  				return "", err
   123  			}
   124  			sys := fi.Sys().(*syscall.Stat_t)
   125  			return fmt.Sprintf("%v %v", sys.Uid, sys.Gid), nil
   126  		})
   127  	}
   128  }
   129  
   130  func TestRootConsistencyLchown(t *testing.T) {
   131  	if runtime.GOOS == "wasip1" {
   132  		t.Skip("Lchown not supported on " + runtime.GOOS)
   133  	}
   134  	groups, err := os.Getgroups()
   135  	if err != nil {
   136  		t.Fatal(err)
   137  	}
   138  	var gid int
   139  	if len(groups) == 0 {
   140  		gid = os.Getgid()
   141  	} else {
   142  		gid = groups[0]
   143  	}
   144  	for _, test := range rootConsistencyTestCases {
   145  		test.run(t, func(t *testing.T, path string, r *os.Root) (string, error) {
   146  			lchown := os.Lchown
   147  			lstat := os.Lstat
   148  			if r != nil {
   149  				lchown = r.Lchown
   150  				lstat = r.Lstat
   151  			}
   152  			err := lchown(path, -1, gid)
   153  			if err != nil {
   154  				return "", err
   155  			}
   156  			fi, err := lstat(path)
   157  			if err != nil {
   158  				return "", err
   159  			}
   160  			sys := fi.Sys().(*syscall.Stat_t)
   161  			return fmt.Sprintf("%v %v", sys.Uid, sys.Gid), nil
   162  		})
   163  	}
   164  }
   165  

View as plain text