github.com/david-imola/snapd@v0.0.0-20210611180407-2de8ddeece6d/sandbox/seccomp/seccomp.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2018 Canonical Ltd
     5   *
     6   * This program is free software: you can redistribute it and/or modify
     7   * it under the terms of the GNU General Public License version 3 as
     8   * published by the Free Software Foundation.
     9   *
    10   * This program is distributed in the hope that it will be useful,
    11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13   * GNU General Public License for more details.
    14   *
    15   * You should have received a copy of the GNU General Public License
    16   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17   *
    18   */
    19  
    20  package seccomp
    21  
    22  import (
    23  	"io/ioutil"
    24  	"sort"
    25  	"strings"
    26  	"sync"
    27  )
    28  
    29  var secCompProber = &secCompProbe{}
    30  
    31  // Actions returns a sorted list of seccomp actions like
    32  // []string{"allow", "errno", "kill", "log", "trace", "trap"}.
    33  func Actions() []string {
    34  	return secCompProber.actions()
    35  }
    36  
    37  func SupportsAction(action string) bool {
    38  	actions := Actions()
    39  	i := sort.SearchStrings(actions, action)
    40  	if i < len(actions) && actions[i] == action {
    41  		return true
    42  	}
    43  	return false
    44  }
    45  
    46  // probing
    47  
    48  type secCompProbe struct {
    49  	probedActions []string
    50  
    51  	once sync.Once
    52  }
    53  
    54  func (scp *secCompProbe) actions() []string {
    55  	scp.once.Do(func() {
    56  		scp.probedActions = probeActions()
    57  	})
    58  	return scp.probedActions
    59  }
    60  
    61  var ioutilReadFile = ioutil.ReadFile
    62  
    63  func probeActions() []string {
    64  	contents, err := ioutilReadFile("/proc/sys/kernel/seccomp/actions_avail")
    65  	if err != nil {
    66  		return []string{}
    67  	}
    68  	actions := strings.Split(strings.TrimRight(string(contents), "\n"), " ")
    69  	sort.Strings(actions)
    70  	return actions
    71  }
    72  
    73  // mocking
    74  
    75  func MockActions(actions []string) (restore func()) {
    76  	old := secCompProber
    77  	secCompProber = &secCompProbe{
    78  		probedActions: actions,
    79  	}
    80  	secCompProber.once.Do(func() {})
    81  	return func() {
    82  		secCompProber = old
    83  	}
    84  }