Commit ddd1cdae authored by Alex Brainman's avatar Alex Brainman

windows: fix race when allocating buffer for some windows syscalls

From main repo: https://go-review.googlesource.com/#/c/4940

Change-Id: I56fe7f6aedc0fd350abb94299ad500fcb80c049a
Reviewed-on: https://go-review.googlesource.com/8604Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
parent ea755264
......@@ -16,19 +16,17 @@ func Getenv(key string) (value string, found bool) {
if err != nil {
return "", false
}
b := make([]uint16, 100)
n, e := GetEnvironmentVariable(keyp, &b[0], uint32(len(b)))
if n == 0 && e == ERROR_ENVVAR_NOT_FOUND {
return "", false
}
if n > uint32(len(b)) {
b = make([]uint16, n)
n, e = GetEnvironmentVariable(keyp, &b[0], uint32(len(b)))
if n > uint32(len(b)) {
n = 0
n := uint32(100)
for {
b := make([]uint16, n)
n, err = GetEnvironmentVariable(keyp, &b[0], uint32(len(b)))
if n == 0 && err == ERROR_ENVVAR_NOT_FOUND {
return "", false
}
if n <= uint32(len(b)) {
return string(utf16.Decode(b[:n])), true
}
}
return string(utf16.Decode(b[0:n])), true
}
func Setenv(key, value string) error {
......
......@@ -6,8 +6,6 @@
package windows
import "syscall"
// EscapeArg rewrites command line argument s as prescribed
// in http://msdn.microsoft.com/en-us/library/ms880421.
// This function returns "" (2 double quotes) if s is empty.
......@@ -85,21 +83,15 @@ func FullPath(name string) (path string, err error) {
if err != nil {
return "", err
}
buf := make([]uint16, 100)
n, err := GetFullPathName(p, uint32(len(buf)), &buf[0], nil)
if err != nil {
return "", err
}
if n > uint32(len(buf)) {
// Windows is asking for bigger buffer.
buf = make([]uint16, n)
n := uint32(100)
for {
buf := make([]uint16, n)
n, err = GetFullPathName(p, uint32(len(buf)), &buf[0], nil)
if err != nil {
return "", err
}
if n > uint32(len(buf)) {
return "", syscall.EINVAL
if n <= uint32(len(buf)) {
return UTF16ToString(buf[:n]), nil
}
}
return UTF16ToString(buf[:n]), nil
}
......@@ -42,21 +42,20 @@ func TranslateAccountName(username string, from, to uint32, initSize int) (strin
if e != nil {
return "", e
}
b := make([]uint16, 50)
n := uint32(len(b))
e = TranslateName(u, from, to, &b[0], &n)
if e != nil {
n := uint32(50)
for {
b := make([]uint16, n)
e = TranslateName(u, from, to, &b[0], &n)
if e == nil {
return UTF16ToString(b[:n]), nil
}
if e != ERROR_INSUFFICIENT_BUFFER {
return "", e
}
// make receive buffers of requested size and try again
b = make([]uint16, n)
e = TranslateName(u, from, to, &b[0], &n)
if e != nil {
if n <= uint32(len(b)) {
return "", e
}
}
return UTF16ToString(b), nil
}
const (
......@@ -137,26 +136,23 @@ func LookupSID(system, account string) (sid *SID, domain string, accType uint32,
return nil, "", 0, e
}
}
db := make([]uint16, 50)
dn := uint32(len(db))
b := make([]byte, 50)
n := uint32(len(b))
sid = (*SID)(unsafe.Pointer(&b[0]))
e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
if e != nil {
n := uint32(50)
dn := uint32(50)
for {
b := make([]byte, n)
db := make([]uint16, dn)
sid = (*SID)(unsafe.Pointer(&b[0]))
e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
if e == nil {
return sid, UTF16ToString(db), accType, nil
}
if e != ERROR_INSUFFICIENT_BUFFER {
return nil, "", 0, e
}
// make receive buffers of requested size and try again
b = make([]byte, n)
sid = (*SID)(unsafe.Pointer(&b[0]))
db = make([]uint16, dn)
e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
if e != nil {
if n <= uint32(len(b)) {
return nil, "", 0, e
}
}
return sid, UTF16ToString(db), accType, nil
}
// String converts sid to a string format
......@@ -198,24 +194,22 @@ func (sid *SID) LookupAccount(system string) (account, domain string, accType ui
return "", "", 0, err
}
}
b := make([]uint16, 50)
n := uint32(len(b))
db := make([]uint16, 50)
dn := uint32(len(db))
e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
if e != nil {
n := uint32(50)
dn := uint32(50)
for {
b := make([]uint16, n)
db := make([]uint16, dn)
e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
if e == nil {
return UTF16ToString(b), UTF16ToString(db), accType, nil
}
if e != ERROR_INSUFFICIENT_BUFFER {
return "", "", 0, e
}
// make receive buffers of requested size and try again
b = make([]uint16, n)
db = make([]uint16, dn)
e = LookupAccountSid(nil, sid, &b[0], &n, &db[0], &dn, &accType)
if e != nil {
if n <= uint32(len(b)) {
return "", "", 0, e
}
}
return UTF16ToString(b), UTF16ToString(db), accType, nil
}
const (
......@@ -327,21 +321,20 @@ func (t Token) Close() error {
// getInfo retrieves a specified type of information about an access token.
func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {
b := make([]byte, initSize)
var n uint32
e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
if e != nil {
n := uint32(initSize)
for {
b := make([]byte, n)
e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
if e == nil {
return unsafe.Pointer(&b[0]), nil
}
if e != ERROR_INSUFFICIENT_BUFFER {
return nil, e
}
// make receive buffers of requested size and try again
b = make([]byte, n)
e = GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
if e != nil {
if n <= uint32(len(b)) {
return nil, e
}
}
return unsafe.Pointer(&b[0]), nil
}
// GetTokenUser retrieves access token t user account information.
......@@ -367,19 +360,18 @@ func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) {
// GetUserProfileDirectory retrieves path to the
// root directory of the access token t user's profile.
func (t Token) GetUserProfileDirectory() (string, error) {
b := make([]uint16, 100)
n := uint32(len(b))
e := GetUserProfileDirectory(t, &b[0], &n)
if e != nil {
n := uint32(100)
for {
b := make([]uint16, n)
e := GetUserProfileDirectory(t, &b[0], &n)
if e == nil {
return UTF16ToString(b), nil
}
if e != ERROR_INSUFFICIENT_BUFFER {
return "", e
}
// make receive buffers of requested size and try again
b = make([]uint16, n)
e = GetUserProfileDirectory(t, &b[0], &n)
if e != nil {
if n <= uint32(len(b)) {
return "", e
}
}
return UTF16ToString(b), nil
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment