From mboxrd@z Thu Jan 1 00:00:00 1970 From: Andrew Cooper Subject: Re: [PATCH v1 3/4] XENVER_build_id: Provide ld-embedded build-ids Date: Fri, 9 Oct 2015 13:47:58 +0100 Message-ID: <5617B77E.3090004@citrix.com> References: <1444359390-14153-1-git-send-email-konrad.wilk@oracle.com> <1444359390-14153-4-git-send-email-konrad.wilk@oracle.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="===============2607968466642814576==" Return-path: Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1ZkX5i-0006al-E5 for xen-devel@lists.xenproject.org; Fri, 09 Oct 2015 12:48:06 +0000 In-Reply-To: <1444359390-14153-4-git-send-email-konrad.wilk@oracle.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Konrad Rzeszutek Wilk , ian.campbell@citrix.com, xen-devel@lists.xenproject.org, wei.liu2@citrix.com, ian.jackson@eu.citrix.com, jbeulich@suse.com, mpohlack@amazon.de, dgdegra@tycho.nsa.gov List-Id: xen-devel@lists.xenproject.org --===============2607968466642814576== Content-Type: multipart/alternative; boundary="------------030806010502010308000004" --------------030806010502010308000004 Content-Type: text/plain; charset="windows-1252" Content-Transfer-Encoding: 7bit On 09/10/15 03:56, Konrad Rzeszutek Wilk wrote: > @@ -367,6 +368,35 @@ DO(xen_version)(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg, > if ( copy_to_guest(arg, saved_cmdline, ARRAY_SIZE(saved_cmdline)) ) > return -EFAULT; > return 0; > + > + case XENVER_build_id: > + { > + int rc; > + char *p = NULL; > + unsigned int sz = 0; > + > + if ( guest_handle_is_null(arg) ) > + return -EINVAL; A NULL guest handle should return size, in the same way that we have size queries with other hypercalls. In the future, build-id will probably extend to sha256 and get//// longer as a result. > + > + if ( len == 0 ) > + return -EINVAL; This check is redundant with the "sz > len" check below. > + > + if ( !guest_handle_okay(arg, len) ) > + return -EINVAL; This check is performed by copy_to_guest() below. > + > + rc = xen_build_id(&p, &sz); > + if ( rc ) > + return rc; > + > + if ( sz > len ) > + return -ENOMEM; ENOBUFS > + > + if ( copy_to_guest(arg, p, sz) ) > + return -EFAULT; > + > + return sz; > + } > + > } > > return -ENOSYS; > diff --git a/xen/common/version.c b/xen/common/version.c > index b152e27..26eeadf 100644 > --- a/xen/common/version.c > +++ b/xen/common/version.c > @@ -1,5 +1,9 @@ > #include > #include > +#include > +#include > +#include > +#include > > const char *xen_compile_date(void) > { > @@ -55,3 +59,36 @@ const char *xen_banner(void) > { > return XEN_BANNER; > } > + > +#ifdef CONFIG_ARM > +int xen_build_id(char **p, unsigned int *len) > +{ > + return -ENODATA; > +} > +#else > +#define NT_GNU_BUILD_ID 3 > + > +extern const Elf_Note __note_gnu_build_id_start; /* Defined in linker script. */ extern const Elf_Note __note_gnu_build_id_start[], __note_gnu_build_id_end[]; > +extern const char __note_gnu_build_id_end[]; > +int xen_build_id(char **p, unsigned int *len) > +{ > + const Elf_Note *n = &__note_gnu_build_id_start; const Elf_Note *n = __note_gnu_build_id_start; > + > + /* Something is wrong. */ > + if ( __note_gnu_build_id_end <= (char *)&__note_gnu_build_id_start ) Need to check for a full Note header as well. if ( &n[1] > __note_gnu_build_id_end ) > + return -ENODATA; > + > + /* Check if we really have a build-id. */ > + if ( NT_GNU_BUILD_ID != n->type ) > + return -ENODATA; > + > + /* Sanity check, name should be "GNU" for ld-generated build-id. */ > + if ( strncmp(ELFNOTE_NAME(n), "GNU", n->namesz) != 0 ) > + return -ENODATA; > + > + *len = n->descsz; > + *p = ELFNOTE_DESC(n); This information could be cached in a couple of static variables, so the sanity checks are only performed once. > + > + return 0; > +} > +#endif > diff --git a/xen/include/public/version.h b/xen/include/public/version.h > index 44f26b0..e575d6b 100644 > --- a/xen/include/public/version.h > +++ b/xen/include/public/version.h > @@ -30,7 +30,8 @@ > > #include "xen.h" > > -/* NB. All ops return zero on success, except XENVER_{version,pagesize} */ > +/* NB. All ops return zero on success, except > + * XENVER_{version,pagesize, build_id} */ > > /* arg == NULL; returns major:minor (16:16). */ > #define XENVER_version 0 > @@ -83,6 +84,12 @@ typedef struct xen_feature_info xen_feature_info_t; > #define XENVER_commandline 9 > typedef char xen_commandline_t[1024]; > > +#define XENVER_build_id 10 > +/* > + * arg1 == pointer to char array, arg2 == size of char array. > + * Return value is the actual size. Return value is the number of bytes written, or -ve error. ~Andrew --------------030806010502010308000004 Content-Type: text/html; charset="windows-1252" Content-Length: 5812 Content-Transfer-Encoding: quoted-printable
On 09/10/15 03:56, Konrad Rzeszutek Wilk wrote:
@@ -367,6 +368,35 @@ DO(xen_version)(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg,
         if ( copy_to_guest(arg, saved_cmdline, ARRAY_SIZE(saved_cmdline)) )
             return -EFAULT;
         return 0;
+
+    case XENVER_build_id:
+    {
+        int rc;
+        char *p =3D NULL;
+        unsigned int sz =3D 0;
+
+        if ( guest_handle_is_null(arg) )
+            return -EINVAL;

A NULL guest handle should return size, in the same way that we have size queries with other hypercalls.=A0 In the future, build-id will probably extend to sha256 and get longer as a result.

+
+        if ( len =3D=3D 0 )
+            return -EINVAL;

This check is redundant with the "sz > len" check below.

+
+        if ( !guest_handle_okay(arg, len) )
+            return -EINVAL;

This check is performed by copy_to_guest() below.

+
+        rc =3D xen_build_id(&p, &sz);
+        if ( rc )
+            return rc;
+
+        if ( sz > len )
+            return -ENOMEM;

ENOBUFS

+
+        if ( copy_to_guest(arg, p, sz) )
+            return -EFAULT;
+
+        return sz;
+    }
+
     }
 
     return -ENOSYS;
diff --git a/xen/common/version.c b/xen/common/version.c
index b152e27..26eeadf 100644
--- a/xen/common/version.c
+++ b/xen/common/version.c
@@ -1,5 +1,9 @@
 #include <xen/compile.h>
 #include <xen/version.h>
+#include <xen/types.h>
+#include <xen/string.h>
+#include <xen/elf.h>
+#include <xen/errno.h>
 
 const char *xen_compile_date(void)
 {
@@ -55,3 +59,36 @@ const char *xen_banner(void)
 {
     return XEN_BANNER;
 }
+
+#ifdef CONFIG_ARM
+int xen_build_id(char **p, unsigned int *len)
+{
+    return -ENODATA;
+}
+#else
+#define NT_GNU_BUILD_ID 3
+
+extern const Elf_Note __note_gnu_build_id_start;  /* Defined in linker script. */

extern const Elf_Note __note_gnu_build_id_start[], __note_gnu_build_id_end[];

+extern const char __note_gnu_build_id_end[];
+int xen_build_id(char **p, unsigned int *len)
+{
+    const Elf_Note *n =3D &__note_gnu_build_id_start;

const Elf_Note *n =3D __note_gnu_build_id_start;

+
+    /* Something is wrong. */
+    if ( __note_gnu_build_id_end <=3D (char *)&__note_gnu_build_id_start )

Need to check for a full Note header as well.

if ( &n[1] > __note_gnu_build_id_end )

+        return -ENODATA;
+
+    /* Check if we really have a build-id. */
+    if ( NT_GNU_BUILD_ID !=3D n->type )
+        return -ENODATA;
+
+    /* Sanity check, name should be "GNU" for ld-generated build-id. */
+    if ( strncmp(ELFNOTE_NAME(n), "GNU", n->namesz) !=3D 0 )
+        return -ENODATA;
+
+    *len =3D n->descsz;
+    *p =3D ELFNOTE_DESC(n);

This information could be cached in a couple of static variables, so the sanity checks are only performed once.

+
+    return 0;
+}
+#endif
diff --git a/xen/include/public/version.h b/xen/include/public/version.h
index 44f26b0..e575d6b 100644
--- a/xen/include/public/version.h
+++ b/xen/include/public/version.h
@@ -30,7 +30,8 @@
 
 #include "xen.h"
 
-/* NB. All ops return zero on success, except XENVER_{version,pagesize} */
+/* NB. All ops return zero on success, except
+ * XENVER_{version,pagesize, build_id} */
 
 /* arg =3D=3D NULL; returns major:minor (16:16). */
 #define XENVER_version      0
@@ -83,6 +84,12 @@ typedef struct xen_feature_info xen_feature_info_t;
 #define XENVER_commandline 9
 typedef char xen_commandline_t[1024];
 
+#define XENVER_build_id 10
+/*
+ * arg1 =3D=3D pointer to char array, arg2 =3D=3D size of char array.
+ * Return value is the actual size.

Return value is the number of bytes written, or -ve error.

~Andrew
--------------030806010502010308000004-- --===============2607968466642814576== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel --===============2607968466642814576==--