diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2019-11-01 15:46:12 -0400 |
---|---|---|
committer | Eric Sandeen <sandeen@sandeen.net> | 2019-11-01 15:46:12 -0400 |
commit | 4546e66dff005f7bd8efd0c8705b72b5807385ff (patch) | |
tree | 2efc7df979754924dc2d64bfc496291b68577524 | |
parent | d9b8ae44b6ee51329af7d81968b9feacc55ffa13 (diff) | |
download | xfsprogs-dev-4546e66dff005f7bd8efd0c8705b72b5807385ff.tar.gz |
xfs_db: btheight should check geometry more carefully
The btheight command needs to check user-supplied geometry more
carefully so that we don't hit floating point exceptions.
Coverity-id: 1453661, 1453659
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
-rw-r--r-- | db/btheight.c | 88 |
1 files changed, 82 insertions, 6 deletions
diff --git a/db/btheight.c b/db/btheight.c index 289e5d84ec..8aa17c895b 100644 --- a/db/btheight.c +++ b/db/btheight.c @@ -138,6 +138,10 @@ construct_records_per_block( perror(p); goto out; } + if (record_size == 0) { + fprintf(stderr, _("%s: record size cannot be zero.\n"), tag); + goto out; + } p = strtok(NULL, ":"); if (!p) { @@ -149,6 +153,10 @@ construct_records_per_block( perror(p); goto out; } + if (key_size == 0) { + fprintf(stderr, _("%s: key size cannot be zero.\n"), tag); + goto out; + } p = strtok(NULL, ":"); if (!p) { @@ -160,6 +168,10 @@ construct_records_per_block( perror(p); goto out; } + if (ptr_size == 0) { + fprintf(stderr, _("%s: pointer size cannot be zero.\n"), tag); + goto out; + } p = strtok(NULL, ":"); if (!p) { @@ -180,6 +192,27 @@ construct_records_per_block( goto out; } + if (record_size > blocksize) { + fprintf(stderr, +_("%s: record size must be less than selected block size (%u bytes).\n"), + tag, blocksize); + goto out; + } + + if (key_size > blocksize) { + fprintf(stderr, +_("%s: key size must be less than selected block size (%u bytes).\n"), + tag, blocksize); + goto out; + } + + if (ptr_size > blocksize) { + fprintf(stderr, +_("%s: pointer size must be less than selected block size (%u bytes).\n"), + tag, blocksize); + goto out; + } + p = strtok(NULL, ":"); if (p) { fprintf(stderr, @@ -211,13 +244,24 @@ report( int ret; ret = construct_records_per_block(tag, blocksize, records_per_block); - if (ret) { - printf(_("%s: Unable to determine records per block.\n"), - tag); + if (ret) return; - } if (report_what & REPORT_MAX) { + if (records_per_block[0] < 2) { + fprintf(stderr, +_("%s: cannot calculate best case scenario due to leaf geometry underflow.\n"), + tag); + return; + } + + if (records_per_block[1] < 4) { + fprintf(stderr, +_("%s: cannot calculate best case scenario due to node geometry underflow.\n"), + tag); + return; + } + printf( _("%s: best case per %u-byte block: %u records (leaf) / %u keyptrs (node)\n"), tag, blocksize, records_per_block[0], @@ -230,6 +274,20 @@ _("%s: best case per %u-byte block: %u records (leaf) / %u keyptrs (node)\n"), records_per_block[0] /= 2; records_per_block[1] /= 2; + if (records_per_block[0] < 1) { + fprintf(stderr, +_("%s: cannot calculate worst case scenario due to leaf geometry underflow.\n"), + tag); + return; + } + + if (records_per_block[1] < 2) { + fprintf(stderr, +_("%s: cannot calculate worst case scenario due to node geometry underflow.\n"), + tag); + return; + } + printf( _("%s: worst case per %u-byte block: %u records (leaf) / %u keyptrs (node)\n"), tag, blocksize, records_per_block[0], @@ -284,8 +342,26 @@ btheight_f( } } - if (argc == optind || blocksize <= 0 || blocksize > INT_MAX || - nr_records == 0) { + if (nr_records == 0) { + fprintf(stderr, +_("Number of records must be greater than zero.\n")); + return 0; + } + + if (blocksize > INT_MAX) { + fprintf(stderr, +_("The largest block size this command will consider is %u bytes.\n"), + INT_MAX); + return 0; + } + + if (blocksize < 128) { + fprintf(stderr, +_("The smallest block size this command will consider is 128 bytes.\n")); + return 0; + } + + if (argc == optind) { btheight_help(); return 0; } |