All of lore.kernel.org
 help / color / mirror / Atom feed
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
To: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Juergen Gross <jgross@suse.com>,
	Xen-devel <xen-devel@lists.xenproject.org>,
	Ross Lagerwall <ross.lagerwall@citrix.com>
Subject: Re: [Xen-devel] [PATCH 2/2] x86/livepatch: Prevent patching with active waitqueues
Date: Wed, 6 Nov 2019 09:25:13 -0500	[thread overview]
Message-ID: <20191106142513.GB5520@localhost.localdomain> (raw)
In-Reply-To: <20191105194317.16232-3-andrew.cooper3@citrix.com>

On Tue, Nov 05, 2019 at 07:43:17PM +0000, Andrew Cooper wrote:
> The safety of livepatching depends on every stack having been unwound, but
> there is one corner case where this is not true.  The Sharing/Paging/Monitor
> infrastructure may use waitqueues, which copy the stack frame sideways and
> longjmp() to a different vcpu.
> 
> This case is rare, and can be worked around by pausing the offending
> domain(s), waiting for their rings to drain, then performing a livepatch.
> 
> In the case that there is an active waitqueue, fail the livepatch attempt with
> -EBUSY, which is preforable to the fireworks which occur from trying to unwind
> the old stack frame at a later point.
> 
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
> CC: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>

Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>

> CC: Ross Lagerwall <ross.lagerwall@citrix.com>
> CC: Juergen Gross <jgross@suse.com>
> 
> This fix wants backporting, and is long overdue for posting upstream.
> ---
>  xen/arch/arm/livepatch.c    |  5 +++++
>  xen/arch/x86/livepatch.c    | 39 +++++++++++++++++++++++++++++++++++++++
>  xen/common/livepatch.c      |  7 +++++++
>  xen/include/xen/livepatch.h |  1 +
>  4 files changed, 52 insertions(+)
> 
> diff --git a/xen/arch/arm/livepatch.c b/xen/arch/arm/livepatch.c
> index 00c5e2bc45..915e9d926a 100644
> --- a/xen/arch/arm/livepatch.c
> +++ b/xen/arch/arm/livepatch.c
> @@ -18,6 +18,11 @@
>  
>  void *vmap_of_xen_text;
>  
> +int arch_livepatch_safety_check(void)
> +{
> +    return 0;
> +}
> +
>  int arch_livepatch_quiesce(void)
>  {
>      mfn_t text_mfn;
> diff --git a/xen/arch/x86/livepatch.c b/xen/arch/x86/livepatch.c
> index c82cf53b9e..0f129fa6b2 100644
> --- a/xen/arch/x86/livepatch.c
> +++ b/xen/arch/x86/livepatch.c
> @@ -14,6 +14,45 @@
>  #include <asm/nmi.h>
>  #include <asm/livepatch.h>
>  
> +static bool has_active_waitqueue(const struct vm_event_domain *ved)
> +{
> +    /* ved may be xzalloc()'d without INIT_LIST_HEAD() yet. */
> +    return (ved && !list_head_is_null(&ved->wq.list) &&
> +            !list_empty(&ved->wq.list));
> +}
> +
> +/*
> + * x86's implementation of waitqueue violates the livepatching safey principle
> + * of having unwound every CPUs stack before modifying live content.
> + *
> + * Search through every domain and check that no vCPUs have an active
> + * waitqueue.
> + */
> +int arch_livepatch_safety_check(void);
> +{
> +    struct domain *d;
> +
> +    for_each_domain ( d )
> +    {
> +#ifdef CONFIG_MEM_SHARING
> +        if ( has_active_waitqueue(d->vm_event_share) )
> +            goto fail;
> +#endif
> +#ifdef CONFIG_MEM_PAGING
> +        if ( has_active_waitqueue(d->vm_event_paging) )
> +            goto fail;
> +#endif
> +        if ( has_active_waitqueue(d->vm_event_monitor) )
> +            goto fail;
> +    }
> +
> +    return 0;
> +
> + fail:
> +    printk(XENLOG_ERR LIVEPATCH "%pd found with active waitqueue\n", d);
> +    return -EBUSY;
> +}
> +
>  int arch_livepatch_quiesce(void)
>  {
>      /* Disable WP to allow changes to read-only pages. */
> diff --git a/xen/common/livepatch.c b/xen/common/livepatch.c
> index 962647616a..27ee5bdeb7 100644
> --- a/xen/common/livepatch.c
> +++ b/xen/common/livepatch.c
> @@ -1060,6 +1060,13 @@ static int apply_payload(struct payload *data)
>      unsigned int i;
>      int rc;
>  
> +    rc = apply_safety_checks();
> +    if ( rc )
> +    {
> +        printk(XENLOG_ERR LIVEPATCH "%s: Safety checks failed\n", data->name);
> +        return rc;
> +    }
> +
>      printk(XENLOG_INFO LIVEPATCH "%s: Applying %u functions\n",
>              data->name, data->nfuncs);
>  
> diff --git a/xen/include/xen/livepatch.h b/xen/include/xen/livepatch.h
> index 1b1817ca0d..69ede75d20 100644
> --- a/xen/include/xen/livepatch.h
> +++ b/xen/include/xen/livepatch.h
> @@ -104,6 +104,7 @@ static inline int livepatch_verify_distance(const struct livepatch_func *func)
>   * These functions are called around the critical region patching live code,
>   * for an architecture to take make appropratie global state adjustments.
>   */
> +int arch_livepatch_safety_check(void);
>  int arch_livepatch_quiesce(void);
>  void arch_livepatch_revive(void);
>  
> -- 
> 2.11.0
> 

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

  parent reply	other threads:[~2019-11-06 14:26 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-05 19:43 [Xen-devel] [PATCH for-4.13 0/2] xen/livepatch: Safety fixes Andrew Cooper
2019-11-05 19:43 ` [Xen-devel] [PATCH 1/2] xen/livepatch: Add a return value to load hooks Andrew Cooper
2019-11-06 14:20   ` Konrad Rzeszutek Wilk
2019-11-06 14:35   ` Jan Beulich
2019-11-08 10:21   ` Ross Lagerwall
2019-11-05 19:43 ` [Xen-devel] [PATCH 2/2] x86/livepatch: Prevent patching with active waitqueues Andrew Cooper
2019-11-05 19:49   ` [Xen-devel] [PATCH v1.5] " Andrew Cooper
2019-11-22 10:13     ` Jürgen Groß
2019-11-23  3:23     ` Sarah Newman
2019-11-23  4:48     ` Sarah Newman
2019-11-06 14:25   ` Konrad Rzeszutek Wilk [this message]
2019-11-08 10:18   ` [Xen-devel] [PATCH 2/2] " Ross Lagerwall

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191106142513.GB5520@localhost.localdomain \
    --to=konrad.wilk@oracle.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=jgross@suse.com \
    --cc=ross.lagerwall@citrix.com \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.