[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v3 02/10] xen/version: Introduce non-truncating deterministically-signed XENVER_* subops


  • To: Stefano Stabellini <sstabellini@xxxxxxxxxx>
  • From: Jan Beulich <jbeulich@xxxxxxxx>
  • Date: Fri, 1 Dec 2023 08:04:41 +0100
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=suse.com; dmarc=pass action=none header.from=suse.com; dkim=pass header.d=suse.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ntrgcbQQr8qmSnAY61BdbyT006mCPiG2PgnYHyPvRrg=; b=ZZQnoHodgWVYBR+4QxLWlEEm2yTqPp3j3VxqdIWKxfBViUt5zKpAeQoSN7RUbxbrzPXBrNpB9+h5ZZ3yg5YMr5Ncy96EBhP+yljocs7WzGwpeyI1U0nIeSzn4z5X+dRXBFJJHy1hpDxIGZvinzFk1B9/TxRIIXtpgG9GX93O+6ZNEXOzmL0v+ryIyJhgKgm96ThUpwbNWFfYKEVamxEAjBUGpptXx0KKGqGbPCTWXKWx/kbQh0mZQMXWH5tpt0MXnx2tOLUt9K9wmya9/ws6mnioQKrN6mkF1sb/w9hzg7+6wdYpxyEs2okAnRp2PHL9mqfpTomu4PdygU0OcavnFA==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=dWpRE0mhI7d5uMWIdu5viJPHSD428m/5DH82VTstHI74VRvCBi+TDFuC6AjsNX2gyJbmxWe+FbGZrEqGKk+qoRDVGSWg9ZCe2awA2it5nroBFLV2dDzw1al/swZY1VvOkmnZwk0BzhRqV7R+zgtYYqtBwz3lDs69N69NiGRZYhUuXkb1ab6X97F4/R2RczpYkGYDIicSEgHSHOgGWKtKey9svc+z0RsEjA+Zue6S4mU42JSw8u3I+tPb7RwznQOQpXLkZsNaqo8n5Xk6NF5H7emFufRVF/ACTCMdk2mn4DZxNb32RQ2kJLceJ+ToBTmO+1/QH3sihM/Lv1y1F2mPJQ==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=suse.com;
  • Autocrypt: addr=jbeulich@xxxxxxxx; keydata= xsDiBFk3nEQRBADAEaSw6zC/EJkiwGPXbWtPxl2xCdSoeepS07jW8UgcHNurfHvUzogEq5xk hu507c3BarVjyWCJOylMNR98Yd8VqD9UfmX0Hb8/BrA+Hl6/DB/eqGptrf4BSRwcZQM32aZK 7Pj2XbGWIUrZrd70x1eAP9QE3P79Y2oLrsCgbZJfEwCgvz9JjGmQqQkRiTVzlZVCJYcyGGsD /0tbFCzD2h20ahe8rC1gbb3K3qk+LpBtvjBu1RY9drYk0NymiGbJWZgab6t1jM7sk2vuf0Py O9Hf9XBmK0uE9IgMaiCpc32XV9oASz6UJebwkX+zF2jG5I1BfnO9g7KlotcA/v5ClMjgo6Gl MDY4HxoSRu3i1cqqSDtVlt+AOVBJBACrZcnHAUSuCXBPy0jOlBhxPqRWv6ND4c9PH1xjQ3NP nxJuMBS8rnNg22uyfAgmBKNLpLgAGVRMZGaGoJObGf72s6TeIqKJo/LtggAS9qAUiuKVnygo 3wjfkS9A3DRO+SpU7JqWdsveeIQyeyEJ/8PTowmSQLakF+3fote9ybzd880fSmFuIEJldWxp Y2ggPGpiZXVsaWNoQHN1c2UuY29tPsJgBBMRAgAgBQJZN5xEAhsDBgsJCAcDAgQVAggDBBYC AwECHgECF4AACgkQoDSui/t3IH4J+wCfQ5jHdEjCRHj23O/5ttg9r9OIruwAn3103WUITZee e7Sbg12UgcQ5lv7SzsFNBFk3nEQQCACCuTjCjFOUdi5Nm244F+78kLghRcin/awv+IrTcIWF hUpSs1Y91iQQ7KItirz5uwCPlwejSJDQJLIS+QtJHaXDXeV6NI0Uef1hP20+y8qydDiVkv6l IreXjTb7DvksRgJNvCkWtYnlS3mYvQ9NzS9PhyALWbXnH6sIJd2O9lKS1Mrfq+y0IXCP10eS FFGg+Av3IQeFatkJAyju0PPthyTqxSI4lZYuJVPknzgaeuJv/2NccrPvmeDg6Coe7ZIeQ8Yj t0ARxu2xytAkkLCel1Lz1WLmwLstV30g80nkgZf/wr+/BXJW/oIvRlonUkxv+IbBM3dX2OV8 AmRv1ySWPTP7AAMFB/9PQK/VtlNUJvg8GXj9ootzrteGfVZVVT4XBJkfwBcpC/XcPzldjv+3 HYudvpdNK3lLujXeA5fLOH+Z/G9WBc5pFVSMocI71I8bT8lIAzreg0WvkWg5V2WZsUMlnDL9 mpwIGFhlbM3gfDMs7MPMu8YQRFVdUvtSpaAs8OFfGQ0ia3LGZcjA6Ik2+xcqscEJzNH+qh8V m5jjp28yZgaqTaRbg3M/+MTbMpicpZuqF4rnB0AQD12/3BNWDR6bmh+EkYSMcEIpQmBM51qM EKYTQGybRCjpnKHGOxG0rfFY1085mBDZCH5Kx0cl0HVJuQKC+dV2ZY5AqjcKwAxpE75MLFkr wkkEGBECAAkFAlk3nEQCGwwACgkQoDSui/t3IH7nnwCfcJWUDUFKdCsBH/E5d+0ZnMQi+G0A nAuWpQkjM1ASeQwSHEeAWPgskBQL
  • Cc: Xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxxx>, Jason Andryuk <jandryuk@xxxxxxxxx>, George Dunlap <George.Dunlap@xxxxxxxxxxxxx>, Wei Liu <wl@xxxxxxx>, Julien Grall <julien@xxxxxxx>, Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>, Daniel Smith <dpsmith@xxxxxxxxxxxxxxxxxxxx>, Henry Wang <Henry.Wang@xxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
  • Delivery-date: Fri, 01 Dec 2023 07:04:53 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On 30.11.2023 23:30, Stefano Stabellini wrote:
> Hi everyone following this thread,
> 
> please see:
> https://marc.info/?l=xen-devel&m=170135718323946
> https://cryptpad.fr/form/#/2/form/view/7ByH95Vd7KiDOvN4wjV5iUGlMuZbkVdwk7cYpZdluWo/
> 
> For a vote on the usage of the word "broken"

So I did vote before becoming aware of this context. I would have voted
differently if I had known that this _alone_ is the context. Yet then
I'm also not going to change my vote, because as written _there_ it is
intended to be more general. If the wording of the text describing what
to vote on changed, things would be different.

Jan

> On Tue, 15 Aug 2023, Andrew Cooper wrote:
>> Recently in XenServer, we have encountered problems caused by both
>> XENVER_extraversion and XENVER_commandline having fixed bounds.
>>
>> More than just the invariant size, the APIs/ABIs also broken by typedef-ing 
>> an
>> array, and using an unqualified 'char' which has implementation-specific
>> signed-ness.
>>
>> Provide brand new ops, which are capable of expressing variable length
>> strings, and mark the older ops as broken.
>>
>> This fixes all issues around XENVER_extraversion being longer than 15 chars.
>> Further work beyond just this API is needed to remove other assumptions about
>> XENVER_commandline being 1023 chars long.
>>
>> Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
>> Reviewed-by: Jason Andryuk <jandryuk@xxxxxxxxx>
>> ---
>> CC: George Dunlap <George.Dunlap@xxxxxxxxxxxxx>
>> CC: Jan Beulich <JBeulich@xxxxxxxx>
>> CC: Stefano Stabellini <sstabellini@xxxxxxxxxx>
>> CC: Wei Liu <wl@xxxxxxx>
>> CC: Julien Grall <julien@xxxxxxx>
>> CC: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
>> CC: Daniel Smith <dpsmith@xxxxxxxxxxxxxxxxxxxx>
>> CC: Jason Andryuk <jandryuk@xxxxxxxxx>
>> CC: Henry Wang <Henry.Wang@xxxxxxx>
>>
>> v3:
>>  * Modify dummy.h's xsm_xen_version() in the same way as flask.
>> v2:
>>  * Remove xen_capabilities_info_t from the stack now that arch_get_xen_caps()
>>    has gone.
>>  * Use an arbitrary limit check much lower than INT_MAX.
>>  * Use "buf" rather than "string" terminology.
>>  * Expand the API comment.
>>
>> Tested by forcing XENVER_extraversion to be 20 chars long, and confirming 
>> that
>> an untruncated version can be obtained.
>> ---
>>  xen/common/kernel.c          | 62 +++++++++++++++++++++++++++++++++++
>>  xen/include/public/version.h | 63 ++++++++++++++++++++++++++++++++++--
>>  xen/include/xlat.lst         |  1 +
>>  xen/include/xsm/dummy.h      |  3 ++
>>  xen/xsm/flask/hooks.c        |  4 +++
>>  5 files changed, 131 insertions(+), 2 deletions(-)
>>
>> diff --git a/xen/common/kernel.c b/xen/common/kernel.c
>> index f822480a8ef3..79c008c7ee5f 100644
>> --- a/xen/common/kernel.c
>> +++ b/xen/common/kernel.c
>> @@ -24,6 +24,7 @@
>>  CHECK_build_id;
>>  CHECK_compile_info;
>>  CHECK_feature_info;
>> +CHECK_varbuf;
>>  #endif
>>  
>>  enum system_state system_state = SYS_STATE_early_boot;
>> @@ -498,6 +499,59 @@ static int __init cf_check param_init(void)
>>  __initcall(param_init);
>>  #endif
>>  
>> +static long xenver_varbuf_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
>> +{
>> +    struct xen_varbuf user_str;
>> +    const char *str = NULL;
>> +    size_t sz;
>> +
>> +    switch ( cmd )
>> +    {
>> +    case XENVER_extraversion2:
>> +        str = xen_extra_version();
>> +        break;
>> +
>> +    case XENVER_changeset2:
>> +        str = xen_changeset();
>> +        break;
>> +
>> +    case XENVER_commandline2:
>> +        str = saved_cmdline;
>> +        break;
>> +
>> +    case XENVER_capabilities2:
>> +        str = xen_cap_info;
>> +        break;
>> +
>> +    default:
>> +        ASSERT_UNREACHABLE();
>> +        return -ENODATA;
>> +    }
>> +
>> +    sz = strlen(str);
>> +
>> +    if ( sz > KB(64) ) /* Arbitrary limit.  Avoid long-running operations. 
>> */
>> +        return -E2BIG;
>> +
>> +    if ( guest_handle_is_null(arg) ) /* Length request */
>> +        return sz;
>> +
>> +    if ( copy_from_guest(&user_str, arg, 1) )
>> +        return -EFAULT;
>> +
>> +    if ( user_str.len == 0 )
>> +        return -EINVAL;
>> +
>> +    if ( sz > user_str.len )
>> +        return -ENOBUFS;
>> +
>> +    if ( copy_to_guest_offset(arg, offsetof(struct xen_varbuf, buf),
>> +                              str, sz) )
>> +        return -EFAULT;
>> +
>> +    return sz;
>> +}
>> +
>>  long do_xen_version(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
>>  {
>>      bool_t deny = !!xsm_xen_version(XSM_OTHER, cmd);
>> @@ -711,6 +765,14 @@ long do_xen_version(int cmd, 
>> XEN_GUEST_HANDLE_PARAM(void) arg)
>>  
>>          return sz;
>>      }
>> +
>> +    case XENVER_extraversion2:
>> +    case XENVER_capabilities2:
>> +    case XENVER_changeset2:
>> +    case XENVER_commandline2:
>> +        if ( deny )
>> +            return -EPERM;
>> +        return xenver_varbuf_op(cmd, arg);
>>      }
>>  
>>      return -ENOSYS;
>> diff --git a/xen/include/public/version.h b/xen/include/public/version.h
>> index cbc4ef7a46e6..0dd6bbcb43cc 100644
>> --- a/xen/include/public/version.h
>> +++ b/xen/include/public/version.h
>> @@ -19,12 +19,20 @@
>>  /* arg == NULL; returns major:minor (16:16). */
>>  #define XENVER_version      0
>>  
>> -/* arg == xen_extraversion_t. */
>> +/*
>> + * arg == xen_extraversion_t.
>> + *
>> + * This API/ABI is broken.  Use XENVER_extraversion2 where possible.
>> + */
>>  #define XENVER_extraversion 1
>>  typedef char xen_extraversion_t[16];
>>  #define XEN_EXTRAVERSION_LEN (sizeof(xen_extraversion_t))
>>  
>> -/* arg == xen_compile_info_t. */
>> +/*
>> + * arg == xen_compile_info_t.
>> + *
>> + * This API/ABI is broken and truncates data.
>> + */
>>  #define XENVER_compile_info 2
>>  struct xen_compile_info {
>>      char compiler[64];
>> @@ -34,10 +42,20 @@ struct xen_compile_info {
>>  };
>>  typedef struct xen_compile_info xen_compile_info_t;
>>  
>> +/*
>> + * arg == xen_capabilities_info_t.
>> + *
>> + * This API/ABI is broken.  Use XENVER_capabilities2 where possible.
>> + */
>>  #define XENVER_capabilities 3
>>  typedef char xen_capabilities_info_t[1024];
>>  #define XEN_CAPABILITIES_INFO_LEN (sizeof(xen_capabilities_info_t))
>>  
>> +/*
>> + * arg == xen_changeset_info_t.
>> + *
>> + * This API/ABI is broken.  Use XENVER_changeset2 where possible.
>> + */
>>  #define XENVER_changeset 4
>>  typedef char xen_changeset_info_t[64];
>>  #define XEN_CHANGESET_INFO_LEN (sizeof(xen_changeset_info_t))
>> @@ -95,6 +113,11 @@ typedef struct xen_feature_info xen_feature_info_t;
>>   */
>>  #define XENVER_guest_handle 8
>>  
>> +/*
>> + * arg == xen_commandline_t.
>> + *
>> + * This API/ABI is broken.  Use XENVER_commandline2 where possible.
>> + */
>>  #define XENVER_commandline 9
>>  typedef char xen_commandline_t[1024];
>>  
>> @@ -110,6 +133,42 @@ struct xen_build_id {
>>  };
>>  typedef struct xen_build_id xen_build_id_t;
>>  
>> +/*
>> + * Container for an arbitrary variable length buffer.
>> + */
>> +struct xen_varbuf {
>> +    uint32_t len;                          /* IN:  size of buf[] in bytes. 
>> */
>> +    unsigned char buf[XEN_FLEX_ARRAY_DIM]; /* OUT: requested data.         
>> */
>> +};
>> +typedef struct xen_varbuf xen_varbuf_t;
>> +
>> +/*
>> + * arg == xen_varbuf_t
>> + *
>> + * Equivalent to the original ops, but with a non-truncating API/ABI.
>> + *
>> + * These hypercalls can fail for a number of reasons.  All callers must 
>> handle
>> + * -XEN_xxx return values appropriately.
>> + *
>> + * Passing arg == NULL is a request for size, which will be signalled with a
>> + * non-negative return value.  Note: a return size of 0 may be legitimate 
>> for
>> + * the requested subop.
>> + *
>> + * Otherwise, the input xen_varbuf_t provides the size of the following
>> + * buffer.  Xen will fill the buffer, and return the number of bytes written
>> + * (e.g. if the input buffer was longer than necessary).
>> + *
>> + * Some subops may return binary data.  Some subops may be expected to 
>> return
>> + * textural data.  These are returned without a NUL terminator, and while 
>> the
>> + * contents is expected to be ASCII/UTF-8, Xen makes no guarentees to this
>> + * effect.  e.g. Xen has no control over the formatting used for the command
>> + * line.
>> + */
>> +#define XENVER_extraversion2 11
>> +#define XENVER_capabilities2 12
>> +#define XENVER_changeset2    13
>> +#define XENVER_commandline2  14
>> +
>>  #endif /* __XEN_PUBLIC_VERSION_H__ */
>>  
>>  /*
>> diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst
>> index 9c41948514bf..a61ba85ed0ca 100644
>> --- a/xen/include/xlat.lst
>> +++ b/xen/include/xlat.lst
>> @@ -173,6 +173,7 @@
>>  ?   build_id                        version.h
>>  ?   compile_info                    version.h
>>  ?   feature_info                    version.h
>> +?   varbuf                          version.h
>>  ?   xenoprof_init                   xenoprof.h
>>  ?   xenoprof_passive                xenoprof.h
>>  ?   flask_access                    xsm/flask_op.h
>> diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h
>> index 8671af1ba4d3..a4a920f74e6e 100644
>> --- a/xen/include/xsm/dummy.h
>> +++ b/xen/include/xsm/dummy.h
>> @@ -828,9 +828,12 @@ static XSM_INLINE int cf_check 
>> xsm_xen_version(XSM_DEFAULT_ARG uint32_t op)
>>          block_speculation();
>>          return 0;
>>      case XENVER_extraversion:
>> +    case XENVER_extraversion2:
>>      case XENVER_compile_info:
>>      case XENVER_capabilities:
>> +    case XENVER_capabilities2:
>>      case XENVER_changeset:
>> +    case XENVER_changeset2:
>>      case XENVER_pagesize:
>>      case XENVER_guest_handle:
>>          /* These MUST always be accessible to any guest by default. */
>> diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
>> index 78225f68c15c..a671dcd0322e 100644
>> --- a/xen/xsm/flask/hooks.c
>> +++ b/xen/xsm/flask/hooks.c
>> @@ -1777,15 +1777,18 @@ static int cf_check flask_xen_version(uint32_t op)
>>          /* These sub-ops ignore the permission checks and return data. */
>>          return 0;
>>      case XENVER_extraversion:
>> +    case XENVER_extraversion2:
>>          return avc_has_perm(dsid, SECINITSID_XEN, SECCLASS_VERSION,
>>                              VERSION__XEN_EXTRAVERSION, NULL);
>>      case XENVER_compile_info:
>>          return avc_has_perm(dsid, SECINITSID_XEN, SECCLASS_VERSION,
>>                              VERSION__XEN_COMPILE_INFO, NULL);
>>      case XENVER_capabilities:
>> +    case XENVER_capabilities2:
>>          return avc_has_perm(dsid, SECINITSID_XEN, SECCLASS_VERSION,
>>                              VERSION__XEN_CAPABILITIES, NULL);
>>      case XENVER_changeset:
>> +    case XENVER_changeset2:
>>          return avc_has_perm(dsid, SECINITSID_XEN, SECCLASS_VERSION,
>>                              VERSION__XEN_CHANGESET, NULL);
>>      case XENVER_pagesize:
>> @@ -1795,6 +1798,7 @@ static int cf_check flask_xen_version(uint32_t op)
>>          return avc_has_perm(dsid, SECINITSID_XEN, SECCLASS_VERSION,
>>                              VERSION__XEN_GUEST_HANDLE, NULL);
>>      case XENVER_commandline:
>> +    case XENVER_commandline2:
>>          return avc_has_perm(dsid, SECINITSID_XEN, SECCLASS_VERSION,
>>                              VERSION__XEN_COMMANDLINE, NULL);
>>      case XENVER_build_id:
>> -- 
>> 2.30.2
>>




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.