|
|
@ -777,16 +777,16 @@ emad_advance(const struct ffa_emad_v1_0 *emad, size_t offset) |
|
|
|
static int spmc_shmem_check_obj(struct spmc_shmem_obj *obj, |
|
|
|
uint32_t ffa_version) |
|
|
|
{ |
|
|
|
uint64_t total_page_count; |
|
|
|
unsigned long long total_page_count; |
|
|
|
const struct ffa_emad_v1_0 *first_emad; |
|
|
|
const struct ffa_emad_v1_0 *end_emad; |
|
|
|
size_t emad_size; |
|
|
|
uint32_t comp_mrd_offset = 0; |
|
|
|
uint32_t comp_mrd_offset; |
|
|
|
size_t header_emad_size; |
|
|
|
size_t size; |
|
|
|
size_t count; |
|
|
|
size_t expected_size; |
|
|
|
struct ffa_comp_mrd *comp; |
|
|
|
const struct ffa_comp_mrd *comp; |
|
|
|
|
|
|
|
if (obj->desc_filled != obj->desc_size) { |
|
|
|
ERROR("BUG: %s called on incomplete object (%zu != %zu)\n", |
|
|
@ -884,16 +884,18 @@ static int spmc_shmem_check_obj(struct spmc_shmem_obj *obj, |
|
|
|
} |
|
|
|
size -= comp_mrd_offset; |
|
|
|
|
|
|
|
/* Check that there is enough space for the composite descriptor. */ |
|
|
|
if (size < sizeof(struct ffa_comp_mrd)) { |
|
|
|
WARN("%s: invalid object, offset %u, total size %zu, no header space.\n", |
|
|
|
__func__, comp_mrd_offset, obj->desc_size); |
|
|
|
return FFA_ERROR_INVALID_PARAMETER; |
|
|
|
} |
|
|
|
size -= sizeof(struct ffa_comp_mrd); |
|
|
|
size -= sizeof(*comp); |
|
|
|
|
|
|
|
count = size / sizeof(struct ffa_cons_mrd); |
|
|
|
|
|
|
|
comp = spmc_shmem_obj_get_comp_mrd(obj, ffa_version); |
|
|
|
comp = (const struct ffa_comp_mrd *) |
|
|
|
((const uint8_t *)(&obj->desc) + comp_mrd_offset); |
|
|
|
|
|
|
|
if (comp->address_range_count != count) { |
|
|
|
WARN("%s: invalid object, desc count %u != %zu\n", |
|
|
@ -901,6 +903,7 @@ static int spmc_shmem_check_obj(struct spmc_shmem_obj *obj, |
|
|
|
return FFA_ERROR_INVALID_PARAMETER; |
|
|
|
} |
|
|
|
|
|
|
|
/* Ensure that the expected and actual sizes are equal. */ |
|
|
|
expected_size = comp_mrd_offset + sizeof(*comp) + |
|
|
|
count * sizeof(struct ffa_cons_mrd); |
|
|
|
|
|
|
@ -912,6 +915,10 @@ static int spmc_shmem_check_obj(struct spmc_shmem_obj *obj, |
|
|
|
|
|
|
|
total_page_count = 0; |
|
|
|
|
|
|
|
/*
|
|
|
|
* comp->address_range_count is 32-bit, so 'count' must fit in a |
|
|
|
* uint32_t at this point. |
|
|
|
*/ |
|
|
|
for (size_t i = 0; i < count; i++) { |
|
|
|
const struct ffa_cons_mrd *mrd = comp->address_range_array + i; |
|
|
|
|
|
|
@ -921,12 +928,17 @@ static int spmc_shmem_check_obj(struct spmc_shmem_obj *obj, |
|
|
|
__func__, i, (unsigned long long)mrd->address); |
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
|
* No overflow possible: total_page_count can hold at |
|
|
|
* least 2^64 - 1, but will be have at most 2^32 - 1. |
|
|
|
* values added to it, each of which cannot exceed 2^32 - 1. |
|
|
|
*/ |
|
|
|
total_page_count += mrd->page_count; |
|
|
|
} |
|
|
|
|
|
|
|
if (comp->total_page_count != total_page_count) { |
|
|
|
WARN("%s: invalid object, desc total_page_count %u != %" PRIu64 "\n", |
|
|
|
__func__, comp->total_page_count, |
|
|
|
total_page_count); |
|
|
|
WARN("%s: invalid object, desc total_page_count %u != %llu\n", |
|
|
|
__func__, comp->total_page_count, total_page_count); |
|
|
|
return FFA_ERROR_INVALID_PARAMETER; |
|
|
|
} |
|
|
|
|
|
|
|