diff options
| author | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-09-18 00:10:07 -0600 |
|---|---|---|
| committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-09-19 04:46:17 +0000 |
| commit | 62fb079e2b374d0e64f5432191f53cecd5282f6b (patch) | |
| tree | b93f94e9079de1509852e645187d04c0ab136298 /src/syscall | |
| parent | fa42157d986c69664e2146b520ff45be204af8eb (diff) | |
| download | go-62fb079e2b374d0e64f5432191f53cecd5282f6b.tar.xz | |
syscall: avoid memory corruption in mksyscall_windows.go with *bool parameters
Windows type PBOOL is a pointer to a 4 byte value, where 0 means false
and not-0 means true. That means we should use uint32 here, not bool,
since Go bools can be 1 byte. Since a *bool is never a "real" valid
Windows type, converting on both in and out is probably sufficient,
since *bool shouldn't ever be used as something with significance for
its particular address.
Updates: #34364
Change-Id: I4c1b91cd9a39d91e23dae6f894b9a49f7fba2c0a
Reviewed-on: https://go-review.googlesource.com/c/go/+/196122
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Diffstat (limited to 'src/syscall')
| -rw-r--r-- | src/syscall/mksyscall_windows.go | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/src/syscall/mksyscall_windows.go b/src/syscall/mksyscall_windows.go index ee2123f939..dbeb684be6 100644 --- a/src/syscall/mksyscall_windows.go +++ b/src/syscall/mksyscall_windows.go @@ -117,6 +117,18 @@ func (p *Param) BoolTmpVarCode() string { return fmt.Sprintf(code, tmp, p.Name, tmp, tmp) } +// BoolPointerTmpVarCode returns source code for bool temp variable. +func (p *Param) BoolPointerTmpVarCode() string { + const code = `var %s uint32 + if *%s { + %s = 1 + } else { + %s = 0 + }` + tmp := p.tmpVar() + return fmt.Sprintf(code, tmp, p.Name, tmp, tmp) +} + // SliceTmpVarCode returns source code for slice temp variable. func (p *Param) SliceTmpVarCode() string { const code = `var %s *%s @@ -152,6 +164,8 @@ func (p *Param) TmpVarCode() string { switch { case p.Type == "bool": return p.BoolTmpVarCode() + case p.Type == "*bool": + return p.BoolPointerTmpVarCode() case strings.HasPrefix(p.Type, "[]"): return p.SliceTmpVarCode() default: @@ -159,6 +173,16 @@ func (p *Param) TmpVarCode() string { } } +// TmpVarReadbackCode returns source code for reading back the temp variable into the original variable. +func (p *Param) TmpVarReadbackCode() string { + switch { + case p.Type == "*bool": + return fmt.Sprintf("*%s = %s != 0", p.Name, p.tmpVar()) + default: + return "" + } +} + // TmpVarHelperCode returns source code for helper's temp variable. func (p *Param) TmpVarHelperCode() string { if p.Type != "string" { @@ -174,6 +198,8 @@ func (p *Param) SyscallArgList() []string { t := p.HelperType() var s string switch { + case t == "*bool": + s = fmt.Sprintf("unsafe.Pointer(&%s)", p.tmpVar()) case t[0] == '*': s = fmt.Sprintf("unsafe.Pointer(%s)", p.Name) case t == "bool": @@ -876,7 +902,7 @@ func {{.Name}}({{.ParamList}}) {{template "results" .}}{ {{define "funcbody"}} func {{.HelperName}}({{.HelperParamList}}) {{template "results" .}}{ -{{template "tmpvars" .}} {{template "syscall" .}} +{{template "tmpvars" .}} {{template "syscall" .}} {{template "tmpvarsreadback" .}} {{template "seterror" .}}{{template "printtrace" .}} return } {{end}} @@ -891,6 +917,9 @@ func {{.HelperName}}({{.HelperParamList}}) {{template "results" .}}{ {{define "syscall"}}{{.Rets.SetReturnValuesCode}}{{.Syscall}}(proc{{.DLLFuncName}}.Addr(), {{.ParamCount}}, {{.SyscallParamList}}){{end}} +{{define "tmpvarsreadback"}}{{range .Params}}{{if .TmpVarReadbackCode}} +{{.TmpVarReadbackCode}}{{end}}{{end}}{{end}} + {{define "seterror"}}{{if .Rets.SetErrorCode}} {{.Rets.SetErrorCode}} {{end}}{{end}} |
