]> Cypherpunks repositories - gostls13.git/commitdiff
syscall: avoid memory corruption in mksyscall_windows.go with *bool parameters
authorJason A. Donenfeld <Jason@zx2c4.com>
Wed, 18 Sep 2019 06:10:07 +0000 (00:10 -0600)
committerJason A. Donenfeld <Jason@zx2c4.com>
Thu, 19 Sep 2019 04:46:17 +0000 (04:46 +0000)
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>
src/syscall/mksyscall_windows.go

index ee2123f9393fc0740c2b739a59061a2e0d6d4670..dbeb684be62145d6ebfc8430cad5ee8b06346772 100644 (file)
@@ -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}}