libvchan: handle libxc evtchn failures properly in init functions
authorMatthew Daley <mattjd@gmail.com>
Thu, 31 Oct 2013 03:41:32 +0000 (16:41 +1300)
committerIan Campbell <ian.campbell@citrix.com>
Thu, 31 Oct 2013 21:55:53 +0000 (21:55 +0000)
The reasoning behind this patch is that ctrl->event_port is a uint32_t
(ie. unsigned), so the current checks on it for negative error results,
non-negative port presence etc. are incorrect.

Fix by using evtchn_port_or_error_t in the init functions instead,
adjusting the error handling, and removing the now-unnecessary check
from the close function.

Coverity-ID: 1055609
Coverity-ID: 1055610
Coverity-ID: 1055611
Signed-off-by: Matthew Daley <mattjd@gmail.com>
Reviewed-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
tools/libvchan/init.c
tools/libvchan/io.c

index 0c7cff6c578be4b074065c592b5435e781688e81..c080a1cbe4d67649981d6310cbc9dda3cab22c00 100644 (file)
@@ -215,15 +215,30 @@ static int init_gnt_cli(struct libxenvchan *ctrl, int domain, uint32_t ring_ref)
 
 static int init_evt_srv(struct libxenvchan *ctrl, int domain, xentoollog_logger *logger)
 {
+       evtchn_port_or_error_t port;
+
        ctrl->event = xc_evtchn_open(logger, 0);
        if (!ctrl->event)
                return -1;
-       ctrl->event_port = xc_evtchn_bind_unbound_port(ctrl->event, domain);
-       if (ctrl->event_port < 0)
-               return -1;
+
+       port = xc_evtchn_bind_unbound_port(ctrl->event, domain);
+       if (port < 0)
+               goto fail;
+       ctrl->event_port = port;
+
        if (xc_evtchn_unmask(ctrl->event, ctrl->event_port))
-               return -1;
+               goto fail;
+
        return 0;
+
+fail:
+       if (port >= 0)
+               xc_evtchn_unbind(ctrl->event, port);
+
+       xc_evtchn_close(ctrl->event);
+       ctrl->event = NULL;
+
+       return -1;
 }
 
 static int init_xs_srv(struct libxenvchan *ctrl, int domain, const char* xs_base, int ring_ref)
@@ -330,15 +345,31 @@ out:
 
 static int init_evt_cli(struct libxenvchan *ctrl, int domain, xentoollog_logger *logger)
 {
+       evtchn_port_or_error_t port;
+
        ctrl->event = xc_evtchn_open(logger, 0);
        if (!ctrl->event)
                return -1;
-       ctrl->event_port = xc_evtchn_bind_interdomain(ctrl->event,
+
+       port = xc_evtchn_bind_interdomain(ctrl->event,
                domain, ctrl->event_port);
-       if (ctrl->event_port < 0)
-               return -1;
-       xc_evtchn_unmask(ctrl->event, ctrl->event_port);
+       if (port < 0)
+               goto fail;
+       ctrl->event_port = port;
+
+       if (xc_evtchn_unmask(ctrl->event, ctrl->event_port))
+               goto fail;
+
        return 0;
+
+fail:
+       if (port >= 0)
+               xc_evtchn_unbind(ctrl->event, port);
+
+       xc_evtchn_close(ctrl->event);
+       ctrl->event = NULL;
+
+       return -1;
 }
 
 
index 3c8d236e520f9f82b0cffb03daa75c885dac211c..2383364cc5c1b04b9384ab6009bf4e60ecf72017 100644 (file)
@@ -337,7 +337,7 @@ void libxenvchan_close(struct libxenvchan *ctrl)
                }
        }
        if (ctrl->event) {
-               if (ctrl->event_port >= 0 && ctrl->ring)
+               if (ctrl->ring)
                        xc_evtchn_notify(ctrl->event, ctrl->event_port);
                xc_evtchn_close(ctrl->event);
        }