github.com/sagernet/gvisor@v0.0.0-20240428053021-e691de28565f/pkg/abi/linux/seccomp.go (about)

     1  // Copyright 2018 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package linux
    16  
    17  import "fmt"
    18  
    19  // Seccomp constants taken from <linux/seccomp.h>.
    20  const (
    21  	SECCOMP_MODE_NONE   = 0
    22  	SECCOMP_MODE_FILTER = 2
    23  
    24  	SECCOMP_RET_ACTION_FULL = 0xffff0000
    25  	SECCOMP_RET_ACTION      = 0x7fff0000
    26  	SECCOMP_RET_DATA        = 0x0000ffff
    27  
    28  	SECCOMP_SET_MODE_FILTER  = 1
    29  	SECCOMP_GET_ACTION_AVAIL = 2
    30  	SECCOMP_GET_NOTIF_SIZES  = 3
    31  
    32  	SECCOMP_FILTER_FLAG_TSYNC        = 1
    33  	SECCOMP_FILTER_FLAG_NEW_LISTENER = 1 << 3
    34  
    35  	SECCOMP_USER_NOTIF_FLAG_CONTINUE = 1
    36  
    37  	SECCOMP_IOCTL_NOTIF_RECV      = 0xc0502100
    38  	SECCOMP_IOCTL_NOTIF_SEND      = 0xc0182101
    39  	SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
    40  
    41  	SECCOMP_USER_NOTIF_FD_SYNC_WAKE_UP = 1
    42  )
    43  
    44  // BPFAction is an action for a BPF filter.
    45  type BPFAction uint32
    46  
    47  // BPFAction definitions.
    48  const (
    49  	SECCOMP_RET_KILL_PROCESS BPFAction = 0x80000000
    50  	SECCOMP_RET_KILL_THREAD  BPFAction = 0x00000000
    51  	SECCOMP_RET_TRAP         BPFAction = 0x00030000
    52  	SECCOMP_RET_ERRNO        BPFAction = 0x00050000
    53  	SECCOMP_RET_TRACE        BPFAction = 0x7ff00000
    54  	SECCOMP_RET_USER_NOTIF   BPFAction = 0x7fc00000
    55  	SECCOMP_RET_ALLOW        BPFAction = 0x7fff0000
    56  )
    57  
    58  func (a BPFAction) String() string {
    59  	switch a & SECCOMP_RET_ACTION_FULL {
    60  	case SECCOMP_RET_KILL_PROCESS:
    61  		return "kill process"
    62  	case SECCOMP_RET_KILL_THREAD:
    63  		return "kill thread"
    64  	case SECCOMP_RET_TRAP:
    65  		data := a.Data()
    66  		if data == 0 {
    67  			return "trap"
    68  		}
    69  		return fmt.Sprintf("trap (data=%#x)", data)
    70  	case SECCOMP_RET_ERRNO:
    71  		return fmt.Sprintf("return errno=%#x", a.Data())
    72  	case SECCOMP_RET_TRACE:
    73  		data := a.Data()
    74  		if data == 0 {
    75  			return "trace"
    76  		}
    77  		return fmt.Sprintf("trace (data=%#x)", data)
    78  	case SECCOMP_RET_ALLOW:
    79  		return "allow"
    80  	case SECCOMP_RET_USER_NOTIF:
    81  		return "unotify"
    82  	}
    83  	return fmt.Sprintf("invalid action: %#x", a)
    84  }
    85  
    86  // Data returns the SECCOMP_RET_DATA portion of the action.
    87  func (a BPFAction) Data() uint16 {
    88  	return uint16(a & SECCOMP_RET_DATA)
    89  }
    90  
    91  // WithReturnCode sets the lower 16 bits of the SECCOMP_RET_ERRNO or
    92  // SECCOMP_RET_TRACE actions to the provided return code, overwriting the previous
    93  // action, and returns a new BPFAction. If not SECCOMP_RET_ERRNO or
    94  // SECCOMP_RET_TRACE then this panics.
    95  func (a BPFAction) WithReturnCode(code uint16) BPFAction {
    96  	// mask out the previous return value
    97  	baseAction := a & SECCOMP_RET_ACTION_FULL
    98  	if baseAction == SECCOMP_RET_ERRNO || baseAction == SECCOMP_RET_TRACE {
    99  		return BPFAction(uint32(baseAction) | uint32(code))
   100  	}
   101  	panic("WithReturnCode only valid for SECCOMP_RET_ERRNO and SECCOMP_RET_TRACE")
   102  }
   103  
   104  // SockFprog is sock_fprog taken from <linux/filter.h>.
   105  type SockFprog struct {
   106  	Len    uint16
   107  	pad    [6]byte
   108  	Filter *BPFInstruction
   109  }
   110  
   111  // SeccompData is equivalent to struct seccomp_data, which contains the data
   112  // passed to seccomp-bpf filters.
   113  //
   114  // +marshal
   115  type SeccompData struct {
   116  	// Nr is the system call number.
   117  	Nr int32
   118  
   119  	// Arch is an AUDIT_ARCH_* value indicating the system call convention.
   120  	Arch uint32
   121  
   122  	// InstructionPointer is the value of the instruction pointer at the time
   123  	// of the system call.
   124  	InstructionPointer uint64
   125  
   126  	// Args contains the first 6 system call arguments.
   127  	Args [6]uint64
   128  }
   129  
   130  // SeccompNotifResp is equivalent to struct seccomp_notif_resp.
   131  //
   132  // +marshal
   133  type SeccompNotifResp struct {
   134  	ID    uint64
   135  	Val   int64
   136  	Error int32
   137  	Flags uint32
   138  }
   139  
   140  // SeccompNotifSizes is equivalent to struct seccomp_notif_sizes.
   141  //
   142  // +marshal
   143  type SeccompNotifSizes struct {
   144  	Notif      uint16
   145  	Notif_resp uint16
   146  	Data       uint16
   147  }
   148  
   149  // SeccompNotif is equivalent to struct seccomp_notif.
   150  //
   151  // +marshal
   152  type SeccompNotif struct {
   153  	ID    uint64
   154  	Pid   int32
   155  	Flags uint32
   156  	Data  SeccompData
   157  }
   158  
   159  // String returns a human-friendly representation of this `SeccompData`.
   160  func (sd SeccompData) String() string {
   161  	return fmt.Sprintf(
   162  		"sysno=%d arch=%#x rip=%#x args=[%#x %#x %#x %#x %#x %#x]",
   163  		sd.Nr,
   164  		sd.Arch,
   165  		sd.InstructionPointer,
   166  		sd.Args[0],
   167  		sd.Args[1],
   168  		sd.Args[2],
   169  		sd.Args[3],
   170  		sd.Args[4],
   171  		sd.Args[5],
   172  	)
   173  }