diff mbox series

[ndctl,4/5] ndctl/namespace: protect against overflow handling param.offset

Message ID 065eb60a8255e44d73b5be963ba3a4a532ae1689.1741047738.git.alison.schofield@intel.com (mailing list archive)
State Superseded
Headers show
Series Address Coverity Scan Defects | expand

Commit Message

Alison Schofield March 4, 2025, 12:37 a.m. UTC
From: Alison Schofield <alison.schofield@intel.com>

A param.offset is parsed using parse_size64() but the result is
not checked for the error return ULLONG_MAX. If ULLONG_MAX is
returned, follow-on calculations will lead to overflow.

Add check for ULLONG_MAX upon return from parse_size64.
Add check for overflow in subsequent PFN_MODE offset calculation.

This issue was reported in a coverity scan.

Signed-off-by: Alison Schofield <alison.schofield@intel.com>
---
 ndctl/namespace.c | 8 ++++++++
 1 file changed, 8 insertions(+)

Comments

Dave Jiang March 5, 2025, 4:43 p.m. UTC | #1
On 3/3/25 5:37 PM, alison.schofield@intel.com wrote:
> From: Alison Schofield <alison.schofield@intel.com>
> 
> A param.offset is parsed using parse_size64() but the result is
> not checked for the error return ULLONG_MAX. If ULLONG_MAX is
> returned, follow-on calculations will lead to overflow.
> 
> Add check for ULLONG_MAX upon return from parse_size64.
> Add check for overflow in subsequent PFN_MODE offset calculation.
> 
> This issue was reported in a coverity scan.
> 
> Signed-off-by: Alison Schofield <alison.schofield@intel.com>

Reviewed-by: Dave Jiang <dave.jiang@intel.com>
> ---
>  ndctl/namespace.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/ndctl/namespace.c b/ndctl/namespace.c
> index 5eb9e1e98e11..40bcf4ca65ac 100644
> --- a/ndctl/namespace.c
> +++ b/ndctl/namespace.c
> @@ -1872,6 +1872,10 @@ static int write_pfn_sb(int fd, unsigned long long size, const char *sig,
>  	int rc;
>  
>  	start = parse_size64(param.offset);
> +	if (start == ULLONG_MAX) {
> +		err("failed to parse offset option '%s'\n", param.offset);
> +		return -EINVAL;
> +	}
>  	npfns = PHYS_PFN(size - SZ_8K);
>  	pfn_align = parse_size64(param.align);
>  	align = max(pfn_align, SUBSECTION_SIZE);
> @@ -1913,6 +1917,10 @@ static int write_pfn_sb(int fd, unsigned long long size, const char *sig,
>  		 * struct page size. But we also want to make sure we notice
>  		 * when we end up adding new elements to struct page.
>  		 */
> +		if (start > ULLONG_MAX - (SZ_8K + MAX_STRUCT_PAGE_SIZE * npfns)) {
> +			error("integer overflow in offset calculation\n");
> +			return -EINVAL;
> +		}
>  		offset = ALIGN(start + SZ_8K + MAX_STRUCT_PAGE_SIZE * npfns, align)
>  			- start;
>  	} else
diff mbox series

Patch

diff --git a/ndctl/namespace.c b/ndctl/namespace.c
index 5eb9e1e98e11..40bcf4ca65ac 100644
--- a/ndctl/namespace.c
+++ b/ndctl/namespace.c
@@ -1872,6 +1872,10 @@  static int write_pfn_sb(int fd, unsigned long long size, const char *sig,
 	int rc;
 
 	start = parse_size64(param.offset);
+	if (start == ULLONG_MAX) {
+		err("failed to parse offset option '%s'\n", param.offset);
+		return -EINVAL;
+	}
 	npfns = PHYS_PFN(size - SZ_8K);
 	pfn_align = parse_size64(param.align);
 	align = max(pfn_align, SUBSECTION_SIZE);
@@ -1913,6 +1917,10 @@  static int write_pfn_sb(int fd, unsigned long long size, const char *sig,
 		 * struct page size. But we also want to make sure we notice
 		 * when we end up adding new elements to struct page.
 		 */
+		if (start > ULLONG_MAX - (SZ_8K + MAX_STRUCT_PAGE_SIZE * npfns)) {
+			error("integer overflow in offset calculation\n");
+			return -EINVAL;
+		}
 		offset = ALIGN(start + SZ_8K + MAX_STRUCT_PAGE_SIZE * npfns, align)
 			- start;
 	} else