From 7e05e809b7579ad0473fff6ce466c19d417d4e93 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sat, 5 Jan 2019 15:44:32 +0100 Subject: main: Run 'ensure fds' code early during the program startup. The files are apparently processed in alphabetic order, so cli_args.go is processed before main.go. In order to run before the go-fuse imports, put the 'ensure fds' code in a separate package. Debug messages are omitted to avoid additional imports (that might contain other code messing up our file descriptors). --- internal/ensurefds012/ensurefds012.go | 52 +++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 internal/ensurefds012/ensurefds012.go (limited to 'internal/ensurefds012') diff --git a/internal/ensurefds012/ensurefds012.go b/internal/ensurefds012/ensurefds012.go new file mode 100644 index 0000000..7872eb2 --- /dev/null +++ b/internal/ensurefds012/ensurefds012.go @@ -0,0 +1,52 @@ +package ensurefds012 + +// Package ensurefds012 ensures that file descriptors 0,1,2 are open. It opens +// multiple copies of /dev/null as required. +// The Go stdlib as well as the gocryptfs code rely on the fact that +// fds 0,1,2 are always open. +// +// Use like this: +// +// import _ "github.com/rfjakob/gocryptfs/internal/ensurefds012" +// +// The import line MUST be in the alphabitcally first source code file of +// package main! +// +// You can test if it works as expected by inserting a long sleep into main, +// startings gocryptfs with all fds closed like this, +// +// $ ./gocryptfs 0<&- 1>&- 2>&- +// +// and then checking the open fds. It should look like this: +// +// $ ls -l /proc/$(pgrep gocryptfs)/fd +// total 0 +// lrwx------. 1 jakob jakob 64 Jan 5 15:54 0 -> /dev/null +// lrwx------. 1 jakob jakob 64 Jan 5 15:54 1 -> /dev/null +// lrwx------. 1 jakob jakob 64 Jan 5 15:54 2 -> /dev/null +// l-wx------. 1 jakob jakob 64 Jan 5 15:54 3 -> /dev/null +// lrwx------. 1 jakob jakob 64 Jan 5 15:54 4 -> 'anon_inode:[eventpoll]' +// +// See https://github.com/rfjakob/gocryptfs/issues/320 for details. + +import ( + "os" + "syscall" + + "github.com/rfjakob/gocryptfs/internal/exitcodes" +) + +func init() { + fd, err := syscall.Open("/dev/null", syscall.O_RDWR, 0) + if err != nil { + os.Exit(exitcodes.DevNull) + } + for fd <= 2 { + fd, err = syscall.Dup(fd) + if err != nil { + os.Exit(exitcodes.DevNull) + } + } + // Close excess fd (usually fd 3) + syscall.Close(fd) +} -- cgit v1.2.3