From 5bc4967b63aa2e9dffad723fefd91b569db21bb3 Mon Sep 17 00:00:00 2001 From: Brandon Dyck Date: Mon, 28 Nov 2022 23:59:12 -0700 Subject: [PATCH] Fixed use-after-free bug from AddImportPath --- ph7.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/ph7.go b/ph7.go index 08880f0..fb21e58 100644 --- a/ph7.go +++ b/ph7.go @@ -124,6 +124,7 @@ func (e *Engine) compileError(code C.int) error { func (e *Engine) Compile(source []byte, phpOnly bool) (*VM, error) { csource := C.CBytes(source) + // TODO Is this a UAF bug? defer C.free(csource) var flags C.int if phpOnly { @@ -140,6 +141,7 @@ func (e *Engine) Compile(source []byte, phpOnly bool) (*VM, error) { func (e *Engine) CompileFile(path string, phpOnly bool) (*VM, error) { cpath := C.CString(path) + // TODO Is this a UAF bug? defer C.free(unsafe.Pointer(cpath)) var flags C.int @@ -468,6 +470,7 @@ type VM struct { outputWriter io.Writer outputWriteErr error userFunctionKeys []unsafe.Pointer + retainedPointers []unsafe.Pointer } func newVM(cvm *C.ph7_vm) *VM { @@ -477,6 +480,10 @@ func newVM(cvm *C.ph7_vm) *VM { return vm } +func (vm *VM) retainPointer(p unsafe.Pointer) { + vm.retainedPointers = append(vm.retainedPointers, p) +} + //export write_vm_output func write_vm_output(buf unsafe.Pointer, bufLen C.uint, userData unsafe.Pointer) C.int { vm := pointer.Restore(userData).(*VM) @@ -496,7 +503,7 @@ func (vm *VM) SetOutputWriter(w io.Writer) error { func (vm *VM) AddImportPath(path string) error { cpath := C.CString(path) - defer C.free(unsafe.Pointer(cpath)) + vm.retainPointer(unsafe.Pointer(cpath)) return newError(C.vm_add_import_path(vm.ptr, cpath)) } @@ -560,6 +567,9 @@ func (vm *VM) Close() error { for _, key := range vm.userFunctionKeys { pointer.Unref(key) } + for _, p := range vm.retainedPointers { + C.free(p) + } return newError(C.ph7_vm_release(vm.ptr)) } @@ -580,6 +590,7 @@ func call_foreign_function(ctx *C.ph7_context, argc C.int, argv **C.ph7_value) C func (vm *VM) CreateFunction(name string, f Function) error { cname := C.CString(name) + // TODO Is this a UAF bug? defer C.free(unsafe.Pointer(cname)) fkey := pointer.Save(f)