Fix ARC pointer overrun

Only access the `b_crypt_hdr` field of an ARC header if the content
is encrypted.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Tom Caputi <tcaputi@datto.com>
Reviewed-by: George Melikov <mail@gmelikov.ru>
Reviewed-by: Giuseppe Di Natale <dinatale2@llnl.gov>
Signed-off-by: DHE <git@dehacked.net>
Closes #6877
This commit is contained in:
DeHackEd 2017-11-17 18:11:39 -05:00 committed by Brian Behlendorf
parent d4a72f2386
commit da5d4697a8
1 changed files with 11 additions and 9 deletions

View File

@ -3155,19 +3155,21 @@ arc_buf_destroy_impl(arc_buf_t *buf)
ASSERT(hdr->b_l1hdr.b_bufcnt > 0); ASSERT(hdr->b_l1hdr.b_bufcnt > 0);
hdr->b_l1hdr.b_bufcnt -= 1; hdr->b_l1hdr.b_bufcnt -= 1;
if (ARC_BUF_ENCRYPTED(buf)) if (ARC_BUF_ENCRYPTED(buf)) {
hdr->b_crypt_hdr.b_ebufcnt -= 1; hdr->b_crypt_hdr.b_ebufcnt -= 1;
/* /*
* If we have no more encrypted buffers and we've already * If we have no more encrypted buffers and we've
* gotten a copy of the decrypted data we can free b_rabd to * already gotten a copy of the decrypted data we can
* save some space. * free b_rabd to save some space.
*/ */
if (hdr->b_crypt_hdr.b_ebufcnt == 0 && HDR_HAS_RABD(hdr) && if (hdr->b_crypt_hdr.b_ebufcnt == 0 &&
hdr->b_l1hdr.b_pabd != NULL && !HDR_IO_IN_PROGRESS(hdr)) { HDR_HAS_RABD(hdr) && hdr->b_l1hdr.b_pabd != NULL &&
!HDR_IO_IN_PROGRESS(hdr)) {
arc_hdr_free_abd(hdr, B_TRUE); arc_hdr_free_abd(hdr, B_TRUE);
} }
} }
}
arc_buf_t *lastbuf = arc_buf_remove(hdr, buf); arc_buf_t *lastbuf = arc_buf_remove(hdr, buf);