Skip to content

Commit

Permalink
tetragon: chmod unix socket to 0660
Browse files Browse the repository at this point in the history
This patch ensures that the control unix socket for the agent has 0660
file permissions.

Signed-off-by: Kornilios Kourtis <kornilios@isovalent.com>
  • Loading branch information
kkourt committed Nov 25, 2022
1 parent 9bec5e9 commit 0d7f811
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 0d7f811

Please sign in to comment.