OpenZFS 9523 - Large alloc in zdb can cause trouble

16MB alloc in zdb_embedded_block() can cause cores in certain
situations (clang, gcc55).

Authored by: Jorgen Lundman <lundman@lundman.net>
Reviewed by: Igor Kozhukhov <igor@dilos.org>
Reviewed by: Andriy Gapon <avg@FreeBSD.org>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed-by: George Melikov <mail@gmelikov.ru>
Approved by: Dan McDonald <danmcd@joyent.com>
Ported-by: Brian Behlendorf <behlendorf1@llnl.gov>

Porting Notes:
* Replaces an equivalent fix previously made for Linux.

OpenZFS-issue: https://illumos.org/issues/9523
OpenZFS-commit: https://github.com/openzfs/openzfs/commit/2c1964a
Closes #7561
This commit is contained in:
Jorgen Lundman 2018-05-07 17:35:50 +09:00 committed by Brian Behlendorf
parent 0dc2f70c5c
commit 561ba8d1b1
1 changed files with 8 additions and 5 deletions

View File

@ -4834,8 +4834,6 @@ zdb_embedded_block(char *thing)
char *buf; char *buf;
int err; int err;
buf = umem_alloc(SPA_MAXBLOCKSIZE, UMEM_NOFAIL);
bzero(&bp, sizeof (bp)); bzero(&bp, sizeof (bp));
err = sscanf(thing, "%llx:%llx:%llx:%llx:%llx:%llx:%llx:%llx:" err = sscanf(thing, "%llx:%llx:%llx:%llx:%llx:%llx:%llx:%llx:"
"%llx:%llx:%llx:%llx:%llx:%llx:%llx:%llx", "%llx:%llx:%llx:%llx:%llx:%llx:%llx:%llx",
@ -4844,17 +4842,22 @@ zdb_embedded_block(char *thing)
words + 8, words + 9, words + 10, words + 11, words + 8, words + 9, words + 10, words + 11,
words + 12, words + 13, words + 14, words + 15); words + 12, words + 13, words + 14, words + 15);
if (err != 16) { if (err != 16) {
(void) printf("invalid input format\n"); (void) fprintf(stderr, "invalid input format\n");
exit(1); exit(1);
} }
ASSERT3U(BPE_GET_LSIZE(&bp), <=, SPA_MAXBLOCKSIZE); ASSERT3U(BPE_GET_LSIZE(&bp), <=, SPA_MAXBLOCKSIZE);
buf = malloc(SPA_MAXBLOCKSIZE);
if (buf == NULL) {
(void) fprintf(stderr, "out of memory\n");
exit(1);
}
err = decode_embedded_bp(&bp, buf, BPE_GET_LSIZE(&bp)); err = decode_embedded_bp(&bp, buf, BPE_GET_LSIZE(&bp));
if (err != 0) { if (err != 0) {
(void) printf("decode failed: %u\n", err); (void) fprintf(stderr, "decode failed: %u\n", err);
exit(1); exit(1);
} }
zdb_dump_block_raw(buf, BPE_GET_LSIZE(&bp), 0); zdb_dump_block_raw(buf, BPE_GET_LSIZE(&bp), 0);
umem_free(buf, SPA_MAXBLOCKSIZE); free(buf);
} }
int int