diff --git a/daemon/debugtrap_windows.go b/daemon/debugtrap_windows.go index 624370ef1a..77977e072d 100644 --- a/daemon/debugtrap_windows.go +++ b/daemon/debugtrap_windows.go @@ -4,7 +4,9 @@ import ( "fmt" "os" "syscall" + "unsafe" + winio "github.com/Microsoft/go-winio" "github.com/Sirupsen/logrus" "github.com/docker/docker/pkg/signal" "github.com/docker/docker/pkg/system" @@ -13,18 +15,27 @@ import ( func setupDumpStackTrap(root string) { // Windows does not support signals like *nix systems. So instead of // trapping on SIGUSR1 to dump stacks, we wait on a Win32 event to be - // signaled. + // signaled. ACL'd to builtin administrators and local system + ev := "Global\\docker-daemon-" + fmt.Sprint(os.Getpid()) + sd, err := winio.SddlToSecurityDescriptor("D:P(A;;GA;;;BA)(A;;GA;;;SY)") + if err != nil { + logrus.Errorf("failed to get security descriptor for debug stackdump event %s: %s", ev, err.Error()) + return + } + var sa syscall.SecurityAttributes + sa.Length = uint32(unsafe.Sizeof(sa)) + sa.InheritHandle = 1 + sa.SecurityDescriptor = uintptr(unsafe.Pointer(&sd[0])) + h, err := system.CreateEvent(&sa, false, false, ev) + if h == 0 || err != nil { + logrus.Errorf("failed to create debug stackdump event %s: %s", ev, err.Error()) + return + } go func() { - sa := syscall.SecurityAttributes{ - Length: 0, - } - ev := "Global\\docker-daemon-" + fmt.Sprint(os.Getpid()) - if h, _ := system.CreateEvent(&sa, false, false, ev); h != 0 { - logrus.Debugf("Stackdump - waiting signal at %s", ev) - for { - syscall.WaitForSingleObject(h, syscall.INFINITE) - signal.DumpStacks(root) - } + logrus.Debugf("Stackdump - waiting signal at %s", ev) + for { + syscall.WaitForSingleObject(h, syscall.INFINITE) + signal.DumpStacks(root) } }() }