Skip to content

Commit 62fb079

Browse files
committed
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 <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Alex Brainman <[email protected]>
1 parent fa42157 commit 62fb079

File tree

1 file changed

+30
-1
lines changed

1 file changed

+30
-1
lines changed

src/syscall/mksyscall_windows.go

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,18 @@ func (p *Param) BoolTmpVarCode() string {
117117
return fmt.Sprintf(code, tmp, p.Name, tmp, tmp)
118118
}
119119

120+
// BoolPointerTmpVarCode returns source code for bool temp variable.
121+
func (p *Param) BoolPointerTmpVarCode() string {
122+
const code = `var %s uint32
123+
if *%s {
124+
%s = 1
125+
} else {
126+
%s = 0
127+
}`
128+
tmp := p.tmpVar()
129+
return fmt.Sprintf(code, tmp, p.Name, tmp, tmp)
130+
}
131+
120132
// SliceTmpVarCode returns source code for slice temp variable.
121133
func (p *Param) SliceTmpVarCode() string {
122134
const code = `var %s *%s
@@ -152,13 +164,25 @@ func (p *Param) TmpVarCode() string {
152164
switch {
153165
case p.Type == "bool":
154166
return p.BoolTmpVarCode()
167+
case p.Type == "*bool":
168+
return p.BoolPointerTmpVarCode()
155169
case strings.HasPrefix(p.Type, "[]"):
156170
return p.SliceTmpVarCode()
157171
default:
158172
return ""
159173
}
160174
}
161175

176+
// TmpVarReadbackCode returns source code for reading back the temp variable into the original variable.
177+
func (p *Param) TmpVarReadbackCode() string {
178+
switch {
179+
case p.Type == "*bool":
180+
return fmt.Sprintf("*%s = %s != 0", p.Name, p.tmpVar())
181+
default:
182+
return ""
183+
}
184+
}
185+
162186
// TmpVarHelperCode returns source code for helper's temp variable.
163187
func (p *Param) TmpVarHelperCode() string {
164188
if p.Type != "string" {
@@ -174,6 +198,8 @@ func (p *Param) SyscallArgList() []string {
174198
t := p.HelperType()
175199
var s string
176200
switch {
201+
case t == "*bool":
202+
s = fmt.Sprintf("unsafe.Pointer(&%s)", p.tmpVar())
177203
case t[0] == '*':
178204
s = fmt.Sprintf("unsafe.Pointer(%s)", p.Name)
179205
case t == "bool":
@@ -876,7 +902,7 @@ func {{.Name}}({{.ParamList}}) {{template "results" .}}{
876902
877903
{{define "funcbody"}}
878904
func {{.HelperName}}({{.HelperParamList}}) {{template "results" .}}{
879-
{{template "tmpvars" .}} {{template "syscall" .}}
905+
{{template "tmpvars" .}} {{template "syscall" .}} {{template "tmpvarsreadback" .}}
880906
{{template "seterror" .}}{{template "printtrace" .}} return
881907
}
882908
{{end}}
@@ -891,6 +917,9 @@ func {{.HelperName}}({{.HelperParamList}}) {{template "results" .}}{
891917
892918
{{define "syscall"}}{{.Rets.SetReturnValuesCode}}{{.Syscall}}(proc{{.DLLFuncName}}.Addr(), {{.ParamCount}}, {{.SyscallParamList}}){{end}}
893919
920+
{{define "tmpvarsreadback"}}{{range .Params}}{{if .TmpVarReadbackCode}}
921+
{{.TmpVarReadbackCode}}{{end}}{{end}}{{end}}
922+
894923
{{define "seterror"}}{{if .Rets.SetErrorCode}} {{.Rets.SetErrorCode}}
895924
{{end}}{{end}}
896925

0 commit comments

Comments
 (0)