summaryrefslogtreecommitdiff
path: root/vendor/github.com/sarnowski/mitigation/mitigation.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/sarnowski/mitigation/mitigation.go')
-rw-r--r--vendor/github.com/sarnowski/mitigation/mitigation.go118
1 files changed, 118 insertions, 0 deletions
diff --git a/vendor/github.com/sarnowski/mitigation/mitigation.go b/vendor/github.com/sarnowski/mitigation/mitigation.go
new file mode 100644
index 0000000..a1110e4
--- /dev/null
+++ b/vendor/github.com/sarnowski/mitigation/mitigation.go
@@ -0,0 +1,118 @@
+/*
+Package mitigation provides the possibility to prevent damage through bugs or exploits.
+
+The package uses multiple techniques to mitigate damage:
+ - privilege revocation: switch to an unprivileged user
+ - chroot jail: restrict filesystem access
+ - defined environment: reset all environment variables
+
+The following prerequisites are nessecary:
+ - The application must run as root
+ - You need to provide a valid user id
+ - You need to provide a valid group id
+ - You need to provide an existing path
+
+Activate() will not return any error. It will panic as soon as anything
+goes wrong because there is no good way to recover. To provide a sensible
+fallback you can use the CanActivate() function.
+
+WARNING: Windows is not supported. Windows has no equivalents for the used
+techniques.
+
+WARNING: Linux is not POSIX compatible and therefor setuid() only changes the
+user ID of the current thread. At the time, there is no way to safely use
+this within go as there may already be other threads spawned at the time
+this library is called. More about this issue here:
+ http://code.google.com/p/go/issues/detail?id=1435
+ http://groups.google.com/group/golang-nuts/browse_thread/thread/059597aafdd84a0e
+
+The following table summarizes the behaviours:
+ openbsd: safe
+ freebsd: safe
+ darwin: safe
+ linux: unsafe
+ windows: not supported
+
+*/
+package mitigation
+
+import (
+ "os"
+ "runtime"
+ "syscall"
+)
+
+// Checks if it is possible to activate the mitigation.
+func CanActivate() bool {
+ if runtime.GOOS == "windows" || runtime.GOARCH == "arm" {
+ return false
+ }
+
+ uid := syscall.Getuid()
+ return uid == 0
+}
+
+// Activates the mitigation measurements.
+func Activate(uid int, gid int, path string) {
+ if !CanActivate() {
+ panic("Cannot activate mitigation measurements!")
+ }
+
+ // chroot directory
+ err := syscall.Chroot(path)
+ if err != nil {
+ panic(err)
+ }
+
+ // change directory to new /
+ err = syscall.Chdir("/")
+ if err != nil {
+ panic(err)
+ }
+
+ // drop all other groups
+ err = syscall.Setgroups([]int{gid})
+ if err != nil {
+ panic(err)
+ }
+
+ // verify the empty group list
+ gids, err := syscall.Getgroups()
+ if err != nil {
+ panic("Could not read groups!")
+ }
+ if len(gids) > 1 {
+ panic("Could not drop groups!")
+ } else if len(gids) == 1 {
+ if gids[0] != gid {
+ panic("Could not drop foreign groups!")
+ }
+ }
+
+ // change group
+ err = syscall.Setgid(gid)
+ if err != nil {
+ panic(err)
+ }
+
+ // verify the group change
+ ngid := syscall.Getgid()
+ if ngid != gid {
+ panic("Could not change group id!")
+ }
+
+ // change user
+ err = syscall.Setuid(uid)
+ if err != nil {
+ panic(err)
+ }
+
+ // verify the user change
+ nuid := syscall.Getuid()
+ if nuid != uid {
+ panic("Could not change user id!")
+ }
+
+ // now drop all environment variables
+ os.Clearenv()
+}