Skip to content

Commit

Permalink
buildkitd: allow --group for windows
Browse files Browse the repository at this point in the history
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
(cherry picked from commit 68671bc)
  • Loading branch information
tonistiigi committed Apr 25, 2024
1 parent 4d961ca commit 25108ab
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 15 deletions.
9 changes: 5 additions & 4 deletions cmd/buildkitd/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,11 @@ type LogConfig struct {
}

type GRPCConfig struct {
Address []string `toml:"address"`
DebugAddress string `toml:"debugAddress"`
UID *int `toml:"uid"`
GID *int `toml:"gid"`
Address []string `toml:"address"`
DebugAddress string `toml:"debugAddress"`
UID *int `toml:"uid"`
GID *int `toml:"gid"`
SecurityDescriptor string `toml:"securityDescriptor"`

TLS TLSConfig `toml:"tls"`
// MaxRecvMsgSize int `toml:"max_recv_message_size"`
Expand Down
35 changes: 28 additions & 7 deletions cmd/buildkitd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"os"
"os/user"
"path/filepath"
"runtime"
"sort"
"strconv"
"strings"
Expand Down Expand Up @@ -397,9 +398,18 @@ func newGRPCListeners(cfg config.GRPCConfig) ([]net.Listener, error) {
if err != nil {
return nil, err
}

sd := cfg.SecurityDescriptor
if sd == "" {
sd, err = groupToSecurityDescriptor("")
if err != nil {
return nil, err
}
}

listeners := make([]net.Listener, 0, len(addrs))
for _, addr := range addrs {
l, err := getListener(addr, *cfg.UID, *cfg.GID, tlsConfig)
l, err := getListener(addr, *cfg.UID, *cfg.GID, sd, tlsConfig)
if err != nil {
for _, l := range listeners {
l.Close()
Expand Down Expand Up @@ -569,11 +579,19 @@ func applyMainFlags(c *cli.Context, cfg *config.Config) error {
}

if group := c.String("group"); group != "" {
gid, err := groupToGid(group)
if err != nil {
return err
if runtime.GOOS == "windows" {
secDescriptor, err := groupToSecurityDescriptor(group)
if err != nil {
return err
}
cfg.GRPC.SecurityDescriptor = secDescriptor
} else {
gid, err := groupToGid(group)
if err != nil {
return err
}
cfg.GRPC.GID = &gid
}
cfg.GRPC.GID = &gid
}

if tlscert := c.String("tlscert"); tlscert != "" {
Expand Down Expand Up @@ -628,7 +646,7 @@ func groupToGid(group string) (int, error) {
return id, nil
}

func getListener(addr string, uid, gid int, tlsConfig *tls.Config) (net.Listener, error) {
func getListener(addr string, uid, gid int, secDescriptor string, tlsConfig *tls.Config) (net.Listener, error) {
addrSlice := strings.SplitN(addr, "://", 2)
if len(addrSlice) < 2 {
return nil, errors.Errorf("address %s does not contain proto, you meant unix://%s ?",
Expand All @@ -641,6 +659,9 @@ func getListener(addr string, uid, gid int, tlsConfig *tls.Config) (net.Listener
if tlsConfig != nil {
bklog.L.Warnf("TLS is disabled for %s", addr)
}
if proto == "npipe" {
return getLocalListener(listenAddr, secDescriptor)
}
return sys.GetLocalListener(listenAddr, uid, gid)
case "fd":
return listenFD(listenAddr, tlsConfig)
Expand Down Expand Up @@ -928,7 +949,7 @@ func parseBoolOrAuto(s string) (*bool, error) {
func runTraceController(p string, exp sdktrace.SpanExporter) error {
server := grpc.NewServer()
tracev1.RegisterTraceServiceServer(server, &traceCollector{exporter: exp})
l, err := getLocalListener(p)
l, err := getLocalListener(p, "")
if err != nil {
return errors.Wrap(err, "creating trace controller listener")
}
Expand Down
6 changes: 5 additions & 1 deletion cmd/buildkitd/main_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func listenFD(addr string, tlsConfig *tls.Config) (net.Listener, error) {
return nil, errors.New("not supported yet")
}

func getLocalListener(listenerPath string) (net.Listener, error) {
func getLocalListener(listenerPath, _ string) (net.Listener, error) {
uid := os.Getuid()
l, err := sys.GetLocalListener(listenerPath, uid, uid)
if err != nil {
Expand All @@ -60,3 +60,7 @@ func getLocalListener(listenerPath string) (net.Listener, error) {
}
return l, nil
}

func groupToSecurityDescriptor(_ string) (string, error) {
return "", nil
}
26 changes: 23 additions & 3 deletions cmd/buildkitd/main_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ package main

import (
"crypto/tls"
"fmt"
"net"
"strings"

"github.com/Microsoft/go-winio"
_ "github.com/moby/buildkit/solver/llbsolver/ops"
Expand All @@ -19,14 +21,18 @@ func listenFD(addr string, tlsConfig *tls.Config) (net.Listener, error) {
return nil, errors.New("listening server on fd not supported on windows")
}

func getLocalListener(listenerPath string) (net.Listener, error) {
pc := &winio.PipeConfig{
func getLocalListener(listenerPath, secDescriptor string) (net.Listener, error) {
if secDescriptor == "" {
// Allow generic read and generic write access to authenticated users
// and system users. On Linux, this pipe seems to be given rw access to
// user, group and others (666).
// TODO(gabriel-samfira): should we restrict access to this pipe to just
// authenticated users? Or Administrators group?
SecurityDescriptor: "D:P(A;;GRGW;;;AU)(A;;GRGW;;;SY)",
secDescriptor = "D:P(A;;GRGW;;;AU)(A;;GRGW;;;SY)"
}

pc := &winio.PipeConfig{
SecurityDescriptor: secDescriptor,
}

listener, err := winio.ListenPipe(listenerPath, pc)
Expand All @@ -35,3 +41,17 @@ func getLocalListener(listenerPath string) (net.Listener, error) {
}
return listener, nil
}

func groupToSecurityDescriptor(group string) (string, error) {
sddl := "D:P(A;;GA;;;BA)(A;;GA;;;SY)"
if group != "" {
for _, g := range strings.Split(group, ",") {
sid, err := winio.LookupSidByName(g)
if err != nil {
return "", errors.Wrapf(err, "failed to lookup sid for group %s", g)
}
sddl += fmt.Sprintf("(A;;GRGW;;;%s)", sid)
}
}
return sddl, nil
}

0 comments on commit 25108ab

Please sign in to comment.