aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2019-12-12 19:54:33 -0500
committerEric Sandeen <sandeen@redhat.com>2019-12-12 19:54:33 -0500
commit9e468ed634ede66ec96c3c4e8cda0816d21fdcaa (patch)
treee17f1fcaf686eb3771fb29a34750860da16dfb79
parent6c3013adde40bf366a985c6e5e0d3d59d2d138f4 (diff)
downloadxfsprogs-dev-9e468ed634ede66ec96c3c4e8cda0816d21fdcaa.tar.gz
xfs: fix sign handling problem in xfs_bmbt_diff_two_keys
Source kernel commit: b521c89027f4b86af418083cb75db60a0e7a5997 In xfs_bmbt_diff_two_keys, we perform a signed int64_t subtraction with two unsigned 64-bit quantities. If the second quantity is actually the "maximum" key (all ones) as used in _query_all, the subtraction effectively becomes addition of two positive numbers and the function returns incorrect results. Fix this with explicit comparisons of the unsigned values. Nobody needs this now, but the online repair patches will need this to work properly. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
-rw-r--r--libxfs/xfs_bmap_btree.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c
index 3c1945a167..443816867a 100644
--- a/libxfs/xfs_bmap_btree.c
+++ b/libxfs/xfs_bmap_btree.c
@@ -398,8 +398,20 @@ xfs_bmbt_diff_two_keys(
union xfs_btree_key *k1,
union xfs_btree_key *k2)
{
- return (int64_t)be64_to_cpu(k1->bmbt.br_startoff) -
- be64_to_cpu(k2->bmbt.br_startoff);
+ uint64_t a = be64_to_cpu(k1->bmbt.br_startoff);
+ uint64_t b = be64_to_cpu(k2->bmbt.br_startoff);
+
+ /*
+ * Note: This routine previously casted a and b to int64 and subtracted
+ * them to generate a result. This lead to problems if b was the
+ * "maximum" key value (all ones) being signed incorrectly, hence this
+ * somewhat less efficient version.
+ */
+ if (a > b)
+ return 1;
+ if (b > a)
+ return -1;
+ return 0;
}
static xfs_failaddr_t