From: Hemant Agrawal <[email protected]>
In lsx_ccsr_map_region(), PAGE_SIZE is defined as
sysconf(_SC_PAGESIZE), which returns a signed long and may be
negative on error. The value was used directly in size_t
comparisons and mmap() length calculations, leading to an
integer overflow (Coverity CID 49765682).
The old code also computed the mapping length without taking
the address offset within the page into account. As a result,
regions crossing a page boundary might not be fully mapped.
The mapping size must cover the entire range from the
page-aligned start address through offset + len.
Fix by validating the page size returned by sysconf(),
deriving the page mask from the validated value, and using
RTE_ALIGN_CEIL(offset + len, page_size) to calculate the
mapping length.
Coverity issue: 49765682
Fixes: f023d059769f ("net/dpaa2: support recycle loopback port")
Cc: [email protected]
Signed-off-by: Hemant Agrawal <[email protected]>
---
drivers/net/dpaa2/dpaa2_recycle.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/drivers/net/dpaa2/dpaa2_recycle.c
b/drivers/net/dpaa2/dpaa2_recycle.c
index f78d12362e..9b6ae3f515 100644
--- a/drivers/net/dpaa2/dpaa2_recycle.c
+++ b/drivers/net/dpaa2/dpaa2_recycle.c
@@ -176,6 +176,9 @@ static void *lsx_ccsr_map_region(uint64_t addr, size_t len)
void *tmp;
uint64_t start;
uint64_t offset;
+ uint64_t page_mask;
+ long page_size;
+ size_t map_len;
fd = open("/dev/mem", O_RDWR);
if (fd < 0) {
@@ -183,20 +186,24 @@ static void *lsx_ccsr_map_region(uint64_t addr, size_t
len)
return NULL;
}
- start = addr & PAGE_MASK;
+ page_size = sysconf(_SC_PAGESIZE);
+ if (page_size <= 0) {
+ close(fd);
+ return NULL;
+ }
+ page_mask = ~((uint64_t)page_size - 1);
+ start = addr & page_mask;
offset = addr - start;
- len = len & PAGE_MASK;
- if (len < (size_t)PAGE_SIZE)
- len = PAGE_SIZE;
+ map_len = RTE_ALIGN_CEIL(offset + len, (size_t)page_size);
- tmp = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, start);
+ tmp = mmap(NULL, map_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
start);
close(fd);
- if (tmp != MAP_FAILED)
- return (uint8_t *)tmp + offset;
- else
+ if (tmp == MAP_FAILED)
return NULL;
+
+ return (uint8_t *)tmp + offset;
}
static const uint8_t ls_sd1_prot_idx_map[] = {
--
2.43.0