|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [XEN PATCH v1] libxl: Fix nul-termination of the return value of libxl_xen_console_read_line()
On Fri, Aug 23, 2024 at 10:34:05AM GMT, Andrew Cooper wrote:
> On 22/08/2024 2:13 pm, Javi Merino wrote:
> > When built with ASAN, "xl dmesg" crashes in the "printf("%s", line)"
> > call in main_dmesg(). ASAN reports a heap buffer overflow: an
> > off-by-one access to cr->buffer.
> >
> > The readconsole sysctl copies up to count characters into the buffer,
> > but it does not add a null character at the end. Despite the
> > documentation of libxl_xen_console_read_line(), line_r is not
> > nul-terminated if 16384 characters were copied to the buffer.
> >
> > Fix this by making count one less that the size of the allocated
> > buffer so that the last byte is always null.
> >
> > Reported-by: Edwin Török <edwin.torok@xxxxxxxxx>
> > Signed-off-by: Javi Merino <javi.merino@xxxxxxxxx>
> > ---
> > tools/libs/light/libxl_console.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/tools/libs/light/libxl_console.c
> > b/tools/libs/light/libxl_console.c
> > index a563c9d3c7f9..fa28e2139453 100644
> > --- a/tools/libs/light/libxl_console.c
> > +++ b/tools/libs/light/libxl_console.c
> > @@ -779,7 +779,7 @@ libxl_xen_console_reader *
> > cr = libxl__zalloc(NOGC, sizeof(libxl_xen_console_reader));
> > cr->buffer = libxl__zalloc(NOGC, size);
> > cr->size = size;
> > - cr->count = size;
> > + cr->count = size - 1;
> > cr->clear = clear;
> > cr->incremental = 1;
> >
>
> This looks like it will fix the ASAN issue, but I think a better fix
> would be:
>
> - printf("%s", line);
> + printf("%.*s", cr->count, line);
>
> because otherwise there's a world of sharp corners once Xen has wrapped
> the buffer for the first time.
>
>
> Which brings us a lot of other WTFs in this code...
>
> First, libxl_console.c describes it's functionality in terms of lines,
> and line_reader() in the API. Yet it's not lines, it's a 16k buffer
> with generally multi-line content. It's too late to fix the naming, but
> we could at least rewrite the comments not to be blatant lies.
>
>
> Just out of context above the hunk is:
>
> unsigned int size = 16384;
>
> which isn't accurate. The size of Xen's console ring can be changed at
> compile time (like XenServer does), and/or by command line variable.
>
> Because the dmesg ring is never full (it just keeps producing and
> overwriting tail data), it's impossible to get a clean copy except in a
> single hypercall; the incremental/offset parameters are an illusion, and
> do not function correctly if a new printk() has occurred between
> adjacent hypercalls.
>
> And that is why setting count to size - 1 probably isn't wise. It means
> that, even in the ideal case where Xen's ringbuffer is 16k, you've still
> got to make 2 hypercalls to get the content.
You are right, having to do 2 hypercalls in the ideal case is not
good. I'm going to get rid of cr->count, and make
libxl_xen_console_read_line() honour its documentation of returning a
nul-terminated string. I'll just make the allocation one char bigger,
which was the fix I originally had.
Cheers,
Javi
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |