|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH] livepatch: Pass buffer size to list sysctl
On Wed, May 07, 2025 at 05:38:59PM +0100, Ross Lagerwall wrote:
> From: Kevin Lampis <kevin.lampis@xxxxxxxxx>
>
> The livepatch list sysctl writes metadata into a buffer provided by the
> caller. The caller is expected to allocate an appropriately sized buffer
> but this is racy and may result in Xen writing beyond the end of the
> buffer should the metadata size change.
>
> The name buffer is expected to be an array of elements with size
> XEN_LIVEPATCH_NAME_SIZE to avoid this kind of race but the xen-livepatch
> tool allocates only as many bytes as needed, therefore encountering the
> same potential race condition.
>
> Fix both these issues by requiring the caller to pass in the size of the
> name and metadata buffers and then not writing beyond the allocated
> size.
>
> The sysctl interface version is bumped due to the change in semantics of
> the fields.
>
> Signed-off-by: Kevin Lampis <kevin.lampis@xxxxxxxxx>
> Signed-off-by: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx>
> ---
> tools/libs/ctrl/xc_misc.c | 3 +++
> xen/common/livepatch.c | 22 +++++++++++++++++-----
> xen/include/public/sysctl.h | 12 ++++++++----
> 3 files changed, 28 insertions(+), 9 deletions(-)
>
> diff --git a/tools/libs/ctrl/xc_misc.c b/tools/libs/ctrl/xc_misc.c
> index 6a60216bda03..33e87bac2868 100644
> --- a/tools/libs/ctrl/xc_misc.c
> +++ b/tools/libs/ctrl/xc_misc.c
> @@ -867,6 +867,9 @@ int xc_livepatch_list(xc_interface *xch, const unsigned
> int max,
> set_xen_guest_handle(sysctl.u.livepatch.u.list.metadata, metadata);
> set_xen_guest_handle(sysctl.u.livepatch.u.list.metadata_len,
> metadata_len);
>
> + sysctl.u.livepatch.u.list.name_total_size = name_sz;
> + sysctl.u.livepatch.u.list.metadata_total_size = metadata_sz;
> +
> rc = do_sysctl(xch, &sysctl);
> /*
> * From here on we MUST call xc_hypercall_bounce. If rc < 0 we
> diff --git a/xen/common/livepatch.c b/xen/common/livepatch.c
> index be9b7e367553..72ef22bea5d2 100644
> --- a/xen/common/livepatch.c
> +++ b/xen/common/livepatch.c
> @@ -1311,11 +1311,10 @@ static int livepatch_list(struct
> xen_sysctl_livepatch_list *list)
> return -EINVAL;
> }
>
> - list->name_total_size = 0;
> - list->metadata_total_size = 0;
> if ( list->nr )
> {
> size_t name_offset = 0, metadata_offset = 0;
> + uint32_t name_total_copied = 0, metadata_total_copied = 0;
>
> list_for_each_entry( data, &payload_list, list )
> {
> @@ -1328,10 +1327,14 @@ static int livepatch_list(struct
> xen_sysctl_livepatch_list *list)
> status.rc = data->rc;
>
> name_len = strlen(data->name) + 1;
> - list->name_total_size += name_len;
> -
> metadata_len = data->metadata.len;
> - list->metadata_total_size += metadata_len;
> +
> + if ( ((uint64_t)name_total_copied + name_len) >
> list->name_total_size ||
> + ((uint64_t)metadata_total_copied + metadata_len) >
> list->metadata_total_size )
I would define name_total_copied and metadata_total_copied as size_t,
and then avoid doing the cast to uint64_t here.
Also please adjust line length to 80 characters max.
Thanks, Roger.
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |