From: Hemant Agrawal <[email protected]>
In lsx_ccsr_map_region, PAGE_SIZE is a macro 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 passed
to mmap, causing an integer overflow (Coverity CID 49765682).
The old round-down "len & PAGE_MASK" ignored the in-page offset: for a
4096-byte or 6656-byte len on a 64K-page kernel the masked result is 0,
and only the subsequent "if (len < PAGE_SIZE) len = PAGE_SIZE" saved it.
That check did not account for offset + len crossing a page boundary.
Fix by calling sysconf(_SC_PAGESIZE) explicitly into a signed long,
checking for a non-positive return before use, computing page_mask from
the verified value, and keeping map_len as a separate variable so that
the final mmap size is always at least one page. The page-aligned start
address and the back-pointer offset are both derived from the same
page_mask, keeping the three values consistent.
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 | 27 +++++++++++++++++++--------
1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/drivers/net/dpaa2/dpaa2_recycle.c
b/drivers/net/dpaa2/dpaa2_recycle.c
index f78d12362e..f1a234deae 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,28 @@ 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;
+ len = len & page_mask;
+
+ map_len = len;
+ if (map_len < (size_t)page_size)
+ map_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