[ovs-dev] [PATCH] ofproto-dpif: Complete all packet translations before freeing an ofproto.
Alex Wang
alexw at nicira.com
Mon Feb 24 20:25:41 UTC 2014
Acked-by: Alex Wang <alexw at nicira.com>
On Mon, Feb 24, 2014 at 11:10 AM, Ben Pfaff <blp at nicira.com> wrote:
> The following scenario can occur:
>
> 1. Handler thread grabs a pointer to an ofproto in handle_upcalls().
>
> 2. Main thread removes ofproto and destroys it in destruct().
>
> 3. Handler thread uses pointer to ofproto and accesses freed memory.
> BOOM!
>
> Each individual step above happens under the xlate_rwlock, but the ofproto
> pointer is retained from step 1 to step 3, hence the problem. This commit
> fixes the problem by ensuring that after an ofproto is removed but before
> it is destroyed, all packet translations get pushed all the way through
> the upcall handler pipeline. (No new packet translations can get a pointer
> to the removed ofproto.)
>
> Bug #1200351.
> Signed-off-by: Ben Pfaff <blp at nicira.com>
> ---
> ofproto/ofproto-dpif-upcall.c | 16 ++++++++++++++++
> ofproto/ofproto-dpif-upcall.h | 3 ++-
> ofproto/ofproto-dpif.c | 6 +++---
> 3 files changed, 21 insertions(+), 4 deletions(-)
>
> diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
> index cad1310..53295aa 100644
> --- a/ofproto/ofproto-dpif-upcall.c
> +++ b/ofproto/ofproto-dpif-upcall.c
> @@ -412,6 +412,22 @@ udpif_set_threads(struct udpif *udpif, size_t
> n_handlers,
> }
> }
>
> +/* Waits for all ongoing upcall translations to complete. This ensures
> that
> + * there are no transient references to any removed ofprotos (or other
> + * objects). In particular, this should be called after an ofproto is
> removed
> + * (e.g. via xlate_remove_ofproto()) but before it is destroyed. */
> +void
> +udpif_synchronize(struct udpif *udpif)
> +{
> + /* This is stronger than necessary. It would be sufficient to ensure
> + * (somehow) that each handler and revalidator thread had passed
> through
> + * its main loop once. */
> + size_t n_handlers = udpif->n_handlers;
> + size_t n_revalidators = udpif->n_revalidators;
> + udpif_set_threads(udpif, 0, 0);
> + udpif_set_threads(udpif, n_handlers, n_revalidators);
> +}
> +
> /* Notifies 'udpif' that something changed which may render previous
> * xlate_actions() results invalid. */
> void
> diff --git a/ofproto/ofproto-dpif-upcall.h b/ofproto/ofproto-dpif-upcall.h
> index d73ae4c..9eeee5b 100644
> --- a/ofproto/ofproto-dpif-upcall.h
> +++ b/ofproto/ofproto-dpif-upcall.h
> @@ -1,4 +1,4 @@
> -/* Copyright (c) 2013 Nicira, Inc.
> +/* Copyright (c) 2013, 2014 Nicira, Inc.
> *
> * Licensed under the Apache License, Version 2.0 (the "License");
> * you may not use this file except in compliance with the License.
> @@ -29,6 +29,7 @@ struct simap;
> struct udpif *udpif_create(struct dpif_backer *, struct dpif *);
> void udpif_set_threads(struct udpif *, size_t n_handlers,
> size_t n_revalidators);
> +void udpif_synchronize(struct udpif *);
> void udpif_destroy(struct udpif *);
> void udpif_revalidate(struct udpif *);
> void udpif_get_memory_usage(struct udpif *, struct simap *usage);
> diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
> index 64e2747..c597114 100644
> --- a/ofproto/ofproto-dpif.c
> +++ b/ofproto/ofproto-dpif.c
> @@ -1182,9 +1182,9 @@ destruct(struct ofproto *ofproto_)
> xlate_remove_ofproto(ofproto);
> ovs_rwlock_unlock(&xlate_rwlock);
>
> - /* Discard any flow_miss_batches queued up for 'ofproto', avoiding a
> - * use-after-free error. */
> - udpif_revalidate(ofproto->backer->udpif);
> + /* Ensure that the upcall processing threads have no remaining
> references
> + * to the ofproto or anything in it. */
> + udpif_synchronize(ofproto->backer->udpif);
>
> hmap_remove(&all_ofproto_dpifs, &ofproto->all_ofproto_dpifs_node);
>
> --
> 1.7.10.4
>
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openvswitch.org/pipermail/ovs-dev/attachments/20140224/12ddcddd/attachment-0005.html>
More information about the dev
mailing list