On 06/04/2013 03:44 AM, Alvaro Polo wrote:
> OpenVZ was accessing ethernet data to obtain the guest iface name
> regardless the domain is configured to use ethernet or bridged
> networking. This prevented the guest network interface to be rightly
> named for bridged networking.
> ---
>  src/openvz/openvz_driver.c | 20 +++++++++++++-------
>  1 file changed, 13 insertions(+), 7 deletions(-)
> 
> diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
> index c8081ce..db738a4 100644
> --- a/src/openvz/openvz_driver.c
> +++ b/src/openvz/openvz_driver.c
> @@ -815,6 +815,7 @@ openvzDomainSetNetwork(virConnectPtr conn, const char 
> *vpsid,
>      char host_macaddr[VIR_MAC_STRING_BUFLEN];
>      struct openvz_driver *driver =  conn->privateData;
>      virCommandPtr cmd = NULL;
> +    char *guest_ifname = NULL;
>  
>      if (net == NULL)
>         return 0;
> @@ -840,11 +841,15 @@ openvzDomainSetNetwork(virConnectPtr conn, const char 
> *vpsid,
>          virBuffer buf = VIR_BUFFER_INITIALIZER;
>          int veid = openvzGetVEID(vpsid);
>  
> -        /* if user doesn't specify guest interface name,
> -         * then we need to generate it */
> -        if (net->data.ethernet.dev == NULL) {
> -            net->data.ethernet.dev = openvzGenerateContainerVethName(veid);
> -            if (net->data.ethernet.dev == NULL) {
> +        /* if net is ethernet and the user has specified guest interface 
> name,
> +         * let's use it; otherwise generate a new one */
> +        if (net->type == VIR_DOMAIN_NET_TYPE_ETHERNET &&
> +            net->data.ethernet.dev != NULL) {

[1] I know this code was pushed, but see note below

> +            if (VIR_STRDUP(guest_ifname, net->data.ethernet.dev) == -1)
> +                goto cleanup;
> +        } else {
> +            guest_ifname = openvzGenerateContainerVethName(veid);
> +            if (guest_ifname == NULL) {
>                 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
>                                _("Could not generate eth name for 
> container"));
>                 goto cleanup;
> @@ -862,7 +867,7 @@ openvzDomainSetNetwork(virConnectPtr conn, const char 
> *vpsid,
>              }
>          }
>  
> -        virBufferAdd(&buf, net->data.ethernet.dev, -1); /* Guest dev */
> +        virBufferAdd(&buf, guest_ifname, -1); /* Guest dev */
>          virBufferAsprintf(&buf, ",%s", macaddr); /* Guest dev mac */
>          virBufferAsprintf(&buf, ",%s", net->ifname); /* Host dev */
>          virBufferAsprintf(&buf, ",%s", host_macaddr); /* Host dev mac */
> @@ -871,7 +876,7 @@ openvzDomainSetNetwork(virConnectPtr conn, const char 
> *vpsid,
>              if (driver->version >= VZCTL_BRIDGE_MIN_VERSION) {
>                  virBufferAsprintf(&buf, ",%s", net->data.bridge.brname); /* 
> Host bridge */
>              } else {
> -                virBufferAsprintf(configBuf, "ifname=%s", 
> net->data.ethernet.dev);
> +                virBufferAsprintf(configBuf, "ifname=%s", guest_ifname);
>                  virBufferAsprintf(configBuf, ",mac=%s", macaddr); /* Guest 
> dev mac */
>                  virBufferAsprintf(configBuf, ",host_ifname=%s", 
> net->ifname); /* Host dev */
>                  virBufferAsprintf(configBuf, ",host_mac=%s", host_macaddr); 
> /* Host dev mac */
> @@ -895,6 +900,7 @@ openvzDomainSetNetwork(virConnectPtr conn, const char 
> *vpsid,
>  
>   cleanup:
>      virCommandFree(cmd);
> +    VIR_FREE(guest_ifname);
>      return rc;
>  }
>  
> 

[1] My nightly Coverity run had the following complaint as a result of this 
patch:


818         char *guest_ifname = NULL;
819     

(1) Event cond_false:   Condition "net == NULL", taking false branch

820         if (net == NULL)
821            return 0;

(2) Event cond_false:   Condition "vpsid == NULL", taking false branch

822         if (vpsid == NULL) {
823             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
824                            _("Container ID is not specified"));
825             return -1;

(3) Event if_end:       End of if statement

826         }
827     

(4) Event cond_true:    Condition "net->type != VIR_DOMAIN_NET_TYPE_BRIDGE", 
taking true branch
(5) Event cond_false:   Condition "net->type != VIR_DOMAIN_NET_TYPE_ETHERNET", 
taking false branch

828         if (net->type != VIR_DOMAIN_NET_TYPE_BRIDGE &&
829             net->type != VIR_DOMAIN_NET_TYPE_ETHERNET)
830             return 0;
831     
832         cmd = virCommandNewArgList(VZCTL, "--quiet", "set", vpsid, NULL);
833     
834         virMacAddrFormat(&net->mac, macaddr);
835         virDomainNetGenerateMAC(driver->xmlopt, &host_mac);
836         virMacAddrFormat(&host_mac, host_macaddr);
837     

(6) Event cond_false:   Condition "net->type == VIR_DOMAIN_NET_TYPE_BRIDGE", 
taking false branch
(7) Event cond_true:    Condition "net->type == VIR_DOMAIN_NET_TYPE_ETHERNET", 
taking true branch
(8) Event cond_true:    Condition "net->data.ethernet.ipaddr == NULL", taking 
true branch

838         if (net->type == VIR_DOMAIN_NET_TYPE_BRIDGE ||
839             (net->type == VIR_DOMAIN_NET_TYPE_ETHERNET &&
840              net->data.ethernet.ipaddr == NULL)) {
841             virBuffer buf = VIR_BUFFER_INITIALIZER;
842             int veid = openvzGetVEID(vpsid);
843     
844             /* if net is ethernet and the user has specified guest 
interface name,
845              * let's use it; otherwise generate a new one */

(9) Event cond_true:    Condition "net->type == VIR_DOMAIN_NET_TYPE_ETHERNET", 
taking true branch
(10) Event cond_false:  Condition "net->data.ethernet.dev != NULL", taking 
false branch
(12) Event var_compare_op:      Comparing "net->data.ethernet.dev" to null 
implies that "net->data.ethernet.dev" might be null.
Also see events:        [var_deref_model]

846             if (net->type == VIR_DOMAIN_NET_TYPE_ETHERNET &&
847                 net->data.ethernet.dev != NULL) {
848                 if (VIR_STRDUP(guest_ifname, net->data.ethernet.dev) == -1)
849                     goto cleanup;

(11) Event else_branch:         Reached else branch

850             } else {
851                 guest_ifname = openvzGenerateContainerVethName(veid);

(13) Event cond_false:  Condition "guest_ifname == NULL", taking false branch

852                 if (guest_ifname == NULL) {
853                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
854                                   _("Could not generate eth name for 
container"));
855                    goto cleanup;

(14) Event if_end:      End of if statement

856                 }
857             }
858     
859             /* if user doesn't specified host interface name,
860              * than we need to generate it */

(15) Event cond_true:   Condition "net->ifname == NULL", taking true branch

861             if (net->ifname == NULL) {

(16) Event var_deref_model:     Passing null pointer "net->data.ethernet.dev" 
to function "openvzGenerateVethName(int, char *)", which dereferences it. 
[details]
Also see events:        [var_compare_op]

862                 net->ifname = openvzGenerateVethName(veid, 
net->data.ethernet.dev);
863                 if (net->ifname == NULL) {
864                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
865                                   _("Could not generate veth name"));
866                    goto cleanup;
867                 }
868             }
869  

If I'm reading the code correctly, it seems replacing 'net->data.ethernet.dev' 
with 'guest_ifname' at line 862 will be the right solution. Doing so makes
Coverity happy.  Previously the code guarenteed data.ethernet.dev was filled
in with the openvzGenerateContainerVethName() result.


John
 

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to