Exemplo n.º 1
1
func childMain() error {
	var err error

	pipe := os.NewFile(uintptr(3), "pipe")
	if pipe != nil {
		defer pipe.Close()
		if err == nil {
			pipe.Write([]byte{DaemonSuccess})
		} else {
			pipe.Write([]byte{DaemonFailure})
		}
	}

	signal.Ignore(syscall.SIGCHLD)

	syscall.Close(0)
	syscall.Close(1)
	syscall.Close(2)

	syscall.Setsid()
	syscall.Umask(022)

	// syscall.Chdir("/")

	return nil
}
Exemplo n.º 2
0
func doChildDaemon() {
	sid, err := syscall.Setsid()
	if sid < 0 || err != nil {
		log.Println("Error setting sid ", err)
		os.Exit(-1)
	}
}
Exemplo n.º 3
0
func PreRunService() {
	fmt.Println("Starting server!")
	ret, _, errNo := syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)
	if errNo != 0 {
		panic(errors.New(fmt.Sprintf("Fork failed err: %d ", errNo)))
	} else {
		return
	}
	switch ret {
	case 0:
		break
	default:
		os.Exit(0)
	}
	sid, err := syscall.Setsid()
	utilities.CheckError(err)
	if sid == -1 {
		os.Exit(-1)
	}

	router := mux.NewRouter().StrictSlash(true)
	router.HandleFunc("/", Index)
	router.HandleFunc("/ls", GetFileList)
	router.HandleFunc("/file", GetFile)
	router.HandleFunc("/tunnel", GetTunnel)

	defer log.Fatal(http.ListenAndServe(":5922", router))
	fmt.Println("WTF!")
}
Exemplo n.º 4
0
// func Reborn daemonize process. Function Reborn calls ForkExec
// in the parent process and terminates him. In the child process,
// function sets umask, work dir and calls Setsid. Function sets
// for child process environment variable _GO_DAEMON=1 - the mark,
// might used for debug.
func Reborn(umask uint32, workDir string) (err error) {

	if !WasReborn() {
		// parent process - fork and exec
		var path string
		if path, err = filepath.Abs(os.Args[0]); err != nil {
			return
		}

		cmd := prepareCommand(path)

		if err = cmd.Start(); err != nil {
			return
		}

		os.Exit(0)
	}

	// child process - daemon
	syscall.Umask(int(umask))

	if len(workDir) != 0 {
		if err = os.Chdir(workDir); err != nil {
			return
		}
	}

	_, err = syscall.Setsid()

	// Do not required redirect std
	// to /dev/null, this work was
	// done function ForkExec

	return
}
Exemplo n.º 5
0
func Daemonize() (e error) {
	// var ret, err uintptr
	ret, _, err := syscall.Syscall(syscall.SYS_FORK, 0, 0, 0)
	if err != 0 {
		return fmt.Errorf("fork error: %d", err)
	}
	if ret != 0 {
		// Parent
		os.Exit(0)
	}

	// We are now child

	if err, _ := syscall.Setsid(); err < 0 {
		return fmt.Errorf("setsid error: %d", err)
	}

	os.Chdir("/")
	f, e := os.OpenFile(os.DevNull, os.O_RDWR, 0)
	if e != nil {
		return
	}
	fd := int(f.Fd())
	syscall.Dup2(fd, int(os.Stdin.Fd()))
	syscall.Dup2(fd, int(os.Stdout.Fd()))
	syscall.Dup2(fd, int(os.Stderr.Fd()))

	return nil
}
Exemplo n.º 6
0
func daemon(nochdir, noclose int) int {
	var ret, ret2 uintptr
	var err syscall.Errno

	darwin := runtime.GOOS == "darwin"

	// already a daemon
	if syscall.Getppid() == 1 {
		return 0
	}

	// fork off the parent process
	ret, ret2, err = syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)
	if err != 0 {
		return -1
	}

	// failure
	if ret2 < 0 {
		os.Exit(-1)
	}

	// handle exception for darwin
	if darwin && ret2 == 1 {
		ret = 0
	}

	// if we got a good PID, then we call exit the parent process.
	if ret > 0 {
		os.Exit(0)
	}

	/* Change the file mode mask */
	_ = syscall.Umask(0)

	// create a new SID for the child process
	s_ret, s_errno := syscall.Setsid()
	if s_errno != nil {
		log.Printf("Error: syscall.Setsid errno: %d", s_errno)
	}
	if s_ret < 0 {
		return -1
	}

	if nochdir == 0 {
		os.Chdir("/")
	}

	if noclose == 0 {
		f, e := os.OpenFile("/dev/null", os.O_RDWR, 0)
		if e == nil {
			fd := f.Fd()
			syscall.Dup2(int(fd), int(os.Stdin.Fd()))
			syscall.Dup2(int(fd), int(os.Stdout.Fd()))
			syscall.Dup2(int(fd), int(os.Stderr.Fd()))
		}
	}

	return 0
}
Exemplo n.º 7
0
func daemon(nochdir, noclose int) int {
	var ret uintptr
	var err syscall.Errno

	ret, _, err = syscall.Syscall(syscall.SYS_FORK, 0, 0, 0)
	if err != 0 {
		return -1
	}
	switch ret {
	case 0:
		break
	default:
		os.Exit(0)
	}
	pid, _ := syscall.Setsid()
	if pid == -1 {
		return -1
	}
	if nochdir == 0 {
		os.Chdir("/")
	}
	if noclose == 0 {
		f, e := os.Open("/dev/null")
		if e == nil {
			fd := int(f.Fd())
			syscall.Dup2(fd, int(os.Stdin.Fd()))
			syscall.Dup2(fd, int(os.Stdout.Fd()))
			syscall.Dup2(fd, int(os.Stderr.Fd()))
		}
	}
	return 0
}
Exemplo n.º 8
0
func (this torUtil) SetDaemonMode(nochdir, noclose int) int {
	if syscall.Getppid() == 1 {
		return 0
	}
	ret, ret2, err := syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)
	if err != 0 {
		return -1
	}
	if ret2 < 0 {
		os.Exit(-1)
	}
	if ret > 0 {
		os.Exit(0)
	}
	syscall.Umask(0)
	s_ret, s_errno := syscall.Setsid()
	if s_ret < 0 {
		return -1
	}
	if nochdir == 0 {
		os.Chdir("/")
	}
	if noclose == 0 {
		f, e := os.OpenFile("/dev/null", os.O_RDWR, 0)
		if e == nil {
			fd := f.Fd()
			syscall.Dup2(int(fd), int(os.Stdin.Fd()))
			syscall.Dup2(int(fd), int(os.Stdout.Fd()))
			syscall.Dup2(int(fd), int(os.Stderr.Fd()))
		}
	}
	return 0
}
Exemplo n.º 9
0
func afterDaemonize(err error) {
	// Ignore SIGCHLD signal
	signal.Ignore(syscall.SIGCHLD)

	// Close STDOUT, STDIN, STDERR
	syscall.Close(0)
	syscall.Close(1)
	syscall.Close(2)

	// Become the process group leader
	syscall.Setsid()

	// // Clear umask
	syscall.Umask(022)

	// // chdir for root directory
	syscall.Chdir("/")

	// Notify that the child process started successfuly
	pipe := os.NewFile(uintptr(3), "pipe")
	if pipe != nil {
		defer pipe.Close()
		if err == nil {
			pipe.Write([]byte{DAEMONIZE_SUCCESS})
		} else {
			pipe.Write([]byte{DAEMONIZE_FAIL})
		}
	}
}
Exemplo n.º 10
0
// This function wraps application with daemonization.
// Returns isDaemon value to distinguish parent and daemonized processes.
func Daemonize() (isDaemon bool, err error) {
	const errLoc = "daemonigo.Daemonize()"
	isDaemon = os.Getenv(EnvVarName) == EnvVarValue
	log.Println("IsDaemon: ", isDaemon)
	if WorkDir != "" {
		if err = os.Chdir(WorkDir); err != nil {
			err = fmt.Errorf(
				"%s: changing working directory failed, reason -> %s",
				errLoc, err.Error(),
			)
			return
		}
	}
	if isDaemon {
		oldmask := syscall.Umask(int(Umask))
		defer syscall.Umask(oldmask)
		if _, err = syscall.Setsid(); err != nil {
			err = fmt.Errorf(
				"%s: setsid failed, reason -> %s", errLoc, err.Error(),
			)
			return
		}
		if pidFile, err = lockPidFile(); err != nil {
			err = fmt.Errorf(
				"%s: locking PID file failed, reason -> %s",
				errLoc, err.Error(),
			)
		}
	} else {
		flag.Usage = func() {
			arr := make([]string, 0, len(actions))
			for k, _ := range actions {
				arr = append(arr, k)
			}
			fmt.Fprintf(os.Stderr, "Usage: %s {%s}\n",
				os.Args[0], strings.Join(arr, "|"),
			)
			flag.PrintDefaults()
		}

		if !flag.Parsed() {
			log.Printf(" flag.Parse\n")
			flag.Parse()
		}
		//fmt.Printf("after flag.Parse\n")
		//fmt.Printf("flag.Arg(0):%s\n", flag.Arg(0))

		//action, exist := actions[flag.Arg(0)]
		action, exist := actions["daemon"]
		//fmt.Println("exist:", exist)
		if exist {
			action()
		} else {
			flag.Usage()
		}

	}
	return
}
Exemplo n.º 11
0
func _not_work_Fork(closeno bool) (pid int, err error) {
	// don't run this
	// not work with go threads
	// see: http://code.google.com/p/go/issues/detail?id=227

	darwin := runtime.GOOS == "darwin"

	// already a daemon
	if syscall.Getppid() == 1 {
		return 0, nil
	}

	// fork off the parent process
	ret, ret2, errno := syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)

	if errno != 0 {
		return -1, fmt.Errorf("Fork failure: %s", errno)
	}

	// failure
	if ret2 < 0 {
		return -1, fmt.Errorf("Fork failure")
	}

	// handle exception for darwin
	if darwin && ret2 == 1 {
		ret = 0
	}

	// if we got a good PID, then we call exit the parent process.
	if ret > 0 {
		return 0, nil
	}

	// create a new SID for the child process
	s_ret, s_errno := syscall.Setsid()
	if s_errno != nil {
		return -1, fmt.Errorf("Error: syscall.Setsid: %s", s_errno)
	}
	if s_ret < 0 {
		return -1, fmt.Errorf("Error: syscall.Setsid: %s", s_errno)
	}

	if closeno {
		f, e := os.OpenFile("/dev/null", os.O_RDWR, 0)
		if e == nil {
			fd := int(f.Fd())
			syscall.Dup2(fd, int(os.Stdin.Fd()))
			syscall.Dup2(fd, int(os.Stdout.Fd()))
			syscall.Dup2(fd, int(os.Stderr.Fd()))
		}
	}

	return os.Getpid(), nil
}
Exemplo n.º 12
0
Arquivo: main.go Projeto: cuiwm/reborn
func main() {
	// create a new session to prevent receiving signals from parent
	syscall.Setsid()

	cmd := os.Args[1]
	args := os.Args[2:]
	c := exec.Command(cmd, args...)
	c.Stdout = os.Stdout
	c.Stderr = os.Stderr

	c.Start()
	os.Exit(0)
}
Exemplo n.º 13
0
Arquivo: daemon.go Projeto: shaovie/go
func daemon() error {
	isDarwin := runtime.GOOS == "darwin"

	// already a daemon
	if syscall.Getppid() == 1 {
		return nil
	}

	// fork off the parent process
	ret, ret2, errno := syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)
	if errno != 0 {
		return errors.New(fmt.Sprintf("fork error! [errno=%d]", errno))
	}

	// failure
	if ret2 < 0 {
		os.Exit(1)
	}

	// handle exception for darwin
	if isDarwin && ret2 == 1 {
		ret = 0
	}

	// if we got a good PID, then we call exit the parent process.
	if int(ret) > 0 {
		os.Exit(0)
	}

	syscall.Umask(0)

	// create a new SID for the child process
	_, err := syscall.Setsid()
	if err != nil {
		return err
	}

	//os.Chdir("/")

	f, err := os.OpenFile("/dev/null", os.O_RDWR, 0)
	if err == nil {
		fd := f.Fd()
		syscall.Dup2(int(fd), int(os.Stdin.Fd()))
		syscall.Dup2(int(fd), int(os.Stdout.Fd()))
		syscall.Dup2(int(fd), int(os.Stderr.Fd()))
	}
	return nil
}
Exemplo n.º 14
0
func (executeLinuxProcForkChildImpl *executeLinuxProcForkChildImpl) Exec(cmdLine string, dir string) error {
	executeLinuxProc := executeLinuxProcStartProcessImpl{}
	pid, _, errno := syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)
	if errno != 0 {
		return syscall.Errno(errno)
	}

	if pid > 0 {
		puid := int(pid)
		processInfo, _ := os.FindProcess(puid)
		if nil != processInfo {
			_, err := processInfo.Wait()
			if nil != err {
				log.WriteLog("Error: find process %s", err.Error())
			}
		}
		return nil
	} else if pid < 0 {
		return errors.New("fork error")
	}

	// pid1, _, errno1 := syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)
	// if errno1 != 0 {
	// 	os.Exit(0)
	// 	return errors.New("fork error")
	// }
	// if pid1 > 0 {
	// 	os.Exit(0)
	// 	return nil
	// } else if pid1 < 0 {
	// 	os.Exit(0)
	// 	return errors.New("fork error")
	// }
	_ = syscall.Umask(0)
	_, s_errno := syscall.Setsid()
	if s_errno != nil {
		log.WriteLog("Error: syscall.Setsid errno: %d", s_errno)
	}
	os.Chdir("/")
	result := executeLinuxProc.Exec(cmdLine, dir)
	os.Exit(0)
	return result
}
Exemplo n.º 15
0
func Daemon(nochdir int) error {
	signal.Ignore(syscall.SIGINT, syscall.SIGHUP, syscall.SIGPIPE)

	if syscall.Getppid() == 1 {
		return nil
	}

	ret1, ret2, eno := syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)
	if eno != 0 || ret2 < 0 {
		return errors.New("Fork fail")
	}

	/* exit parent */
	if ret1 > 0 {
		os.Exit(0)
	}

	_ = syscall.Umask(0)

	ret, err := syscall.Setsid()
	if ret < 0 || err != nil {
		return errors.New("Set sid failed")
	}

	if nochdir == 0 {
		err = os.Chdir("/")
		if err != nil {
			return errors.New("Chdir failed")
		}
	}

	file, err := os.OpenFile("/dev/null", os.O_RDWR, 0)
	if err == nil {
		fd := file.Fd()
		syscall.Dup2(int(fd), int(os.Stdin.Fd()))
		syscall.Dup2(int(fd), int(os.Stdout.Fd()))
		//	syscall.Dup2(int(fd), int(os.Stderr.Fd()))
	}

	return nil
}
Exemplo n.º 16
0
func Daemonize() (int, error) {

	// create a subprocess
	pid, err := Fork(false)
	if err != nil {
		return -1, err
	} else if pid > 0 {
		// return the parent
		return int(pid), nil
	}

	// exit the created one, create the daemon
	_, err = Fork(true)
	if err != nil {
		os.Exit(-1)
	}

	//Change the file mode mask
	_ = syscall.Umask(0)

	// create a new SID for the child process
	s_ret, err := syscall.Setsid()
	if err != nil {
		os.Exit(-1)
	}
	if s_ret < 0 {
		os.Exit(-1)
	}

	os.Chdir("/")

	f, e := os.OpenFile("/dev/null", os.O_RDWR, 0)
	if e == nil {
		fd := f.Fd()
		syscall.Dup2(int(fd), int(os.Stdin.Fd()))
		syscall.Dup2(int(fd), int(os.Stdout.Fd()))
		syscall.Dup2(int(fd), int(os.Stderr.Fd()))
	}

	return 0, nil
}
Exemplo n.º 17
0
// Daemonizes but doesn't fork.
//
// The stdin, stdout and, unless keepStderr is specified, stderr fds are
// remapped to /dev/null. setsid is called.
//
// The process changes its current directory to /.
//
// If you intend to call DropPrivileges, call it after calling this function,
// as /dev/null will no longer be available after privileges are dropped.
func Daemonize(keepStderr bool) error {
	null_f, err := os.OpenFile("/dev/null", os.O_RDWR, 0)
	if err != nil {
		return err
	}
	defer null_f.Close()

	stdin_fd := int(os.Stdin.Fd())
	stdout_fd := int(os.Stdout.Fd())
	stderr_fd := int(os.Stderr.Fd())

	// ... reopen fds 0, 1, 2 as /dev/null ...
	// Since dup2 closes fds which are already open we needn't close the above fds.
	// This lets us avoid race conditions.
	null_fd := int(null_f.Fd())
	err = dupfd.Dup2(null_fd, stdin_fd)
	if err != nil {
		return err
	}

	err = dupfd.Dup2(null_fd, stdout_fd)
	if err != nil {
		return err
	}

	if !keepStderr {
		err = dupfd.Dup2(null_fd, stderr_fd)
		if err != nil {
			return err
		}

		haveStderr = false
	}

	// This may fail if we're not root
	syscall.Setsid()

	// Daemonize implies Init.
	return Init()
}
Exemplo n.º 18
0
Arquivo: daemon.go Projeto: leicc/web
func Daemon(chdir bool, clstd bool) (err error) {
	var ret1, ret2 uintptr
	var er syscall.Errno

	darwin := runtime.GOOS == "darwin"
	if syscall.Getppid() == 1 {
		return
	}
	ret1, ret2, er = syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)
	if er != 0 {
		err = errors.New("daemon fork fail")
		return
	}
	if ret2 < 0 {
		err = errors.New("fork return fail")
		os.Exit(-1)
	}
	if darwin && ret2 == 1 {
		ret1 = 0
	}
	if ret1 > 0 {
		os.Exit(0)
	}
	syscall.Umask(0)
	syscall.Setsid()
	if chdir {
		os.Chdir("/")
	}
	if clstd {
		fs, err := os.OpenFile(os.DevNull, os.O_RDWR, 0)
		if err == nil {
			fd := fs.Fd()
			syscall.Dup2(int(fd), int(os.Stdin.Fd()))
			syscall.Dup2(int(fd), int(os.Stdout.Fd()))
			syscall.Dup2(int(fd), int(os.Stderr.Fd()))
		}
	}
	return
}
Exemplo n.º 19
0
Arquivo: main.go Projeto: jdp/lineup
func daemonize(server *Server) {
	pid, err := os.ForkExec("lineupd", []string{}, []string{}, "/var/run", []*os.File{});
	if err != nil {
		server.Logger().Logf("couldn't fork: %s\n", err);
		os.Exit(1);
	}
	server.Logger().Logf("%d->%d\n", os.Getpid(), pid);
	if (pid < 0) {
		os.Exit(1);
	}
	if (pid > 0) {
		os.Exit(0);
	}
	syscall.Setsid();
	for i := 0; i < 3; i++ {
		syscall.Close(i);
	}
	for i := 0; i < 3; i++ {
		syscall.Open("/dev/null", os.O_RDWR, 0644);
	}
	syscall.Umask(027);
	syscall.Chdir("/var/run");
}
Exemplo n.º 20
0
func Reborn(umask uint32, workDir string) (err error) {
	if !WasReborn() {
		var path string
		if path, err = filepath.Abs(os.Args[0]); err != nil {
			return
		}
		cmd := exec.Command(path, os.Args[1:]...)
		envVar := fmt.Sprintf("%s=%s", envVarName, envVarValue)
		cmd.Env = append(os.Environ(), envVar)
		if err = cmd.Start(); err != nil {
			return
		}
		os.Exit(0)
	}
	syscall.Umask(int(umask))
	if len(workDir) == 0 {
		if err = os.Chdir(workDir); err != nil {
			return
		}
	}
	_, err = syscall.Setsid()
	return
}
Exemplo n.º 21
0
func childMain() {
	// 初期化処理があればここに
	var err error

	// 子プロセスの起動状態を親プロセスに通知する
	pipe := os.NewFile(uintptr(3), "pipe")
	if pipe != nil {
		defer pipe.Close()
		if err == nil {
			pipe.Write([]byte{DAEMON_SUCCESS})
		} else {
			pipe.Write([]byte{DAEMON_FAIL})
		}
	}

	// SIGCHILDを無視する
	signal.Ignore(syscall.SIGCHLD)

	// STDOUT, STDIN, STDERRをクローズ
	syscall.Close(0)
	syscall.Close(1)
	syscall.Close(2)

	// プロセスグループリーダーになる
	syscall.Setsid()

	// Umaskをクリア
	syscall.Umask(022)

	// / にchdirする
	syscall.Chdir("/")

	// main loop
	for {
		time.Sleep(1000 * time.Millisecond)
	}
}
Exemplo n.º 22
0
func (l *linuxStandardInit) Init() error {
	// do not inherit the parent's session keyring
	sessKeyId, err := keyctl.JoinSessionKeyring("")
	if err != nil {
		return err
	}
	// make session keyring searcheable
	// without user ns we need 'UID' search permissions
	// with user ns we need 'other' search permissions
	if err := keyctl.ModKeyringPerm(sessKeyId, 0xffffffff, 0x080008); err != nil {
		return err
	}

	// join any namespaces via a path to the namespace fd if provided
	if err := joinExistingNamespaces(l.config.Config.Namespaces); err != nil {
		return err
	}
	var console *linuxConsole
	if l.config.Console != "" {
		console = newConsoleFromPath(l.config.Console)
		if err := console.dupStdio(); err != nil {
			return err
		}
	}
	if _, err := syscall.Setsid(); err != nil {
		return err
	}
	if console != nil {
		if err := system.Setctty(); err != nil {
			return err
		}
	}
	if err := setupNetwork(l.config); err != nil {
		return err
	}
	if err := setupRoute(l.config.Config); err != nil {
		return err
	}
	if err := setupRlimits(l.config.Config); err != nil {
		return err
	}
	if err := setOomScoreAdj(l.config.Config.OomScoreAdj); err != nil {
		return err
	}
	label.Init()
	// InitializeMountNamespace() can be executed only for a new mount namespace
	if l.config.Config.Namespaces.Contains(configs.NEWNS) {
		if err := setupRootfs(l.config.Config, console); err != nil {
			return err
		}
	}
	if hostname := l.config.Config.Hostname; hostname != "" {
		if err := syscall.Sethostname([]byte(hostname)); err != nil {
			return err
		}
	}
	if err := apparmor.ApplyProfile(l.config.Config.AppArmorProfile); err != nil {
		return err
	}
	if err := label.SetProcessLabel(l.config.Config.ProcessLabel); err != nil {
		return err
	}

	for key, value := range l.config.Config.Sysctl {
		if err := writeSystemProperty(key, value); err != nil {
			return err
		}
	}
	for _, path := range l.config.Config.ReadonlyPaths {
		if err := remountReadonly(path); err != nil {
			return err
		}
	}
	for _, path := range l.config.Config.MaskPaths {
		if err := maskFile(path); err != nil {
			return err
		}
	}
	pdeath, err := system.GetParentDeathSignal()
	if err != nil {
		return err
	}
	if l.config.Config.NoNewPrivileges {
		if err := system.Prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); err != nil {
			return err
		}
	}
	// Tell our parent that we're ready to Execv. This must be done before the
	// Seccomp rules have been applied, because we need to be able to read and
	// write to a socket.
	if err := syncParentReady(l.pipe); err != nil {
		return err
	}
	if l.config.Config.Seccomp != nil {
		if err := seccomp.InitSeccomp(l.config.Config.Seccomp); err != nil {
			return err
		}
	}
	if err := finalizeNamespace(l.config); err != nil {
		return err
	}
	// finalizeNamespace can change user/group which clears the parent death
	// signal, so we restore it here.
	if err := pdeath.Restore(); err != nil {
		return err
	}
	// compare the parent from the inital start of the init process and make sure that it did not change.
	// if the parent changes that means it died and we were reparened to something else so we should
	// just kill ourself and not cause problems for someone else.
	if syscall.Getppid() != l.parentPid {
		return syscall.Kill(syscall.Getpid(), syscall.SIGKILL)
	}

	return system.Execv(l.config.Args[0], l.config.Args[0:], os.Environ())
}
Exemplo n.º 23
0
func Daemon(pfile, lfile string, uid, gid, nochdir, noclose int) int {
	if syscall.Getppid() == 1 {
		return 0
	}

	ret, mret, errno := syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)
	if errno != 0 {
		return -1
	}

	if mret < 0 {
		os.Exit(-1)
	}

	if runtime.GOOS == "darwin" && mret == 1 {
		ret = 0
	}

	if ret > 0 {
		os.Exit(0)
	}

	_ = syscall.Umask(0)
	s_ret, err := syscall.Setsid()
	if err != nil {
		panic(err)
	}

	if s_ret < 0 {
		return -1
	}

	err = WriteFile(pfile, fmt.Sprintf("%d\n", os.Getpid()))
	if err != nil {
		panic(err)
	}

	/*
	   err = syscall.Setgid(gid)
	   if err != nil {
	       panic(err)
	   }

	   err = syscall.Setuid(uid)
	   if err != nil {
	       panic(err)
	   }
	*/

	if nochdir == 0 {
		os.Chdir("/")
	}

	if noclose == 0 {
		fp, err := os.OpenFile(lfile, os.O_RDWR|os.O_APPEND, 0)
		if err != nil {
			panic(err)
		}

		fd := fp.Fd()
		syscall.Dup2(int(fd), int(os.Stdin.Fd()))
		syscall.Dup2(int(fd), int(os.Stdout.Fd()))
		syscall.Dup2(int(fd), int(os.Stderr.Fd()))
	}

	return 0
}
Exemplo n.º 24
0
func (l *linuxStandardInit) Init() error {
	// join any namespaces via a path to the namespace fd if provided
	if err := joinExistingNamespaces(l.config.Config.Namespaces); err != nil {
		return err
	}
	var console *linuxConsole
	if l.config.Console != "" {
		console = newConsoleFromPath(l.config.Console)
		if err := console.dupStdio(); err != nil {
			return err
		}
	}
	if _, err := syscall.Setsid(); err != nil {
		return err
	}
	if console != nil {
		if err := system.Setctty(); err != nil {
			return err
		}
	}
	if err := setupNetwork(l.config); err != nil {
		return err
	}
	if err := setupRoute(l.config.Config); err != nil {
		return err
	}
	if err := setupRlimits(l.config.Config); err != nil {
		return err
	}
	label.Init()
	// InitializeMountNamespace() can be executed only for a new mount namespace
	if l.config.Config.Namespaces.Contains(configs.NEWNS) {
		if err := setupRootfs(l.config.Config, console); err != nil {
			return err
		}
	}
	if hostname := l.config.Config.Hostname; hostname != "" {
		if err := syscall.Sethostname([]byte(hostname)); err != nil {
			return err
		}
	}
	if err := apparmor.ApplyProfile(l.config.Config.AppArmorProfile); err != nil {
		return err
	}
	if err := label.SetProcessLabel(l.config.Config.ProcessLabel); err != nil {
		return err
	}

	for key, value := range l.config.Config.Sysctl {
		if err := writeSystemProperty(key, value); err != nil {
			return err
		}
	}

	for _, path := range l.config.Config.ReadonlyPaths {
		if err := remountReadonly(path); err != nil {
			return err
		}
	}
	for _, path := range l.config.Config.MaskPaths {
		if err := maskFile(path); err != nil {
			return err
		}
	}
	pdeath, err := system.GetParentDeathSignal()
	if err != nil {
		return err
	}
	if l.config.Config.Seccomp != nil {
		if err := seccomp.InitSeccomp(l.config.Config.Seccomp); err != nil {
			return err
		}
	}
	if err := finalizeNamespace(l.config); err != nil {
		return err
	}
	// finalizeNamespace can change user/group which clears the parent death
	// signal, so we restore it here.
	if err := pdeath.Restore(); err != nil {
		return err
	}
	// compare the parent from the inital start of the init process and make sure that it did not change.
	// if the parent changes that means it died and we were reparened to something else so we should
	// just kill ourself and not cause problems for someone else.
	if syscall.Getppid() != l.parentPid {
		return syscall.Kill(syscall.Getpid(), syscall.SIGKILL)
	}
	return system.Execv(l.config.Args[0], l.config.Args[0:], os.Environ())
}
func (l *linuxStandardInit) Init() error {
	// join any namespaces via a path to the namespace fd if provided
	if err := joinExistingNamespaces(l.config.Config.Namespaces); err != nil {
		return err
	}
	var console *linuxConsole
	if l.config.Console != "" {
		console = newConsoleFromPath(l.config.Console)
		if err := console.dupStdio(); err != nil {
			return err
		}
	}
	if _, err := syscall.Setsid(); err != nil {
		return err
	}
	if console != nil {
		if err := system.Setctty(); err != nil {
			return err
		}
	}
	if err := setupNetwork(l.config); err != nil {
		return err
	}
	if err := setupRoute(l.config.Config); err != nil {
		return err
	}
	if err := setupRlimits(l.config.Config); err != nil {
		return err
	}
	label.Init()
	// InitializeMountNamespace() can be executed only for a new mount namespace
	if l.config.Config.Namespaces.Contains(configs.NEWNS) {
		if err := setupRootfs(l.config.Config, console); err != nil {
			return err
		}
	}
	if hostname := l.config.Config.Hostname; hostname != "" {
		if err := syscall.Sethostname([]byte(hostname)); err != nil {
			return err
		}
	}
	if err := apparmor.ApplyProfile(l.config.Config.AppArmorProfile); err != nil {
		return err
	}
	if err := label.SetProcessLabel(l.config.Config.ProcessLabel); err != nil {
		return err
	}
	for _, path := range l.config.Config.ReadonlyPaths {
		if err := remountReadonly(path); err != nil {
			return err
		}
	}
	for _, path := range l.config.Config.MaskPaths {
		if err := maskFile(path); err != nil {
			return err
		}
	}
	pdeath, err := system.GetParentDeathSignal()
	if err != nil {
		return err
	}
	if err := finalizeNamespace(l.config); err != nil {
		return err
	}
	// finalizeNamespace can change user/group which clears the parent death
	// signal, so we restore it here.
	if err := pdeath.Restore(); err != nil {
		return err
	}
	// Signal self if parent is already dead. Does nothing if running in a new
	// PID namespace, as Getppid will always return 0.
	if syscall.Getppid() == 1 {
		return syscall.Kill(syscall.Getpid(), syscall.SIGKILL)
	}
	return system.Execv(l.config.Args[0], l.config.Args[0:], os.Environ())
}
Exemplo n.º 26
0
func daemon(cmd string, argv []string, pipe int) error {

	// create a subprocess
	pid, err := fork(false)
	if err != nil {
		return err
	} else if pid > 0 {
		go func() {
			wp, err := syscall.Wait4(int(pid), nil, 0, nil)
			if err == nil {
				glog.V(3).Infof("collect child %d", wp)
			} else {
				glog.Errorf("error during wait %d: %s", pid, err.Error())
			}
		}()
		// return the parent
		return nil
	}

	// exit the created one, create the daemon
	_, err = fork(true)
	if err != nil {
		glog.Error("second fork failed: ", err.Error())
		os.Exit(-1)
	}

	cur := os.Getpid()
	glog.V(1).Infof("qemu daemon pid %d.", cur)
	//Change the file mode mask
	_ = syscall.Umask(0)

	// create a new SID for the child process
	s_ret, err := syscall.Setsid()
	if err != nil {
		glog.Info("Error: syscall.Setsid errno: ", err.Error())
		os.Exit(-1)
	}
	if s_ret < 0 {
		glog.Errorf("setsid return negative value: %d", s_ret)
		os.Exit(-1)
	}

	os.Chdir("/")

	f, e := os.OpenFile("/dev/null", os.O_RDWR, 0)
	if e == nil {
		fd := f.Fd()
		syscall.Dup2(int(fd), int(os.Stdin.Fd()))
		syscall.Dup2(int(fd), int(os.Stdout.Fd()))
		syscall.Dup2(int(fd), int(os.Stderr.Fd()))
	}

	buf := make([]byte, 4)
	binary.BigEndian.PutUint32(buf, uint32(cur))
	syscall.Write(pipe, buf)
	syscall.Close(pipe)

	fds := listFd()
	for _, fd := range fds {
		if f, err := strconv.Atoi(fd); err == nil && f > 2 {
			glog.V(1).Infof("close fd %d", f)
			syscall.Close(f)
		}
	}

	err = syscall.Exec(cmd, argv, []string{})
	if err != nil {
		glog.Error("fail to exec qemu process")
		os.Exit(-1)
	}

	return nil
}
Exemplo n.º 27
0
Arquivo: child.go Projeto: rhenium/poe
func doChild(rootdir string, progfile string, plan plan, stdin_fd, stdout_fd, stderr_fd [2]int) (error, string) {
	if os.Getpid() != 1 {
		return errors.New("not cloned?"), ""
	}

	if err := syscall.Dup2(stdin_fd[0], 0); err != nil {
		return err, "dup2 failed"
	}
	syscall.Close(stdin_fd[0])
	syscall.Close(stdin_fd[1])
	if err := syscall.Dup2(stdout_fd[1], 1); err != nil {
		return err, "dup2 failed"
	}
	syscall.Close(stdout_fd[0])
	syscall.Close(stdout_fd[1])
	if err := syscall.Dup2(stderr_fd[1], 2); err != nil {
		return err, "dup2 failed"
	}
	syscall.Close(stderr_fd[0])
	syscall.Close(stderr_fd[1])

	if _, _, err := syscall.Syscall(syscall.SYS_PRCTL, syscall.PR_SET_PDEATHSIG, uintptr(syscall.SIGKILL), 0); err != 0 {
		return error(err), "PR_SET_PDEATHSIG failed"
	}

	if err := syscall.Sethostname([]byte("poe-sandbox")); err != nil {
		return err, "sethostname failed"
	}

	mounts := []mountPoint{
		{"none", "/", "", syscall.MS_PRIVATE | syscall.MS_REC, ""},
		{rootdir, rootdir, "bind", syscall.MS_BIND | syscall.MS_REC, ""},
		// { "none",   rootdir + "/proc", "proc",         syscall.MS_NOSUID | syscall.MS_NOEXEC | syscall.MS_NODEV, "" },
		// { "none",   rootdir + "/dev",  "devtmpfs",     syscall.MS_NOSUID | syscall.MS_NOEXEC, "" },
		// { "none",   rootdir + "/dev/shm", "tmpfs",        syscall.MS_NOSUID | syscall.MS_NODEV, "" },
	}
	for _, point := range mounts {
		if err := syscall.Mount(point.source, point.target, point.fstype, point.flags, point.data); err != nil {
			return err, fmt.Sprintf("mount '%s' on '%s' (%s) failed", point.source, point.target, point.fstype)
		}
	}

	if err := syscall.Chroot(rootdir); err != nil {
		return err, "chroot failed"
	}

	if _, err := syscall.Setsid(); err != nil {
		return err, "setsid failed"
	}

	pw, err := user.Lookup(username)
	if err != nil {
		return err, "getpwnam failed"
	}
	uid, err := strconv.Atoi(pw.Uid)
	if err != nil {
		return err, "atoi error"
	}
	gid, err := strconv.Atoi(pw.Gid)
	if err != nil {
		return err, "atoi error"
	}
	// TODO: initgroups

	if err := syscall.Setresgid(gid, gid, gid); err != nil {
		return err, "setresgid failed"
	}

	if err := syscall.Setresuid(uid, uid, uid); err != nil {
		return err, "setresuid failed"
	}

	if err := syscall.Chdir("/tmp"); err != nil {
		return err, "chdir failed"
	}

	// stop
	os.Stdin.Read(make([]byte, 1))
	// be traced
	if _, _, err := syscall.Syscall(syscall.SYS_PRCTL, PR_SET_NO_NEW_PRIVS, 1, 0); err != 0 {
		return error(err), "PR_SET_NO_NEW_PRIVS failed"
	}

	if err := SetupSeccomp(); err != nil {
		return err, "seccomp fail"
	}

	envp := []string{
		"PATH=/opt/bin:/usr/bin",
		"USER="******"LOGNAME=" + username,
	}

	cmdl := make([]string, 0, len(plan.Compiler.Command)+len(plan.Extra)-1)
	for _, arg := range plan.Compiler.Command {
		if arg == "PROGRAM" {
			cmdl = append(cmdl, progfile)
		} else if arg == "EXTRA" {
			cmdl = append(cmdl, plan.Extra...)
		} else {
			cmdl = append(cmdl, arg)
		}
	}

	if err := syscall.Exec(cmdl[0], cmdl, envp); err != nil {
		return err, "execve failed"
	}

	return errors.New("unreachable"), ""
}
Exemplo n.º 28
0
// TODO(vishh): This is part of the libcontainer API and it does much more than just namespaces related work.
// Move this to libcontainer package.
// Init is the init process that first runs inside a new namespace to setup mounts, users, networking,
// and other options required for the new container.
// The caller of Init function has to ensure that the go runtime is locked to an OS thread
// (using runtime.LockOSThread) else system calls like setns called within Init may not work as intended.
func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, syncPipe *syncpipe.SyncPipe, args []string) (err error) {
	defer func() {
		if err != nil {
			syncPipe.ReportChildError(err)
		}
	}()

	rootfs, err := utils.ResolveRootfs(uncleanRootfs)
	if err != nil {
		return err
	}

	// clear the current processes env and replace it with the environment
	// defined on the container
	if err := LoadContainerEnvironment(container); err != nil {
		return err
	}

	// We always read this as it is a way to sync with the parent as well
	var networkState *network.NetworkState
	if err := syncPipe.ReadFromParent(&networkState); err != nil {
		return err
	}

	if consolePath != "" {
		if err := console.OpenAndDup(consolePath); err != nil {
			return err
		}
	}
	if _, err := syscall.Setsid(); err != nil {
		return fmt.Errorf("setsid %s", err)
	}
	if consolePath != "" {
		if err := system.Setctty(); err != nil {
			return fmt.Errorf("setctty %s", err)
		}
	}
	if err := ipc.Initialize(container.IpcNsPath); err != nil {
		return fmt.Errorf("setup IPC %s", err)
	}
	if err := setupNetwork(container, networkState); err != nil {
		return fmt.Errorf("setup networking %s", err)
	}
	if err := setupRoute(container); err != nil {
		return fmt.Errorf("setup route %s", err)
	}

	label.Init()

	if err := mount.InitializeMountNamespace(rootfs,
		consolePath,
		container.RestrictSys,
		(*mount.MountConfig)(container.MountConfig)); err != nil {
		return fmt.Errorf("setup mount namespace %s", err)
	}

	if container.Hostname != "" {
		if err := syscall.Sethostname([]byte(container.Hostname)); err != nil {
			return fmt.Errorf("sethostname %s", err)
		}
	}

	if err := apparmor.ApplyProfile(container.AppArmorProfile); err != nil {
		return fmt.Errorf("set apparmor profile %s: %s", container.AppArmorProfile, err)
	}

	if err := label.SetProcessLabel(container.ProcessLabel); err != nil {
		return fmt.Errorf("set process label %s", err)
	}

	// TODO: (crosbymichael) make this configurable at the Config level
	if container.RestrictSys {
		if err := restrict.Restrict("proc/sys", "proc/sysrq-trigger", "proc/irq", "proc/bus"); err != nil {
			return err
		}
	}

	pdeathSignal, err := system.GetParentDeathSignal()
	if err != nil {
		return fmt.Errorf("get parent death signal %s", err)
	}

	if err := FinalizeNamespace(container); err != nil {
		return fmt.Errorf("finalize namespace %s", err)
	}

	// FinalizeNamespace can change user/group which clears the parent death
	// signal, so we restore it here.
	if err := RestoreParentDeathSignal(pdeathSignal); err != nil {
		return fmt.Errorf("restore parent death signal %s", err)
	}

	return system.Execv(args[0], args[0:], os.Environ())
}
Exemplo n.º 29
0
func Setsid() (int, error) {
	return syscall.Setsid()
}
Exemplo n.º 30
0
// TODO(vishh): This is part of the libcontainer API and it does much more than just namespaces related work.
// Move this to libcontainer package.
// Init is the init process that first runs inside a new namespace to setup mounts, users, networking,
// and other options required for the new container.
// The caller of Init function has to ensure that the go runtime is locked to an OS thread
// (using runtime.LockOSThread) else system calls like setns called within Init may not work as intended.
func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, pipe *os.File, args []string) (err error) {
	defer func() {
		// if we have an error during the initialization of the container's init then send it back to the
		// parent process in the form of an initError.
		if err != nil {
			// ensure that any data sent from the parent is consumed so it doesn't
			// receive ECONNRESET when the child writes to the pipe.
			ioutil.ReadAll(pipe)
			if err := json.NewEncoder(pipe).Encode(initError{
				Message: err.Error(),
			}); err != nil {
				panic(err)
			}
		}
		// ensure that this pipe is always closed
		pipe.Close()
	}()

	rootfs, err := utils.ResolveRootfs(uncleanRootfs)
	if err != nil {
		return err
	}

	// clear the current processes env and replace it with the environment
	// defined on the container
	if err := LoadContainerEnvironment(container); err != nil {
		return err
	}

	// We always read this as it is a way to sync with the parent as well
	var networkState *network.NetworkState
	if err := json.NewDecoder(pipe).Decode(&networkState); err != nil {
		return err
	}
	// join any namespaces via a path to the namespace fd if provided
	if err := joinExistingNamespaces(container.Namespaces); err != nil {
		return err
	}
	if consolePath != "" {
		if err := console.OpenAndDup(consolePath); err != nil {
			return err
		}
	}
	if _, err := syscall.Setsid(); err != nil {
		return fmt.Errorf("setsid %s", err)
	}
	if consolePath != "" {
		if err := system.Setctty(); err != nil {
			return fmt.Errorf("setctty %s", err)
		}
	}

	if err := setupNetwork(container, networkState); err != nil {
		return fmt.Errorf("setup networking %s", err)
	}
	if err := setupRoute(container); err != nil {
		return fmt.Errorf("setup route %s", err)
	}

	if err := setupRlimits(container); err != nil {
		return fmt.Errorf("setup rlimits %s", err)
	}

	label.Init()

	if err := mount.InitializeMountNamespace(rootfs,
		consolePath,
		container.RestrictSys,
		(*mount.MountConfig)(container.MountConfig)); err != nil {
		return fmt.Errorf("setup mount namespace %s", err)
	}

	if container.Hostname != "" {
		if err := syscall.Sethostname([]byte(container.Hostname)); err != nil {
			return fmt.Errorf("unable to sethostname %q: %s", container.Hostname, err)
		}
	}

	if err := apparmor.ApplyProfile(container.AppArmorProfile); err != nil {
		return fmt.Errorf("set apparmor profile %s: %s", container.AppArmorProfile, err)
	}

	if err := label.SetProcessLabel(container.ProcessLabel); err != nil {
		return fmt.Errorf("set process label %s", err)
	}

	// TODO: (crosbymichael) make this configurable at the Config level
	if container.RestrictSys {
		if err := restrict.Restrict("proc/sys", "proc/sysrq-trigger", "proc/irq", "proc/bus"); err != nil {
			return err
		}
	}

	pdeathSignal, err := system.GetParentDeathSignal()
	if err != nil {
		return fmt.Errorf("get parent death signal %s", err)
	}

	if err := FinalizeNamespace(container); err != nil {
		return fmt.Errorf("finalize namespace %s", err)
	}

	// FinalizeNamespace can change user/group which clears the parent death
	// signal, so we restore it here.
	if err := RestoreParentDeathSignal(pdeathSignal); err != nil {
		return fmt.Errorf("restore parent death signal %s", err)
	}

	return system.Execv(args[0], args[0:], os.Environ())
}