Skip to content

Commit f1eb81f

Browse files
author
Kathryn Baldauf
committed
Update to use upstream sddl/SecurityAttribute but retain old exported functions
Signed-off-by: Kathryn Baldauf <kabaldau@microsoft.com>
1 parent 6eac466 commit f1eb81f

File tree

7 files changed

+111
-45
lines changed

7 files changed

+111
-45
lines changed

backuptar/tar.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"strings"
1515
"syscall"
1616
"time"
17+
"unsafe"
1718

1819
"github.com/Microsoft/go-winio"
1920
"golang.org/x/sys/windows"
@@ -330,32 +331,34 @@ func FileInfoFromHeader(hdr *tar.Header) (name string, size int64, fileInfo *win
330331
// tar file that was not processed, or io.EOF is there are no more.
331332
func WriteBackupStreamFromTarFile(w io.Writer, t *tar.Reader, hdr *tar.Header) (*tar.Header, error) {
332333
bw := winio.NewBackupStreamWriter(w)
333-
var sd []byte
334+
sd := &windows.SECURITY_DESCRIPTOR{}
334335
var err error
335336
// Maintaining old SDDL-based behavior for backward compatibility. All new tar headers written
336337
// by this library will have raw binary for the security descriptor.
337338
if sddl, ok := hdr.PAXRecords[hdrSecurityDescriptor]; ok {
338-
sd, err = winio.SddlToSecurityDescriptor(sddl)
339+
sd, err = windows.SecurityDescriptorFromString(sddl)
339340
if err != nil {
340341
return nil, err
341342
}
342343
}
343344
if sdraw, ok := hdr.PAXRecords[hdrRawSecurityDescriptor]; ok {
344-
sd, err = base64.StdEncoding.DecodeString(sdraw)
345+
sdAsByteSlice, err := base64.StdEncoding.DecodeString(sdraw)
345346
if err != nil {
346347
return nil, err
347348
}
349+
sd = (*windows.SECURITY_DESCRIPTOR)(unsafe.Pointer(&sdAsByteSlice[0]))
348350
}
349-
if len(sd) != 0 {
351+
sdLen := sd.Length()
352+
if sdLen != 0 {
350353
bhdr := winio.BackupHeader{
351354
Id: winio.BackupSecurity,
352-
Size: int64(len(sd)),
355+
Size: int64(sdLen),
353356
}
354357
err := bw.WriteHeader(&bhdr)
355358
if err != nil {
356359
return nil, err
357360
}
358-
_, err = bw.Write(sd)
361+
_, err = bw.Write((*[(1 << 31) - 1]byte)(unsafe.Pointer(sd))[:sdLen])
359362
if err != nil {
360363
return nil, err
361364
}

backuptar/tar_test.go

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package backuptar
55
import (
66
"archive/tar"
77
"bytes"
8+
"io"
89
"io/ioutil"
910
"os"
1011
"path/filepath"
@@ -22,7 +23,7 @@ func ensurePresent(t *testing.T, m map[string]string, keys ...string) {
2223
}
2324
}
2425

25-
func TestRoundTrip(t *testing.T) {
26+
func TestTarFileFromBackupStream(t *testing.T) {
2627
f, err := ioutil.TempFile("", "tst")
2728
if err != nil {
2829
t.Fatal(err)
@@ -84,3 +85,79 @@ func TestRoundTrip(t *testing.T) {
8485

8586
ensurePresent(t, hdr.PAXRecords, "MSWINDOWS.fileattr", "MSWINDOWS.rawsd")
8687
}
88+
89+
func TestBackupStreamFromTar(t *testing.T) {
90+
f, err := ioutil.TempFile("", "tst")
91+
if err != nil {
92+
t.Fatal(err)
93+
}
94+
defer f.Close()
95+
defer os.Remove(f.Name())
96+
97+
expectedContent := "testing 1 2 3\n"
98+
if _, err = f.Write([]byte(expectedContent)); err != nil {
99+
t.Fatal(err)
100+
}
101+
102+
if _, err = f.Seek(0, 0); err != nil {
103+
t.Fatal(err)
104+
}
105+
106+
fi, err := f.Stat()
107+
if err != nil {
108+
t.Fatal(err)
109+
}
110+
111+
bi, err := winio.GetFileBasicInfo(f)
112+
if err != nil {
113+
t.Fatal(err)
114+
}
115+
116+
br := winio.NewBackupFileReader(f, true)
117+
defer br.Close()
118+
119+
var buf bytes.Buffer
120+
tw := tar.NewWriter(&buf)
121+
err = WriteTarFileFromBackupStream(tw, br, f.Name(), fi.Size(), bi)
122+
if err != nil {
123+
t.Fatal(err)
124+
}
125+
126+
tarContentReader := tar.NewReader(&buf)
127+
hdr2, err := tarContentReader.Next()
128+
if err != nil {
129+
t.Fatal(err)
130+
}
131+
var backupStreamBuf bytes.Buffer
132+
_, err = WriteBackupStreamFromTarFile(&backupStreamBuf, tarContentReader, hdr2)
133+
if err != nil && err != io.EOF {
134+
t.Fatal(err)
135+
}
136+
137+
bsr := winio.NewBackupStreamReader(&backupStreamBuf)
138+
139+
// read the first header that has security descriptor
140+
_, err = bsr.Next()
141+
if err != nil && err != io.EOF {
142+
t.Fatal(err)
143+
}
144+
145+
// read header for contents
146+
bhdr, err := bsr.Next()
147+
if err != nil && err != io.EOF {
148+
t.Fatal(err)
149+
}
150+
151+
resultBuf := make([]byte, int(bhdr.Size))
152+
written, err := bsr.Read(resultBuf)
153+
if err != nil && err != io.EOF {
154+
t.Fatal(err)
155+
}
156+
if int64(written) != bhdr.Size {
157+
t.Fatal("unexpected size of read bytes for backup stream")
158+
}
159+
160+
if expectedContent != string(resultBuf) {
161+
t.Fatalf("expected to read \"%v\" instead got \"%v\"", expectedContent, string(resultBuf))
162+
}
163+
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ go 1.12
55
require (
66
github.com/pkg/errors v0.9.1
77
github.com/sirupsen/logrus v1.7.0
8-
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c
8+
golang.org/x/sys v0.0.0-20210309074719-68d13333faf2
99
)

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1
1010
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
1111
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
1212
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
13-
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk=
14-
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
13+
golang.org/x/sys v0.0.0-20210309074719-68d13333faf2 h1:46ULzRKLh1CwgRq2dC5SlBzEqqNCi8rreOZnNrbqcIY=
14+
golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

pipe.go

Lines changed: 16 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import (
1313
"syscall"
1414
"time"
1515
"unsafe"
16+
17+
"golang.org/x/sys/windows"
1618
)
1719

1820
//sys connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) = ConnectNamedPipe
@@ -35,7 +37,7 @@ type objectAttributes struct {
3537
RootDirectory uintptr
3638
ObjectName *unicodeString
3739
Attributes uintptr
38-
SecurityDescriptor *securityDescriptor
40+
SecurityDescriptor *windows.SECURITY_DESCRIPTOR
3941
SecurityQoS uintptr
4042
}
4143

@@ -45,16 +47,6 @@ type unicodeString struct {
4547
Buffer uintptr
4648
}
4749

48-
type securityDescriptor struct {
49-
Revision byte
50-
Sbz1 byte
51-
Control uint16
52-
Owner uintptr
53-
Group uintptr
54-
Sacl uintptr
55-
Dacl uintptr
56-
}
57-
5850
type ntstatus int32
5951

6052
func (status ntstatus) Err() error {
@@ -82,8 +74,6 @@ const (
8274

8375
cFILE_PIPE_MESSAGE_TYPE = 1
8476
cFILE_PIPE_REJECT_REMOTE_CLIENTS = 2
85-
86-
cSE_DACL_PRESENT = 4
8777
)
8878

8979
var (
@@ -273,7 +263,7 @@ type win32PipeListener struct {
273263
doneCh chan int
274264
}
275265

276-
func makeServerPipeHandle(path string, sd []byte, c *PipeConfig, first bool) (syscall.Handle, error) {
266+
func makeServerPipeHandle(path string, sd *windows.SECURITY_DESCRIPTOR, c *PipeConfig, first bool) (syscall.Handle, error) {
277267
path16, err := syscall.UTF16FromString(path)
278268
if err != nil {
279269
return 0, &os.PathError{Op: "open", Path: path, Err: err}
@@ -286,29 +276,25 @@ func makeServerPipeHandle(path string, sd []byte, c *PipeConfig, first bool) (sy
286276
if err := rtlDosPathNameToNtPathName(&path16[0], &ntPath, 0, 0).Err(); err != nil {
287277
return 0, &os.PathError{Op: "open", Path: path, Err: err}
288278
}
289-
defer localFree(ntPath.Buffer)
279+
defer windows.LocalFree(windows.Handle(ntPath.Buffer))
290280
oa.ObjectName = &ntPath
291281

292282
// The security descriptor is only needed for the first pipe.
293283
if first {
294284
if sd != nil {
295-
len := uint32(len(sd))
296-
sdb := localAlloc(0, len)
297-
defer localFree(sdb)
298-
copy((*[0xffff]byte)(unsafe.Pointer(sdb))[:], sd)
299-
oa.SecurityDescriptor = (*securityDescriptor)(unsafe.Pointer(sdb))
285+
oa.SecurityDescriptor = sd
300286
} else {
301287
// Construct the default named pipe security descriptor.
302-
var dacl uintptr
303-
if err := rtlDefaultNpAcl(&dacl).Err(); err != nil {
288+
dacl := &windows.ACL{}
289+
if err := windows.RtlDefaultNpAcl(&dacl); err != nil {
304290
return 0, fmt.Errorf("getting default named pipe ACL: %s", err)
305291
}
306-
defer localFree(dacl)
307-
308-
sdb := &securityDescriptor{
309-
Revision: 1,
310-
Control: cSE_DACL_PRESENT,
311-
Dacl: dacl,
292+
sdb, err := windows.NewSecurityDescriptor()
293+
if err != nil {
294+
return 0, err
295+
}
296+
if err := sdb.SetDACL(dacl, true, true); err != nil {
297+
return 0, err
312298
}
313299
oa.SecurityDescriptor = sdb
314300
}
@@ -440,14 +426,14 @@ type PipeConfig struct {
440426
// The pipe must not already exist.
441427
func ListenPipe(path string, c *PipeConfig) (net.Listener, error) {
442428
var (
443-
sd []byte
429+
sd *windows.SECURITY_DESCRIPTOR
444430
err error
445431
)
446432
if c == nil {
447433
c = &PipeConfig{}
448434
}
449435
if c.SecurityDescriptor != "" {
450-
sd, err = SddlToSecurityDescriptor(c.SecurityDescriptor)
436+
sd, err = windows.SecurityDescriptorFromString(c.SecurityDescriptor)
451437
if err != nil {
452438
return nil, err
453439
}

vhd/vhd.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ import (
1313

1414
//go:generate go run mksyscall_windows.go -output zvhd_windows.go vhd.go
1515

16-
//sys createVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, securityDescriptor *uintptr, createVirtualDiskFlags uint32, providerSpecificFlags uint32, parameters *CreateVirtualDiskParameters, overlapped *syscall.Overlapped, handle *syscall.Handle) (err error) [failretval != 0] = virtdisk.CreateVirtualDisk
16+
//sys createVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, securityDescriptor *windows.SECURITY_DESCRIPTOR, createVirtualDiskFlags uint32, providerSpecificFlags uint32, parameters *CreateVirtualDiskParameters, overlapped *syscall.Overlapped, handle *syscall.Handle) (err error) [failretval != 0] = virtdisk.CreateVirtualDisk
1717
//sys openVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, openVirtualDiskFlags uint32, parameters *OpenVirtualDiskParameters, handle *syscall.Handle) (err error) [failretval != 0] = virtdisk.OpenVirtualDisk
18-
//sys attachVirtualDisk(handle syscall.Handle, securityDescriptor *uintptr, attachVirtualDiskFlag uint32, providerSpecificFlags uint32, parameters *AttachVirtualDiskParameters, overlapped *syscall.Overlapped) (err error) [failretval != 0] = virtdisk.AttachVirtualDisk
18+
//sys attachVirtualDisk(handle syscall.Handle, securityDescriptor *windows.SECURITY_DESCRIPTOR, attachVirtualDiskFlag uint32, providerSpecificFlags uint32, parameters *AttachVirtualDiskParameters, overlapped *syscall.Overlapped) (err error) [failretval != 0] = virtdisk.AttachVirtualDisk
1919
//sys detachVirtualDisk(handle syscall.Handle, detachVirtualDiskFlags uint32, providerSpecificFlags uint32) (err error) [failretval != 0] = virtdisk.DetachVirtualDisk
2020
//sys getVirtualDiskPhysicalPath(handle syscall.Handle, diskPathSizeInBytes *uint32, buffer *uint16) (err error) [failretval != 0] = virtdisk.GetVirtualDiskPhysicalPath
2121

vhd/zvhd_windows.go

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)