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

[Xen-changelog] [xen stable-4.2] ocaml/xenctrl: Fix stub_xc_readconsolering()



commit e1395c154c2ebcc218adb5b8999f74620461dfb4
Author:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Fri Jan 30 14:11:14 2015 +0000
Commit:     Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
CommitDate: Wed Aug 12 11:59:39 2015 +0100

    ocaml/xenctrl: Fix stub_xc_readconsolering()
    
    The Ocaml stub to retrieve the hypervisor console ring had a few problems.
    
     * A single 32k buffer would truncate a large console ring.
     * The buffer was static and not under the protection of the Ocaml GC lock 
so
       could be clobbered by concurrent accesses.
     * Embedded NUL characters would cause caml_copy_string() (which is strlen()
       based) to truncate the buffer.
    
    The function is rewritten from scratch, using the same algorithm as the 
python
    stubs, but uses the protection of the Ocaml GC lock to maintain a static
    running total of the ring size, to avoid redundant realloc()ing in future
    calls.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    CC: Dave Scott <dave.scott@xxxxxxxxxxxxx>
    CC: Ian Campbell <Ian.Campbell@xxxxxxxxxx>
    CC: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
    CC: Wei Liu <wei.liu2@xxxxxxxxxx>
    Acked-by: David Scott <dave.scott@xxxxxxxxxx>
    Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
    (cherry picked from commit 1a010ca99e9b04c1cfbd0ee718aa22d5ebd530ab)
    (cherry picked from commit cfc4c43be14e60608ed0b8173365c737950afe41)
    (cherry picked from commit c669c244246a7e45cedb03a30d59656c95d09719)
    (cherry picked from commit 04f8006b66fd9f351467ad0e9c77a0a14741c6e4)
---
 tools/ocaml/libs/xc/xenctrl_stubs.c |   59 +++++++++++++++++++++++++++++------
 1 files changed, 49 insertions(+), 10 deletions(-)

diff --git a/tools/ocaml/libs/xc/xenctrl_stubs.c 
b/tools/ocaml/libs/xc/xenctrl_stubs.c
index 3c1bc0e..39ebbd3 100644
--- a/tools/ocaml/libs/xc/xenctrl_stubs.c
+++ b/tools/ocaml/libs/xc/xenctrl_stubs.c
@@ -526,26 +526,65 @@ CAMLprim value stub_xc_evtchn_reset(value xch, value 
domid)
 }
 
 
-#define RING_SIZE 32768
-static char ring[RING_SIZE];
-
 CAMLprim value stub_xc_readconsolering(value xch)
 {
-       unsigned int size = RING_SIZE - 1;
-       char *ring_ptr = ring;
-       int retval;
+       /* Safe to use outside of blocking sections because of Ocaml GC lock. */
+       static unsigned int conring_size = 16384 + 1;
+
+       unsigned int count = conring_size, size = count, index = 0;
+       char *str = NULL, *ptr;
+       int ret;
 
        CAMLparam1(xch);
+       CAMLlocal1(ring);
 
+       str = malloc(size);
+       if (!str)
+               caml_raise_out_of_memory();
+
+       /* Hopefully our conring_size guess is sufficient */
        caml_enter_blocking_section();
-       retval = xc_readconsolering(_H(xch), ring_ptr, &size, 0, 0, NULL);
+       ret = xc_readconsolering(_H(xch), str, &count, 0, 0, &index);
        caml_leave_blocking_section();
 
-       if (retval)
+       if (ret < 0) {
+               free(str);
                failwith_xc(_H(xch));
+       }
+
+       while (count == size && ret >= 0) {
+               size += count - 1;
+               if (size < count)
+                       break;
+
+               ptr = realloc(str, size);
+               if (!ptr)
+                       break;
+
+               str = ptr + count;
+               count = size - count;
+
+               caml_enter_blocking_section();
+               ret = xc_readconsolering(_H(xch), str, &count, 0, 1, &index);
+               caml_leave_blocking_section();
+
+               count += str - ptr;
+               str = ptr;
+       }
+
+       /*
+        * If we didn't break because of an overflow with size, and we have
+        * needed to realloc() ourself more space, update our tracking of the
+        * real console ring size.
+        */
+       if (size > conring_size)
+               conring_size = size;
+
+       ring = caml_alloc_string(count);
+       memcpy(String_val(ring), str, count);
+       free(str);
 
-       ring[size] = '\0';
-       CAMLreturn(caml_copy_string(ring));
+       CAMLreturn(ring);
 }
 
 CAMLprim value stub_xc_send_debug_keys(value xch, value keys)
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.2

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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