|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] ocaml/xenctrl: Fix stub_xc_readconsolering()
> On 30 Jan 2015, at 14:11, Andrew Cooper <andrew.cooper3@xxxxxxxxxx> wrote:
>
> 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.
>
As far as the OCaml FFI goes, this looks fine to me. I canât spot any problems
with the more regular C parts either, although someone who is more used to
spotting bugs in C code should probably take a look.
Acked-by: David Scott <dave.scott@xxxxxxxxxx>
Dave
> 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>
> ---
> tools/ocaml/libs/xc/xenctrl_stubs.c | 59 +++++++++++++++++++++++++++++------
> 1 file changed, 49 insertions(+), 10 deletions(-)
>
> diff --git a/tools/ocaml/libs/xc/xenctrl_stubs.c
> b/tools/ocaml/libs/xc/xenctrl_stubs.c
> index 92d064f..0340c64 100644
> --- a/tools/ocaml/libs/xc/xenctrl_stubs.c
> +++ b/tools/ocaml/libs/xc/xenctrl_stubs.c
> @@ -529,26 +529,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)
> --
> 1.7.10.4
>
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |