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

[Xen-changelog] [xen master] libxc: don't fail domain creation when unpacking initrd fails



commit d0115f96ea633fd6d668f2c067785912c0ad4c00
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Tue Feb 6 17:29:33 2018 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Tue Feb 6 17:29:33 2018 +0100

    libxc: don't fail domain creation when unpacking initrd fails
    
    At least Linux kernels have been able to work with gzip-ed initrd for
    quite some time; initrd compressed with other methods aren't even being
    attempted to unpack. Furthermore the unzip-ing routine used here isn't
    capable of dealing with various forms of concatenated files, each of
    which was gzip-ed separately (it is this particular case which has been
    the source of observed VM creation failures).
    
    Hence, if unpacking fails, simply hand the compressed blob to the guest
    as is.
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Acked-by: Wei Liu <wei.liu2@xxxxxxxxxx>
---
 tools/libxc/include/xc_dom.h |  1 -
 tools/libxc/xc_dom_core.c    | 51 +++++++++++++++++++++++---------------------
 2 files changed, 27 insertions(+), 25 deletions(-)

diff --git a/tools/libxc/include/xc_dom.h b/tools/libxc/include/xc_dom.h
index 08be8a8..491cad8 100644
--- a/tools/libxc/include/xc_dom.h
+++ b/tools/libxc/include/xc_dom.h
@@ -298,7 +298,6 @@ int xc_dom_mem_init(struct xc_dom_image *dom, unsigned int 
mem_mb);
 int xc_dom_kernel_check_size(struct xc_dom_image *dom, size_t sz);
 int xc_dom_kernel_max_size(struct xc_dom_image *dom, size_t sz);
 
-int xc_dom_module_check_size(struct xc_dom_image *dom, size_t sz);
 int xc_dom_module_max_size(struct xc_dom_image *dom, size_t sz);
 
 int xc_dom_devicetree_max_size(struct xc_dom_image *dom, size_t sz);
diff --git a/tools/libxc/xc_dom_core.c b/tools/libxc/xc_dom_core.c
index 3e65aff..96e71dd 100644
--- a/tools/libxc/xc_dom_core.c
+++ b/tools/libxc/xc_dom_core.c
@@ -314,22 +314,6 @@ int xc_dom_kernel_check_size(struct xc_dom_image *dom, 
size_t sz)
     return 0;
 }
 
-int xc_dom_module_check_size(struct xc_dom_image *dom, size_t sz)
-{
-    /* No limit */
-    if ( !dom->max_module_size )
-        return 0;
-
-    if ( sz > dom->max_module_size )
-    {
-        xc_dom_panic(dom->xch, XC_INVALID_KERNEL,
-                     "module image too large");
-        return 1;
-    }
-
-    return 0;
-}
-
 /* ------------------------------------------------------------------------ */
 /* read files, copy memory blocks, with transparent gunzip                  */
 
@@ -1026,16 +1010,28 @@ static int xc_dom_build_module(struct xc_dom_image 
*dom, unsigned int mod)
     char name[10];
 
     if ( !dom->modules[mod].seg.vstart )
-    {
         unziplen = xc_dom_check_gzip(dom->xch,
                                      dom->modules[mod].blob, 
dom->modules[mod].size);
-        if ( xc_dom_module_check_size(dom, unziplen) != 0 )
-            unziplen = 0;
-    }
     else
         unziplen = 0;
 
-    modulelen = unziplen ? unziplen : dom->modules[mod].size;
+    modulelen = max(unziplen, dom->modules[mod].size);
+    if ( dom->max_module_size )
+    {
+        if ( unziplen && modulelen > dom->max_module_size )
+        {
+            modulelen = min(unziplen, dom->modules[mod].size);
+            if ( unziplen > modulelen )
+                unziplen = 0;
+        }
+        if ( modulelen > dom->max_module_size )
+        {
+            xc_dom_panic(dom->xch, XC_INVALID_KERNEL,
+                         "module %u image too large", mod);
+            goto err;
+        }
+    }
+
     snprintf(name, sizeof(name), "module%u", mod);
     if ( xc_dom_alloc_segment(dom, &dom->modules[mod].seg, name,
                               dom->modules[mod].seg.vstart, modulelen) != 0 )
@@ -1050,11 +1046,18 @@ static int xc_dom_build_module(struct xc_dom_image 
*dom, unsigned int mod)
     if ( unziplen )
     {
         if ( xc_dom_do_gunzip(dom->xch, dom->modules[mod].blob, 
dom->modules[mod].size,
-                              modulemap, modulelen) == -1 )
+                              modulemap, unziplen) != -1 )
+            return 0;
+        if ( dom->modules[mod].size > modulelen )
             goto err;
     }
-    else
-        memcpy(modulemap, dom->modules[mod].blob, dom->modules[mod].size);
+
+    /* Fall back to handing over the raw blob. */
+    memcpy(modulemap, dom->modules[mod].blob, dom->modules[mod].size);
+    /* If an unzip attempt was made, the buffer may no longer be all zero. */
+    if ( unziplen > dom->modules[mod].size )
+        memset(modulemap + dom->modules[mod].size, 0,
+               unziplen - dom->modules[mod].size);
 
     return 0;
 
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

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