github.com/HACKERALERT/Picocrypt/src/external/sys@v0.0.0-20210609020157-e519952f829f/unix/syscall_freebsd_test.go (about)

     1  // Copyright 2014 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 freebsd
     6  // +build freebsd
     7  
     8  package unix_test
     9  
    10  import (
    11  	"flag"
    12  	"fmt"
    13  	"io/ioutil"
    14  	"net"
    15  	"os"
    16  	"os/exec"
    17  	"path"
    18  	"path/filepath"
    19  	"runtime"
    20  	"testing"
    21  
    22  	"golang.org/x/sys/unix"
    23  )
    24  
    25  func TestSysctlUint64(t *testing.T) {
    26  	_, err := unix.SysctlUint64("vm.swap_total")
    27  	if err != nil {
    28  		t.Fatal(err)
    29  	}
    30  }
    31  
    32  // FIXME: Infrastructure for launching tests in subprocesses stolen from openbsd_test.go - refactor?
    33  // testCmd generates a proper command that, when executed, runs the test
    34  // corresponding to the given key.
    35  
    36  type testProc struct {
    37  	fn      func()                    // should always exit instead of returning
    38  	arg     func(t *testing.T) string // generate argument for test
    39  	cleanup func(arg string) error    // for instance, delete coredumps from testing pledge
    40  	success bool                      // whether zero-exit means success or failure
    41  }
    42  
    43  var (
    44  	testProcs = map[string]testProc{}
    45  	procName  = ""
    46  	procArg   = ""
    47  )
    48  
    49  const (
    50  	optName = "sys-unix-internal-procname"
    51  	optArg  = "sys-unix-internal-arg"
    52  )
    53  
    54  func init() {
    55  	flag.StringVar(&procName, optName, "", "internal use only")
    56  	flag.StringVar(&procArg, optArg, "", "internal use only")
    57  
    58  }
    59  
    60  func testCmd(procName string, procArg string) (*exec.Cmd, error) {
    61  	exe, err := filepath.Abs(os.Args[0])
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  	cmd := exec.Command(exe, "-"+optName+"="+procName, "-"+optArg+"="+procArg)
    66  	cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
    67  	return cmd, nil
    68  }
    69  
    70  // ExitsCorrectly is a comprehensive, one-line-of-use wrapper for testing
    71  // a testProc with a key.
    72  func ExitsCorrectly(t *testing.T, procName string) {
    73  	s := testProcs[procName]
    74  	arg := "-"
    75  	if s.arg != nil {
    76  		arg = s.arg(t)
    77  	}
    78  	c, err := testCmd(procName, arg)
    79  	defer func(arg string) {
    80  		if err := s.cleanup(arg); err != nil {
    81  			t.Fatalf("Failed to run cleanup for %s %s %#v", procName, err, err)
    82  		}
    83  	}(arg)
    84  	if err != nil {
    85  		t.Fatalf("Failed to construct command for %s", procName)
    86  	}
    87  	if (c.Run() == nil) != s.success {
    88  		result := "succeed"
    89  		if !s.success {
    90  			result = "fail"
    91  		}
    92  		t.Fatalf("Process did not %s when it was supposed to", result)
    93  	}
    94  }
    95  
    96  func TestMain(m *testing.M) {
    97  	flag.Parse()
    98  	if procName != "" {
    99  		t := testProcs[procName]
   100  		t.fn()
   101  		os.Stderr.WriteString("test function did not exit\n")
   102  		if t.success {
   103  			os.Exit(1)
   104  		} else {
   105  			os.Exit(0)
   106  		}
   107  	}
   108  	os.Exit(m.Run())
   109  }
   110  
   111  // end of infrastructure
   112  
   113  const testfile = "gocapmodetest"
   114  const testfile2 = testfile + "2"
   115  
   116  func CapEnterTest() {
   117  	_, err := os.OpenFile(path.Join(procArg, testfile), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
   118  	if err != nil {
   119  		panic(fmt.Sprintf("OpenFile: %s", err))
   120  	}
   121  
   122  	err = unix.CapEnter()
   123  	if err != nil {
   124  		panic(fmt.Sprintf("CapEnter: %s", err))
   125  	}
   126  
   127  	_, err = os.OpenFile(path.Join(procArg, testfile2), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
   128  	if err == nil {
   129  		panic("OpenFile works!")
   130  	}
   131  	if err.(*os.PathError).Err != unix.ECAPMODE {
   132  		panic(fmt.Sprintf("OpenFile failed wrong: %s %#v", err, err))
   133  	}
   134  	os.Exit(0)
   135  }
   136  
   137  func makeTempDir(t *testing.T) string {
   138  	d, err := ioutil.TempDir("", "go_openat_test")
   139  	if err != nil {
   140  		t.Fatalf("TempDir failed: %s", err)
   141  	}
   142  	return d
   143  }
   144  
   145  func removeTempDir(arg string) error {
   146  	err := os.RemoveAll(arg)
   147  	if err != nil && err.(*os.PathError).Err == unix.ENOENT {
   148  		return nil
   149  	}
   150  	return err
   151  }
   152  
   153  func init() {
   154  	testProcs["cap_enter"] = testProc{
   155  		CapEnterTest,
   156  		makeTempDir,
   157  		removeTempDir,
   158  		true,
   159  	}
   160  }
   161  
   162  func TestCapEnter(t *testing.T) {
   163  	if runtime.GOARCH != "amd64" {
   164  		t.Skipf("skipping test on %s", runtime.GOARCH)
   165  	}
   166  	ExitsCorrectly(t, "cap_enter")
   167  }
   168  
   169  func OpenatTest() {
   170  	f, err := os.Open(procArg)
   171  	if err != nil {
   172  		panic(err)
   173  	}
   174  
   175  	err = unix.CapEnter()
   176  	if err != nil {
   177  		panic(fmt.Sprintf("CapEnter: %s", err))
   178  	}
   179  
   180  	fxx, err := unix.Openat(int(f.Fd()), "xx", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
   181  	if err != nil {
   182  		panic(err)
   183  	}
   184  	unix.Close(fxx)
   185  
   186  	// The right to open BASE/xx is not ambient
   187  	_, err = os.OpenFile(procArg+"/xx", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
   188  	if err == nil {
   189  		panic("OpenFile succeeded")
   190  	}
   191  	if err.(*os.PathError).Err != unix.ECAPMODE {
   192  		panic(fmt.Sprintf("OpenFile failed wrong: %s %#v", err, err))
   193  	}
   194  
   195  	// Can't make a new directory either
   196  	err = os.Mkdir(procArg+"2", 0777)
   197  	if err == nil {
   198  		panic("MKdir succeeded")
   199  	}
   200  	if err.(*os.PathError).Err != unix.ECAPMODE {
   201  		panic(fmt.Sprintf("Mkdir failed wrong: %s %#v", err, err))
   202  	}
   203  
   204  	// Remove all caps except read and lookup.
   205  	r, err := unix.CapRightsInit([]uint64{unix.CAP_READ, unix.CAP_LOOKUP})
   206  	if err != nil {
   207  		panic(fmt.Sprintf("CapRightsInit failed: %s %#v", err, err))
   208  	}
   209  	err = unix.CapRightsLimit(f.Fd(), r)
   210  	if err != nil {
   211  		panic(fmt.Sprintf("CapRightsLimit failed: %s %#v", err, err))
   212  	}
   213  
   214  	// Check we can get the rights back again
   215  	r, err = unix.CapRightsGet(f.Fd())
   216  	if err != nil {
   217  		panic(fmt.Sprintf("CapRightsGet failed: %s %#v", err, err))
   218  	}
   219  	b, err := unix.CapRightsIsSet(r, []uint64{unix.CAP_READ, unix.CAP_LOOKUP})
   220  	if err != nil {
   221  		panic(fmt.Sprintf("CapRightsIsSet failed: %s %#v", err, err))
   222  	}
   223  	if !b {
   224  		panic(fmt.Sprintf("Unexpected rights"))
   225  	}
   226  	b, err = unix.CapRightsIsSet(r, []uint64{unix.CAP_READ, unix.CAP_LOOKUP, unix.CAP_WRITE})
   227  	if err != nil {
   228  		panic(fmt.Sprintf("CapRightsIsSet failed: %s %#v", err, err))
   229  	}
   230  	if b {
   231  		panic(fmt.Sprintf("Unexpected rights (2)"))
   232  	}
   233  
   234  	// Can no longer create a file
   235  	_, err = unix.Openat(int(f.Fd()), "xx2", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
   236  	if err == nil {
   237  		panic("Openat succeeded")
   238  	}
   239  	if err != unix.ENOTCAPABLE {
   240  		panic(fmt.Sprintf("OpenFileAt failed wrong: %s %#v", err, err))
   241  	}
   242  
   243  	// But can read an existing one
   244  	_, err = unix.Openat(int(f.Fd()), "xx", os.O_RDONLY, 0666)
   245  	if err != nil {
   246  		panic(fmt.Sprintf("Openat failed: %s %#v", err, err))
   247  	}
   248  
   249  	os.Exit(0)
   250  }
   251  
   252  func init() {
   253  	testProcs["openat"] = testProc{
   254  		OpenatTest,
   255  		makeTempDir,
   256  		removeTempDir,
   257  		true,
   258  	}
   259  }
   260  
   261  func TestOpenat(t *testing.T) {
   262  	if runtime.GOARCH != "amd64" {
   263  		t.Skipf("skipping test on %s", runtime.GOARCH)
   264  	}
   265  	ExitsCorrectly(t, "openat")
   266  }
   267  
   268  func TestCapRightsSetAndClear(t *testing.T) {
   269  	r, err := unix.CapRightsInit([]uint64{unix.CAP_READ, unix.CAP_WRITE, unix.CAP_PDWAIT})
   270  	if err != nil {
   271  		t.Fatalf("CapRightsInit failed: %s", err)
   272  	}
   273  
   274  	err = unix.CapRightsSet(r, []uint64{unix.CAP_EVENT, unix.CAP_LISTEN})
   275  	if err != nil {
   276  		t.Fatalf("CapRightsSet failed: %s", err)
   277  	}
   278  
   279  	b, err := unix.CapRightsIsSet(r, []uint64{unix.CAP_READ, unix.CAP_WRITE, unix.CAP_PDWAIT, unix.CAP_EVENT, unix.CAP_LISTEN})
   280  	if err != nil {
   281  		t.Fatalf("CapRightsIsSet failed: %s", err)
   282  	}
   283  	if !b {
   284  		t.Fatalf("Wrong rights set")
   285  	}
   286  
   287  	err = unix.CapRightsClear(r, []uint64{unix.CAP_READ, unix.CAP_PDWAIT})
   288  	if err != nil {
   289  		t.Fatalf("CapRightsClear failed: %s", err)
   290  	}
   291  
   292  	b, err = unix.CapRightsIsSet(r, []uint64{unix.CAP_WRITE, unix.CAP_EVENT, unix.CAP_LISTEN})
   293  	if err != nil {
   294  		t.Fatalf("CapRightsIsSet failed: %s", err)
   295  	}
   296  	if !b {
   297  		t.Fatalf("Wrong rights set")
   298  	}
   299  }
   300  
   301  func TestGetsockoptXucred(t *testing.T) {
   302  	fds, err := unix.Socketpair(unix.AF_LOCAL, unix.SOCK_STREAM, 0)
   303  	if err != nil {
   304  		t.Fatalf("Socketpair: %v", err)
   305  	}
   306  
   307  	srvFile := os.NewFile(uintptr(fds[0]), "server")
   308  	cliFile := os.NewFile(uintptr(fds[1]), "client")
   309  	defer srvFile.Close()
   310  	defer cliFile.Close()
   311  
   312  	srv, err := net.FileConn(srvFile)
   313  	if err != nil {
   314  		t.Fatalf("FileConn: %v", err)
   315  	}
   316  	defer srv.Close()
   317  
   318  	cli, err := net.FileConn(cliFile)
   319  	if err != nil {
   320  		t.Fatalf("FileConn: %v", err)
   321  	}
   322  	defer cli.Close()
   323  
   324  	cred, err := unix.GetsockoptXucred(fds[1], unix.SOL_LOCAL, unix.LOCAL_PEERCRED)
   325  	if err == unix.ENOTCONN {
   326  		t.Skip("GetsockoptXucred not supported with Socketpair on FreeBSD 11 and earlier")
   327  	} else if err != nil {
   328  		t.Fatal(err)
   329  	}
   330  	t.Logf("got: %+v", cred)
   331  	if got, want := cred.Uid, os.Getuid(); int(got) != int(want) {
   332  		t.Errorf("uid = %v; want %v", got, want)
   333  	}
   334  }
   335  
   336  // stringsFromByteSlice converts a sequence of attributes to a []string.
   337  // On FreeBSD, each entry consists of a single byte containing the length
   338  // of the attribute name, followed by the attribute name.
   339  // The name is _not_ NULL-terminated.
   340  func stringsFromByteSlice(buf []byte) []string {
   341  	var result []string
   342  	i := 0
   343  	for i < len(buf) {
   344  		next := i + 1 + int(buf[i])
   345  		result = append(result, string(buf[i+1:next]))
   346  		i = next
   347  	}
   348  	return result
   349  }