github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/runc/libcontainer/integration/seccomp_test.go (about)

     1  // +build linux,cgo,seccomp
     2  
     3  package integration
     4  
     5  import (
     6  	"strings"
     7  	"syscall"
     8  	"testing"
     9  
    10  	"github.com/opencontainers/runc/libcontainer"
    11  	"github.com/opencontainers/runc/libcontainer/configs"
    12  	libseccomp "github.com/seccomp/libseccomp-golang"
    13  )
    14  
    15  func TestSeccompDenyGetcwd(t *testing.T) {
    16  	if testing.Short() {
    17  		return
    18  	}
    19  
    20  	rootfs, err := newRootfs()
    21  	if err != nil {
    22  		t.Fatal(err)
    23  	}
    24  	defer remove(rootfs)
    25  
    26  	config := newTemplateConfig(rootfs)
    27  	config.Seccomp = &configs.Seccomp{
    28  		DefaultAction: configs.Allow,
    29  		Syscalls: []*configs.Syscall{
    30  			{
    31  				Name:   "getcwd",
    32  				Action: configs.Errno,
    33  			},
    34  		},
    35  	}
    36  
    37  	container, err := newContainer(config)
    38  	if err != nil {
    39  		t.Fatal(err)
    40  	}
    41  	defer container.Destroy()
    42  
    43  	buffers := newStdBuffers()
    44  	pwd := &libcontainer.Process{
    45  		Cwd:    "/",
    46  		Args:   []string{"pwd"},
    47  		Env:    standardEnvironment,
    48  		Stdin:  buffers.Stdin,
    49  		Stdout: buffers.Stdout,
    50  		Stderr: buffers.Stderr,
    51  	}
    52  
    53  	err = container.Run(pwd)
    54  	if err != nil {
    55  		t.Fatal(err)
    56  	}
    57  	ps, err := pwd.Wait()
    58  	if err == nil {
    59  		t.Fatal("Expecting error (negative return code); instead exited cleanly!")
    60  	}
    61  
    62  	var exitCode int
    63  	status := ps.Sys().(syscall.WaitStatus)
    64  	if status.Exited() {
    65  		exitCode = status.ExitStatus()
    66  	} else if status.Signaled() {
    67  		exitCode = -int(status.Signal())
    68  	} else {
    69  		t.Fatalf("Unrecognized exit reason!")
    70  	}
    71  
    72  	if exitCode == 0 {
    73  		t.Fatalf("Getcwd should fail with negative exit code, instead got %d!", exitCode)
    74  	}
    75  
    76  	expected := "pwd: getcwd: Operation not permitted"
    77  	actual := strings.Trim(buffers.Stderr.String(), "\n")
    78  	if actual != expected {
    79  		t.Fatalf("Expected output %s but got %s\n", expected, actual)
    80  	}
    81  }
    82  
    83  func TestSeccompPermitWriteConditional(t *testing.T) {
    84  	if testing.Short() {
    85  		return
    86  	}
    87  
    88  	rootfs, err := newRootfs()
    89  	if err != nil {
    90  		t.Fatal(err)
    91  	}
    92  	defer remove(rootfs)
    93  
    94  	config := newTemplateConfig(rootfs)
    95  	config.Seccomp = &configs.Seccomp{
    96  		DefaultAction: configs.Allow,
    97  		Syscalls: []*configs.Syscall{
    98  			{
    99  				Name:   "write",
   100  				Action: configs.Errno,
   101  				Args: []*configs.Arg{
   102  					{
   103  						Index: 0,
   104  						Value: 2,
   105  						Op:    configs.EqualTo,
   106  					},
   107  				},
   108  			},
   109  		},
   110  	}
   111  
   112  	container, err := newContainer(config)
   113  	if err != nil {
   114  		t.Fatal(err)
   115  	}
   116  	defer container.Destroy()
   117  
   118  	buffers := newStdBuffers()
   119  	dmesg := &libcontainer.Process{
   120  		Cwd:    "/",
   121  		Args:   []string{"busybox", "ls", "/"},
   122  		Env:    standardEnvironment,
   123  		Stdin:  buffers.Stdin,
   124  		Stdout: buffers.Stdout,
   125  		Stderr: buffers.Stderr,
   126  	}
   127  
   128  	err = container.Run(dmesg)
   129  	if err != nil {
   130  		t.Fatal(err)
   131  	}
   132  	if _, err := dmesg.Wait(); err != nil {
   133  		t.Fatalf("%s: %s", err, buffers.Stderr)
   134  	}
   135  }
   136  
   137  func TestSeccompDenyWriteConditional(t *testing.T) {
   138  	if testing.Short() {
   139  		return
   140  	}
   141  
   142  	// Only test if library version is v2.2.1 or higher
   143  	// Conditional filtering will always error in v2.2.0 and lower
   144  	major, minor, micro := libseccomp.GetLibraryVersion()
   145  	if (major == 2 && minor < 2) || (major == 2 && minor == 2 && micro < 1) {
   146  		return
   147  	}
   148  
   149  	rootfs, err := newRootfs()
   150  	if err != nil {
   151  		t.Fatal(err)
   152  	}
   153  	defer remove(rootfs)
   154  
   155  	config := newTemplateConfig(rootfs)
   156  	config.Seccomp = &configs.Seccomp{
   157  		DefaultAction: configs.Allow,
   158  		Syscalls: []*configs.Syscall{
   159  			{
   160  				Name:   "write",
   161  				Action: configs.Errno,
   162  				Args: []*configs.Arg{
   163  					{
   164  						Index: 0,
   165  						Value: 2,
   166  						Op:    configs.EqualTo,
   167  					},
   168  				},
   169  			},
   170  		},
   171  	}
   172  
   173  	container, err := newContainer(config)
   174  	if err != nil {
   175  		t.Fatal(err)
   176  	}
   177  	defer container.Destroy()
   178  
   179  	buffers := newStdBuffers()
   180  	dmesg := &libcontainer.Process{
   181  		Cwd:    "/",
   182  		Args:   []string{"busybox", "ls", "does_not_exist"},
   183  		Env:    standardEnvironment,
   184  		Stdin:  buffers.Stdin,
   185  		Stdout: buffers.Stdout,
   186  		Stderr: buffers.Stderr,
   187  	}
   188  
   189  	err = container.Run(dmesg)
   190  	if err != nil {
   191  		t.Fatal(err)
   192  	}
   193  
   194  	ps, err := dmesg.Wait()
   195  	if err == nil {
   196  		t.Fatal("Expecting negative return, instead got 0!")
   197  	}
   198  
   199  	var exitCode int
   200  	status := ps.Sys().(syscall.WaitStatus)
   201  	if status.Exited() {
   202  		exitCode = status.ExitStatus()
   203  	} else if status.Signaled() {
   204  		exitCode = -int(status.Signal())
   205  	} else {
   206  		t.Fatalf("Unrecognized exit reason!")
   207  	}
   208  
   209  	if exitCode == 0 {
   210  		t.Fatalf("Busybox should fail with negative exit code, instead got %d!", exitCode)
   211  	}
   212  
   213  	// We're denying write to stderr, so we expect an empty buffer
   214  	expected := ""
   215  	actual := strings.Trim(buffers.Stderr.String(), "\n")
   216  	if actual != expected {
   217  		t.Fatalf("Expected output %s but got %s\n", expected, actual)
   218  	}
   219  }