Skip to content

Commit

Permalink
drivers: xen: gnttab: prevent double-free for grant refs
Browse files Browse the repository at this point in the history
Grant references are allocated with simple O(1) allocator, where every
next free gref is stored in previous and first free gref is always
stored in 0 element.

Current implementation had a possibility for double-free of some gref,
because it did not store any information about entries being claimed.
It may led to invalid gref_list value.

Add GNTTAB_GREF_USED value and mark all taken value to prevent double
free in put_grant_entry().

Signed-off-by: Dmytro Firsov <[email protected]>
  • Loading branch information
firscity committed May 3, 2024
1 parent 3b81717 commit b631737
Showing 1 changed file with 9 additions and 0 deletions.
9 changes: 9 additions & 0 deletions drivers/xen/gnttab.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ LOG_MODULE_REGISTER(xen_gnttab);
#define DT_GNTTAB_SIZE DT_REG_SIZE_BY_IDX(DT_INST(0, xen_xen), 0)
#define GNT_ENTRIES_PER_FRAME (XEN_PAGE_SIZE / sizeof(grant_entry_v1_t))

#define GNTTAB_GREF_USED (UINT32_MAX - 1)
#define GNTTAB_LAST_GREF UINT32_MAX

BUILD_ASSERT(!(DT_GNTTAB_SIZE % XEN_PAGE_SIZE),
Expand Down Expand Up @@ -74,6 +75,7 @@ static grant_ref_t get_grant_entry(void)

gref = gnttab.gref_list[0];
gnttab.gref_list[0] = gnttab.gref_list[gref];
gnttab.gref_list[gref] = GNTTAB_GREF_USED;
k_mutex_unlock(&gnttab.lock);

return gref;
Expand All @@ -82,6 +84,13 @@ static grant_ref_t get_grant_entry(void)
static void put_grant_entry(grant_ref_t gref)
{
k_mutex_lock(&gnttab.lock, K_FOREVER);
if (gnttab.gref_list[gref] != GNTTAB_GREF_USED) {
k_mutex_unlock(&gnttab.lock);
LOG_WRN("Trying to put already free gref = %u", gref);

return;
}

gnttab.gref_list[gref] = gnttab.gref_list[0];
gnttab.gref_list[0] = gref;
k_mutex_unlock(&gnttab.lock);
Expand Down

0 comments on commit b631737

Please sign in to comment.