Commit 62fb079e authored by Jason A. Donenfeld's avatar Jason A. Donenfeld

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: default avatarAlex Brainman <alex.brainman@gmail.com>
parent fa42157d
...@@ -117,6 +117,18 @@ func (p *Param) BoolTmpVarCode() string { ...@@ -117,6 +117,18 @@ func (p *Param) BoolTmpVarCode() string {
return fmt.Sprintf(code, tmp, p.Name, tmp, tmp) 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. // SliceTmpVarCode returns source code for slice temp variable.
func (p *Param) SliceTmpVarCode() string { func (p *Param) SliceTmpVarCode() string {
const code = `var %s *%s const code = `var %s *%s
...@@ -152,6 +164,8 @@ func (p *Param) TmpVarCode() string { ...@@ -152,6 +164,8 @@ func (p *Param) TmpVarCode() string {
switch { switch {
case p.Type == "bool": case p.Type == "bool":
return p.BoolTmpVarCode() return p.BoolTmpVarCode()
case p.Type == "*bool":
return p.BoolPointerTmpVarCode()
case strings.HasPrefix(p.Type, "[]"): case strings.HasPrefix(p.Type, "[]"):
return p.SliceTmpVarCode() return p.SliceTmpVarCode()
default: default:
...@@ -159,6 +173,16 @@ func (p *Param) TmpVarCode() string { ...@@ -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. // TmpVarHelperCode returns source code for helper's temp variable.
func (p *Param) TmpVarHelperCode() string { func (p *Param) TmpVarHelperCode() string {
if p.Type != "string" { if p.Type != "string" {
...@@ -174,6 +198,8 @@ func (p *Param) SyscallArgList() []string { ...@@ -174,6 +198,8 @@ func (p *Param) SyscallArgList() []string {
t := p.HelperType() t := p.HelperType()
var s string var s string
switch { switch {
case t == "*bool":
s = fmt.Sprintf("unsafe.Pointer(&%s)", p.tmpVar())
case t[0] == '*': case t[0] == '*':
s = fmt.Sprintf("unsafe.Pointer(%s)", p.Name) s = fmt.Sprintf("unsafe.Pointer(%s)", p.Name)
case t == "bool": case t == "bool":
...@@ -876,7 +902,7 @@ func {{.Name}}({{.ParamList}}) {{template "results" .}}{ ...@@ -876,7 +902,7 @@ func {{.Name}}({{.ParamList}}) {{template "results" .}}{
{{define "funcbody"}} {{define "funcbody"}}
func {{.HelperName}}({{.HelperParamList}}) {{template "results" .}}{ func {{.HelperName}}({{.HelperParamList}}) {{template "results" .}}{
{{template "tmpvars" .}} {{template "syscall" .}} {{template "tmpvars" .}} {{template "syscall" .}} {{template "tmpvarsreadback" .}}
{{template "seterror" .}}{{template "printtrace" .}} return {{template "seterror" .}}{{template "printtrace" .}} return
} }
{{end}} {{end}}
...@@ -891,6 +917,9 @@ func {{.HelperName}}({{.HelperParamList}}) {{template "results" .}}{ ...@@ -891,6 +917,9 @@ func {{.HelperName}}({{.HelperParamList}}) {{template "results" .}}{
{{define "syscall"}}{{.Rets.SetReturnValuesCode}}{{.Syscall}}(proc{{.DLLFuncName}}.Addr(), {{.ParamCount}}, {{.SyscallParamList}}){{end}} {{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}} {{define "seterror"}}{{if .Rets.SetErrorCode}} {{.Rets.SetErrorCode}}
{{end}}{{end}} {{end}}{{end}}
......
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