mirror of
https://github.com/golang/go
synced 2024-11-14 07:50:21 -07:00
all: fix race when allocating buffer for some windows syscalls
Fixes #9753 Change-Id: I6c641ed7ef4f687a108e7d937ab4b9c24d5baf5d Reviewed-on: https://go-review.googlesource.com/4940 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
2f16ddc580
commit
32e75bace0
@ -481,20 +481,18 @@ func Pipe() (r *File, w *File, err error) {
|
|||||||
|
|
||||||
// TempDir returns the default directory to use for temporary files.
|
// TempDir returns the default directory to use for temporary files.
|
||||||
func TempDir() string {
|
func TempDir() string {
|
||||||
const pathSep = '\\'
|
n := uint32(syscall.MAX_PATH)
|
||||||
dirw := make([]uint16, syscall.MAX_PATH)
|
for {
|
||||||
n, _ := syscall.GetTempPath(uint32(len(dirw)), &dirw[0])
|
b := make([]uint16, n)
|
||||||
if n > uint32(len(dirw)) {
|
n, _ = syscall.GetTempPath(uint32(len(b)), &b[0])
|
||||||
dirw = make([]uint16, n)
|
if n > uint32(len(b)) {
|
||||||
n, _ = syscall.GetTempPath(uint32(len(dirw)), &dirw[0])
|
continue
|
||||||
if n > uint32(len(dirw)) {
|
|
||||||
n = 0
|
|
||||||
}
|
}
|
||||||
}
|
if n > 0 && b[n-1] == '\\' {
|
||||||
if n > 0 && dirw[n-1] == pathSep {
|
|
||||||
n--
|
n--
|
||||||
}
|
}
|
||||||
return string(utf16.Decode(dirw[0:n]))
|
return string(utf16.Decode(b[:n]))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Link creates newname as a hard link to the oldname file.
|
// Link creates newname as a hard link to the oldname file.
|
||||||
|
@ -14,18 +14,17 @@ func toShort(path string) (string, error) {
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
b := p // GetShortPathName says we can reuse buffer
|
b := p // GetShortPathName says we can reuse buffer
|
||||||
n, err := syscall.GetShortPathName(&p[0], &b[0], uint32(len(b)))
|
n := uint32(len(b))
|
||||||
if err != nil {
|
for {
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if n > uint32(len(b)) {
|
|
||||||
b = make([]uint16, n)
|
|
||||||
n, err = syscall.GetShortPathName(&p[0], &b[0], uint32(len(b)))
|
n, err = syscall.GetShortPathName(&p[0], &b[0], uint32(len(b)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
if n <= uint32(len(b)) {
|
||||||
|
return syscall.UTF16ToString(b[:n]), nil
|
||||||
|
}
|
||||||
|
b = make([]uint16, n)
|
||||||
}
|
}
|
||||||
return syscall.UTF16ToString(b), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func toLong(path string) (string, error) {
|
func toLong(path string) (string, error) {
|
||||||
@ -34,19 +33,17 @@ func toLong(path string) (string, error) {
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
b := p // GetLongPathName says we can reuse buffer
|
b := p // GetLongPathName says we can reuse buffer
|
||||||
n, err := syscall.GetLongPathName(&p[0], &b[0], uint32(len(b)))
|
n := uint32(len(b))
|
||||||
if err != nil {
|
for {
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if n > uint32(len(b)) {
|
|
||||||
b = make([]uint16, n)
|
|
||||||
n, err = syscall.GetLongPathName(&p[0], &b[0], uint32(len(b)))
|
n, err = syscall.GetLongPathName(&p[0], &b[0], uint32(len(b)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
if n <= uint32(len(b)) {
|
||||||
|
return syscall.UTF16ToString(b[:n]), nil
|
||||||
|
}
|
||||||
|
b = make([]uint16, n)
|
||||||
}
|
}
|
||||||
b = b[:n]
|
|
||||||
return syscall.UTF16ToString(b), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func evalSymlinks(path string) (string, error) {
|
func evalSymlinks(path string) (string, error) {
|
||||||
|
@ -16,19 +16,17 @@ func Getenv(key string) (value string, found bool) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
b := make([]uint16, 100)
|
n := uint32(100)
|
||||||
n, e := GetEnvironmentVariable(keyp, &b[0], uint32(len(b)))
|
for {
|
||||||
if n == 0 && e == ERROR_ENVVAR_NOT_FOUND {
|
b := make([]uint16, n)
|
||||||
|
n, err = GetEnvironmentVariable(keyp, &b[0], uint32(len(b)))
|
||||||
|
if n == 0 && err == ERROR_ENVVAR_NOT_FOUND {
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
if n > uint32(len(b)) {
|
if n <= uint32(len(b)) {
|
||||||
b = make([]uint16, n)
|
return string(utf16.Decode(b[:n])), true
|
||||||
n, e = GetEnvironmentVariable(keyp, &b[0], uint32(len(b)))
|
|
||||||
if n > uint32(len(b)) {
|
|
||||||
n = 0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return string(utf16.Decode(b[0:n])), true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Setenv(key, value string) error {
|
func Setenv(key, value string) error {
|
||||||
|
@ -135,24 +135,18 @@ func FullPath(name string) (path string, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
buf := make([]uint16, 100)
|
n := uint32(100)
|
||||||
n, err := GetFullPathName(p, uint32(len(buf)), &buf[0], nil)
|
for {
|
||||||
if err != nil {
|
buf := make([]uint16, n)
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if n > uint32(len(buf)) {
|
|
||||||
// Windows is asking for bigger buffer.
|
|
||||||
buf = make([]uint16, n)
|
|
||||||
n, err = GetFullPathName(p, uint32(len(buf)), &buf[0], nil)
|
n, err = GetFullPathName(p, uint32(len(buf)), &buf[0], nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
if n > uint32(len(buf)) {
|
if n <= uint32(len(buf)) {
|
||||||
return "", EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return UTF16ToString(buf[:n]), nil
|
return UTF16ToString(buf[:n]), nil
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func isSlash(c uint8) bool {
|
func isSlash(c uint8) bool {
|
||||||
return c == '\\' || c == '/'
|
return c == '\\' || c == '/'
|
||||||
|
@ -41,21 +41,20 @@ func TranslateAccountName(username string, from, to uint32, initSize int) (strin
|
|||||||
if e != nil {
|
if e != nil {
|
||||||
return "", e
|
return "", e
|
||||||
}
|
}
|
||||||
b := make([]uint16, 50)
|
n := uint32(50)
|
||||||
n := uint32(len(b))
|
for {
|
||||||
|
b := make([]uint16, n)
|
||||||
e = TranslateName(u, from, to, &b[0], &n)
|
e = TranslateName(u, from, to, &b[0], &n)
|
||||||
if e != nil {
|
if e == nil {
|
||||||
|
return UTF16ToString(b[:n]), nil
|
||||||
|
}
|
||||||
if e != ERROR_INSUFFICIENT_BUFFER {
|
if e != ERROR_INSUFFICIENT_BUFFER {
|
||||||
return "", e
|
return "", e
|
||||||
}
|
}
|
||||||
// make receive buffers of requested size and try again
|
if n <= uint32(len(b)) {
|
||||||
b = make([]uint16, n)
|
|
||||||
e = TranslateName(u, from, to, &b[0], &n)
|
|
||||||
if e != nil {
|
|
||||||
return "", e
|
return "", e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return UTF16ToString(b), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -136,26 +135,23 @@ func LookupSID(system, account string) (sid *SID, domain string, accType uint32,
|
|||||||
return nil, "", 0, e
|
return nil, "", 0, e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
db := make([]uint16, 50)
|
n := uint32(50)
|
||||||
dn := uint32(len(db))
|
dn := uint32(50)
|
||||||
b := make([]byte, 50)
|
for {
|
||||||
n := uint32(len(b))
|
b := make([]byte, n)
|
||||||
|
db := make([]uint16, dn)
|
||||||
sid = (*SID)(unsafe.Pointer(&b[0]))
|
sid = (*SID)(unsafe.Pointer(&b[0]))
|
||||||
e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
|
e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
|
||||||
if e != nil {
|
if e == nil {
|
||||||
|
return sid, UTF16ToString(db), accType, nil
|
||||||
|
}
|
||||||
if e != ERROR_INSUFFICIENT_BUFFER {
|
if e != ERROR_INSUFFICIENT_BUFFER {
|
||||||
return nil, "", 0, e
|
return nil, "", 0, e
|
||||||
}
|
}
|
||||||
// make receive buffers of requested size and try again
|
if n <= uint32(len(b)) {
|
||||||
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 {
|
|
||||||
return nil, "", 0, e
|
return nil, "", 0, e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sid, UTF16ToString(db), accType, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// String converts sid to a string format
|
// String converts sid to a string format
|
||||||
@ -197,24 +193,22 @@ func (sid *SID) LookupAccount(system string) (account, domain string, accType ui
|
|||||||
return "", "", 0, err
|
return "", "", 0, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b := make([]uint16, 50)
|
n := uint32(50)
|
||||||
n := uint32(len(b))
|
dn := uint32(50)
|
||||||
db := make([]uint16, 50)
|
for {
|
||||||
dn := uint32(len(db))
|
b := make([]uint16, n)
|
||||||
|
db := make([]uint16, dn)
|
||||||
e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
|
e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
|
||||||
if e != nil {
|
if e == nil {
|
||||||
|
return UTF16ToString(b), UTF16ToString(db), accType, nil
|
||||||
|
}
|
||||||
if e != ERROR_INSUFFICIENT_BUFFER {
|
if e != ERROR_INSUFFICIENT_BUFFER {
|
||||||
return "", "", 0, e
|
return "", "", 0, e
|
||||||
}
|
}
|
||||||
// make receive buffers of requested size and try again
|
if n <= uint32(len(b)) {
|
||||||
b = make([]uint16, n)
|
|
||||||
db = make([]uint16, dn)
|
|
||||||
e = LookupAccountSid(nil, sid, &b[0], &n, &db[0], &dn, &accType)
|
|
||||||
if e != nil {
|
|
||||||
return "", "", 0, e
|
return "", "", 0, e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return UTF16ToString(b), UTF16ToString(db), accType, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -326,21 +320,20 @@ func (t Token) Close() error {
|
|||||||
|
|
||||||
// getInfo retrieves a specified type of information about an access token.
|
// getInfo retrieves a specified type of information about an access token.
|
||||||
func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {
|
func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {
|
||||||
b := make([]byte, initSize)
|
n := uint32(initSize)
|
||||||
var n uint32
|
for {
|
||||||
|
b := make([]byte, n)
|
||||||
e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
|
e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
|
||||||
if e != nil {
|
if e == nil {
|
||||||
|
return unsafe.Pointer(&b[0]), nil
|
||||||
|
}
|
||||||
if e != ERROR_INSUFFICIENT_BUFFER {
|
if e != ERROR_INSUFFICIENT_BUFFER {
|
||||||
return nil, e
|
return nil, e
|
||||||
}
|
}
|
||||||
// make receive buffers of requested size and try again
|
if n <= uint32(len(b)) {
|
||||||
b = make([]byte, n)
|
|
||||||
e = GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
|
|
||||||
if e != nil {
|
|
||||||
return nil, e
|
return nil, e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return unsafe.Pointer(&b[0]), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTokenUser retrieves access token t user account information.
|
// GetTokenUser retrieves access token t user account information.
|
||||||
@ -366,19 +359,18 @@ func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) {
|
|||||||
// GetUserProfileDirectory retrieves path to the
|
// GetUserProfileDirectory retrieves path to the
|
||||||
// root directory of the access token t user's profile.
|
// root directory of the access token t user's profile.
|
||||||
func (t Token) GetUserProfileDirectory() (string, error) {
|
func (t Token) GetUserProfileDirectory() (string, error) {
|
||||||
b := make([]uint16, 100)
|
n := uint32(100)
|
||||||
n := uint32(len(b))
|
for {
|
||||||
|
b := make([]uint16, n)
|
||||||
e := GetUserProfileDirectory(t, &b[0], &n)
|
e := GetUserProfileDirectory(t, &b[0], &n)
|
||||||
if e != nil {
|
if e == nil {
|
||||||
|
return UTF16ToString(b), nil
|
||||||
|
}
|
||||||
if e != ERROR_INSUFFICIENT_BUFFER {
|
if e != ERROR_INSUFFICIENT_BUFFER {
|
||||||
return "", e
|
return "", e
|
||||||
}
|
}
|
||||||
// make receive buffers of requested size and try again
|
if n <= uint32(len(b)) {
|
||||||
b = make([]uint16, n)
|
|
||||||
e = GetUserProfileDirectory(t, &b[0], &n)
|
|
||||||
if e != nil {
|
|
||||||
return "", e
|
return "", e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return UTF16ToString(b), nil
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user