Skip to content

Commit

Permalink
tetragon: chmod unix socket to 0660
Browse files Browse the repository at this point in the history
[upstream commit: 9aae81d]

This patch ensures that the control unix socket for the agent has 0660
file permissions.

Signed-off-by: Kornilios Kourtis <[email protected]>
  • Loading branch information
kkourt committed Dec 9, 2022
1 parent 07ce360 commit d4cda7f
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 1 deletion.
9 changes: 8 additions & 1 deletion cmd/tetragon/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (
"github.com/cilium/tetragon/pkg/sensors/base"
"github.com/cilium/tetragon/pkg/sensors/program"
"github.com/cilium/tetragon/pkg/server"
"github.com/cilium/tetragon/pkg/unixlisten"
"github.com/cilium/tetragon/pkg/version"
"github.com/cilium/tetragon/pkg/watcher"
"github.com/cilium/tetragon/pkg/watcher/crd"
Expand Down Expand Up @@ -367,7 +368,13 @@ func Serve(ctx context.Context, listenAddr string, server *server.Server) error
return fmt.Errorf("failed to parse listen address: %w", err)
}
go func(proto, addr string) {
listener, err := net.Listen(proto, addr)
var listener net.Listener
var err error
if proto == "unix" {
listener, err = unixlisten.ListenWithRename(addr, 0660)
} else {
listener, err = net.Listen(proto, addr)
}
if err != nil {
log.WithError(err).WithField("protocol", proto).WithField("address", addr).Fatal("Failed to start gRPC server")
}
Expand Down
57 changes: 57 additions & 0 deletions pkg/unixlisten/unixlisten.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Tetragon
package unixlisten

import (
"fmt"
"net"
"os"
"path/filepath"
)

// ListenWithRename creates a "unix" listener for the given path and the given mode
//
// Go's net.Listen() performs three system calls at once:
// - socket, where the file descriptor is created
// - bind, where the unix socket file is created
// - listen, where the socket can now accept connections
//
// Hence, doing a chmod(2) after Listen is racy because a client can connect
// between the listen(2) and the chmod(2) calls. One solution would be to use
// umask(2), but this is tricky to do in a multi-threaded program because it
// affects other files being created from different threads. Also, other
// threads may change the umask.
//
// This function, instead, creates the socket file in a private directory,
// performs the appropriate chmod and only then moves the file to its original
// location. Not sure about other systems, but at least on Linux renaming a
// unix socket file after the listen seems to work without issues.
func ListenWithRename(path string, mode os.FileMode) (net.Listener, error) {
os.Remove(path)

baseName := filepath.Base(path)
dirName := filepath.Dir(path)

// Create a temporary directory: MkdirTemp creates the directory with 0700
tmpDir, err := os.MkdirTemp(dirName, fmt.Sprintf("%s-dir-*", baseName))
if err != nil {
return nil, err
}
defer os.RemoveAll(tmpDir)

tmpPath := filepath.Join(tmpDir, baseName)
l, err := net.Listen("unix", tmpPath)
if err != nil {
return nil, err
}

if err := os.Chmod(tmpPath, mode); err != nil {
return nil, err
}

err = os.Rename(tmpPath, path)
if err != nil {
return nil, err
}
return l, nil
}

0 comments on commit d4cda7f

Please sign in to comment.