2020-05-08 07:36:29 -06:00
|
|
|
/*
|
2020-05-08 07:55:32 -06:00
|
|
|
Package protect is a wrapper for OpenBSD's pledge(2) and unveil(2) system
|
|
|
|
calls.
|
2020-05-08 07:36:29 -06:00
|
|
|
|
2020-05-08 07:55:32 -06:00
|
|
|
This library is trivial, but I found myself writing it often enough that I
|
|
|
|
figure it should be a package.
|
2020-05-08 07:36:29 -06:00
|
|
|
*/
|
|
|
|
package protect
|
|
|
|
|
2021-07-08 08:49:24 -06:00
|
|
|
import (
|
|
|
|
"regexp"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
2023-03-21 06:49:24 -06:00
|
|
|
// Unveil is a wrapper for OpenBSD's unveil(2) and Linux's LandLock. Both of
|
|
|
|
// which are used to limit a processes view of the filesystem.
|
2020-05-08 07:36:29 -06:00
|
|
|
//
|
|
|
|
// The first call to Unveil removes a processes visibility to everything
|
|
|
|
// except 'path'. Any subsequent calls expand the view to contain those
|
|
|
|
// paths. Finally a call to UnveilBlock will lock the view in place.
|
|
|
|
// Preventing access to anything else.
|
|
|
|
//
|
|
|
|
// On non-OpenBSD machines this call is a noop.
|
2020-05-10 07:04:34 -06:00
|
|
|
func Unveil(path string, flags string) error {
|
|
|
|
return unveil(path, flags)
|
2020-05-08 07:55:32 -06:00
|
|
|
}
|
2020-05-08 07:36:29 -06:00
|
|
|
|
2021-09-21 16:30:41 -06:00
|
|
|
// UnveilSet takes a set of Unveils and runs them all, returning the first
|
|
|
|
// error encountered. Optionally call UnveilBlock at the end.
|
|
|
|
func UnveilSet(set map[string]string, block bool) error {
|
|
|
|
for p, s := range set {
|
|
|
|
err := Unveil(p, s)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if block {
|
|
|
|
return UnveilBlock()
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-05-08 07:36:29 -06:00
|
|
|
// UnveilBlock locks the Unveil'd paths. Preventing further changes to a
|
|
|
|
// processes filesystem view.
|
|
|
|
//
|
2023-03-21 06:49:24 -06:00
|
|
|
// On non-OpenBSD,Linux machines this call is a noop.
|
2020-05-08 07:55:32 -06:00
|
|
|
func UnveilBlock() error {
|
|
|
|
return unveilBlock()
|
|
|
|
}
|
2020-05-08 07:36:29 -06:00
|
|
|
|
|
|
|
// Pledge wraps OpenBSD's pledge(2) system call. One can use this to limit
|
|
|
|
// the system calls a process can make.
|
|
|
|
//
|
|
|
|
// On non-OpenBSD machines this call is a noop.
|
2020-05-10 07:04:34 -06:00
|
|
|
func Pledge(promises string) error {
|
|
|
|
return pledge(promises)
|
2020-05-08 07:55:32 -06:00
|
|
|
}
|
2021-07-08 08:49:24 -06:00
|
|
|
|
|
|
|
// ReducePledges takes the current list of plpedges and a list of pledges that
|
|
|
|
// should be removed. The new list is returned and Pledge() will be called
|
|
|
|
// with the reduced set of pledges.
|
|
|
|
func ReducePledges(current, toRemove string) (string, error) {
|
|
|
|
newPledges, err := reduce(current, toRemove)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
return newPledges, pledge(newPledges)
|
|
|
|
}
|
|
|
|
|
|
|
|
func reduce(a, b string) (string, error) {
|
|
|
|
var newList []string
|
|
|
|
currentList := strings.Split(a, " ")
|
|
|
|
|
|
|
|
for _, s := range currentList {
|
|
|
|
match, err := regexp.MatchString(s, b)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
if !match {
|
|
|
|
newList = append(newList, s)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return strings.Join(newList, " "), nil
|
|
|
|
}
|