summaryrefslogtreecommitdiff
path: root/utils/isolate.go
diff options
context:
space:
mode:
Diffstat (limited to 'utils/isolate.go')
-rwxr-xr-xutils/isolate.go59
1 files changed, 59 insertions, 0 deletions
diff --git a/utils/isolate.go b/utils/isolate.go
new file mode 100755
index 00000000..b05f4b3a
--- /dev/null
+++ b/utils/isolate.go
@@ -0,0 +1,59 @@
+// +build !windows
+
+package utils
+
+import (
+ "fmt"
+ "os"
+ "os/exec"
+ "os/user"
+ "strconv"
+ "syscall"
+
+ "github.com/spiral/errors"
+)
+
+// IsolateProcess change gpid for the process to avoid bypassing signals to php processes.
+func IsolateProcess(cmd *exec.Cmd) {
+ cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true, Pgid: 0}
+}
+
+// ExecuteFromUser may work only if run RR under root user
+func ExecuteFromUser(cmd *exec.Cmd, u string) error {
+ const op = errors.Op("execute_from_user")
+ usr, err := user.Lookup(u)
+ if err != nil {
+ return errors.E(op, err)
+ }
+
+ usrI32, err := strconv.ParseInt(usr.Uid, 10, 32)
+ if err != nil {
+ return errors.E(op, err)
+ }
+
+ grI32, err := strconv.ParseInt(usr.Gid, 10, 32)
+ if err != nil {
+ return errors.E(op, err)
+ }
+
+ // For more information:
+ // https://www.man7.org/linux/man-pages/man7/user_namespaces.7.html
+ // https://www.man7.org/linux/man-pages/man7/namespaces.7.html
+ if _, err := os.Stat("/proc/self/ns/user"); err != nil {
+ if os.IsNotExist(err) {
+ return fmt.Errorf("kernel doesn't support user namespaces")
+ }
+ if os.IsPermission(err) {
+ return fmt.Errorf("unable to test user namespaces due to permissions")
+ }
+
+ return errors.E(op, errors.Errorf("failed to stat /proc/self/ns/user: %v", err))
+ }
+
+ cmd.SysProcAttr.Credential = &syscall.Credential{
+ Uid: uint32(usrI32),
+ Gid: uint32(grI32),
+ }
+
+ return nil
+}