]> xenbits.xensource.com Git - xen.git/commitdiff
golang/xenlight: Don't leak memory on context open failure
authorGeorge Dunlap <george.dunlap@citrix.com>
Fri, 17 Jan 2020 14:01:05 +0000 (14:01 +0000)
committerGeorge Dunlap <george.dunlap@citrix.com>
Tue, 21 Jan 2020 17:48:24 +0000 (17:48 +0000)
If libxl_ctx_alloc() returns an error, we need to destroy the logger
that we made.

Restructure the Close() method such that it checks for each resource
to be freed and then frees it.  This allows Close() to be come
idempotent, as well as to be a useful clean-up to a partially-created
context.

Signed-off-by: George Dunlap <george.dunlap@citrix.com>
Reviewed-by: Nick Rosbrook <rosbrookn@ainfosec.com>
tools/golang/xenlight/xenlight.go

index aa1e63a61a6ee39e3fce1c69fc1fab90ffc4fca9..3f1b0baa0cb4d69aa04167f7cf036c50df94dec5 100644 (file)
@@ -79,28 +79,40 @@ type Context struct {
 }
 
 // NewContext returns a new Context.
-func NewContext() (*Context, error) {
-       var ctx Context
+func NewContext() (ctx *Context, err error) {
+       ctx = &Context{}
+
+       defer func() {
+               if err != nil {
+                       ctx.Close()
+                       ctx = nil
+               }
+       }()
 
        ctx.logger = C.xtl_createlogger_stdiostream(C.stderr, C.XTL_ERROR, 0)
 
        ret := C.libxl_ctx_alloc(&ctx.ctx, C.LIBXL_VERSION, 0,
                (*C.xentoollog_logger)(unsafe.Pointer(ctx.logger)))
        if ret != 0 {
-               return nil, Error(ret)
+               return ctx, Error(ret)
        }
 
-       return &ctx, nil
+       return ctx, nil
 }
 
 // Close closes the Context.
 func (ctx *Context) Close() error {
-       ret := C.libxl_ctx_free(ctx.ctx)
-       ctx.ctx = nil
-       C.xtl_logger_destroy((*C.xentoollog_logger)(unsafe.Pointer(ctx.logger)))
+       if ctx.ctx != nil {
+               ret := C.libxl_ctx_free(ctx.ctx)
+               if ret != 0 {
+                       return Error(ret)
+               }
+               ctx.ctx = nil
+       }
 
-       if ret != 0 {
-               return Error(ret)
+       if ctx.logger != nil {
+               C.xtl_logger_destroy((*C.xentoollog_logger)(unsafe.Pointer(ctx.logger)))
+               ctx.logger = nil
        }
 
        return nil