From eceb327478f4a99b8ef96d08a5df0c81956a17c7 Mon Sep 17 00:00:00 2001 From: Ryan Moeller Date: Sun, 22 Sep 2019 18:27:53 -0400 Subject: [PATCH] Use signed types to prevent subtraction overflow The difference between the sizes could be positive or negative. Leaving the types as unsigned means the result overflows when the difference is negative and removing the labs() means we'll have introduced a bug. The subtraction results in the correct value when the unsigned integer is interpreted as a signed integer by labs(). Clang doesn't see that we're doing a subtraction and abusing the types. It sees the result of the subtraction, an unsigned value, being passed to an absolute value function and emits a warning which we treat as an error. Reviewed by: Youzhong Yang Reviewed-by: Igor Kozhukhov Reviewed-by: Brian Behlendorf Signed-off-by: Ryan Moeller Closes #9355 --- cmd/zpool/zpool_vdev.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/zpool/zpool_vdev.c b/cmd/zpool/zpool_vdev.c index ef2a30996e53..527fca08b887 100644 --- a/cmd/zpool/zpool_vdev.c +++ b/cmd/zpool/zpool_vdev.c @@ -829,7 +829,7 @@ get_replication(nvlist_t *nvroot, boolean_t fatal) rep.zprl_children = 1; rep.zprl_parity = 0; } else { - uint64_t vdev_size; + int64_t vdev_size; /* * This is a mirror or RAID-Z vdev. Go through and make @@ -859,12 +859,12 @@ get_replication(nvlist_t *nvroot, boolean_t fatal) */ type = NULL; dontreport = 0; - vdev_size = -1ULL; + vdev_size = -1LL; for (c = 0; c < children; c++) { nvlist_t *cnv = child[c]; char *path; struct stat64 statbuf; - uint64_t size = -1ULL; + int64_t size = -1LL; char *childtype; int fd, err; @@ -955,7 +955,7 @@ get_replication(nvlist_t *nvroot, boolean_t fatal) * (~16MB) then report an error. */ if (!dontreport && - (vdev_size != -1ULL && + (vdev_size != -1LL && (labs(size - vdev_size) > ZPOOL_FUZZ))) { if (ret != NULL)