[libvirt] [PATCH] conf: utility function to update entry in def->nets array

Michal Privoznik mprivozn at redhat.com
Thu Sep 26 07:28:21 UTC 2019


On 9/25/19 6:57 PM, Laine Stump wrote:
> A virDomainNetDef object in a domain's nets array might contain a
> virDomainHostdevDef, and when this is the case, the domain's hostdevs
> array will also have a pointer to this embedded hostdev (this is done
> so that internal functions that need to perform some operation on all
> hostdevs won't leave out the type='hostdev' network interfaces).
> 
> When a network device was updated with virDomainUpdateDeviceFlags(),
> we were replacing the entry in the nets array (and free'ing the
> original) but forgetting about the pointer in the hostdevs array
> (which would then point to the now-free'd hostdev contained in the old
> net object.) This often resulted in a libvirtd crash.
> 
> The solution is to add a function, virDomainNetUpdate(), called by
> qemuDomainUpdateDeviceConfig(), that updates the hostdevs array
> appropriately along with the nets array.
> 
> Resolves: https://bugzilla.redhat.com/1558934
> Signed-off-by: Laine Stump <laine at redhat.com>
> 
> ---
> 
> (I actually think that it was a bad idea to have this "reach over"
> pointer in the hostdevs array (I can say that, since it was my idea
> :-), and want to eliminate it in favor of using an iterator function
> for all operations that need to do something to all hostdevs, but this
> bug exists on old, maintained branches, and I wouldn't want to require
> backporting anything that disruptive to a stable branch.)
> 
> Also, I was unable to reproduce the crashes described in the bug
> report using current upstream code, but could witness (by adding a
> breakpoint in gdb) the stale pointer when running without this patch,
> and the correct pointer when running with the patch)

Agreed, refactoring the whole approach would require a significant 
amount of work and it's not worth it only to fix a crasher.

> 
>   src/conf/domain_conf.c   | 41 ++++++++++++++++++++++++++++++++++++++++
>   src/conf/domain_conf.h   |  1 +
>   src/libvirt_private.syms |  1 +
>   src/qemu/qemu_driver.c   |  6 ++++--
>   4 files changed, 47 insertions(+), 2 deletions(-)
> 

> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 0753904472..5f63c4f51e 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -8786,8 +8786,10 @@ qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef,
>                                            false) < 0)
>               return -1;
>   
> -        virDomainNetDefFree(vmdef->nets[pos]);
> -        vmdef->nets[pos] = net;
> +        if (virDomainNetUpdate(vmdef, pos, net))
> +            return -1;
> +
> +        virDomainNetDefFree(oldDev.data.net);
>           dev->data.net = NULL;
>           break;
>   
> 

The same code pattern occurrs in lxcDomainUpdateDeviceConfig() so you 
may want to fix it the same way as you're doing here. With that,

Reviewed-by: Michal Privoznik <mprivozn at redhat.com>

Michal




More information about the libvir-list mailing list