Skip to content

Commit 58542c7

Browse files
authored
Merge pull request #75 from thaJeztah/move_umask
NewUnixSocketWithOpts(): reduce umask override time-window, document hack
2 parents ca1f92b + 196500f commit 58542c7

File tree

1 file changed

+24
-4
lines changed

1 file changed

+24
-4
lines changed

sockets/unix_socket.go

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func WithChown(uid, gid int) SockOption {
6767
}
6868
}
6969

70-
// WithChmod modifies socket file's access mode
70+
// WithChmod modifies socket file's access mode.
7171
func WithChmod(mask os.FileMode) SockOption {
7272
return func(path string) error {
7373
if err := os.Chmod(path, mask); err != nil {
@@ -77,15 +77,35 @@ func WithChmod(mask os.FileMode) SockOption {
7777
}
7878
}
7979

80-
// NewUnixSocketWithOpts creates a unix socket with the specified options
80+
// NewUnixSocketWithOpts creates a unix socket with the specified options.
81+
// By default, socket permissions are 0000 (i.e.: no access for anyone); pass
82+
// WithChmod() and WithChown() to set the desired ownership and permissions.
83+
//
84+
// This function temporarily changes the system's "umask" to 0777 to work around
85+
// a race condition between creating the socket and setting its permissions. While
86+
// this should only be for a short duration, it may affect other processes that
87+
// create files/directories during that period.
8188
func NewUnixSocketWithOpts(path string, opts ...SockOption) (net.Listener, error) {
8289
if err := syscall.Unlink(path); err != nil && !os.IsNotExist(err) {
8390
return nil, err
8491
}
85-
mask := syscall.Umask(0777)
86-
defer syscall.Umask(mask)
8792

93+
// net.Listen does not allow for permissions to be set. As a result, when
94+
// specifying custom permissions ("WithChmod()"), there is a short time
95+
// between creating the socket and applying the permissions, during which
96+
// the socket permissions are Less restrictive than desired.
97+
//
98+
// To work around this limitation of net.Listen(), we temporarily set the
99+
// umask to 0777, which forces the socket to be created with 000 permissions
100+
// (i.e.: no access for anyone). After that, WithChmod() must be used to set
101+
// the desired permissions.
102+
//
103+
// We don't use "defer" here, to reset the umask to its original value as soon
104+
// as possible. Ideally we'd be able to detect if WithChmod() was passed as
105+
// an option, and skip changing umask if default permissions are used.
106+
origUmask := syscall.Umask(0777)
88107
l, err := net.Listen("unix", path)
108+
syscall.Umask(origUmask)
89109
if err != nil {
90110
return nil, err
91111
}

0 commit comments

Comments
 (0)