Date: Mon, 30 Aug 2021 18:23:35 GMT From: Mark Johnston <markj@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 564b6aa7fccd - main - aesni: Avoid a potential out-of-bounds load in aes_encrypt_icm() Message-ID: <202108301823.17UINZJZ089198@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=564b6aa7fccd98654207447f870b82659b895e7b commit 564b6aa7fccd98654207447f870b82659b895e7b Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2021-08-30 18:22:20 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2021-08-30 18:22:20 +0000 aesni: Avoid a potential out-of-bounds load in aes_encrypt_icm() Given a partial block at the end of a payload, aes_encrypt_icm() would perform a 16-byte load of the residual into a temporary variable. This is unsafe in principle since the full block may cross a page boundary. Fix the problem by copying the residual into a stack buffer first. Reported by: syzbot+b7e44cde9e2e89f0f6c9@syzkaller.appspotmail.com Reported by: syzbot+4b5eaf123a99456b5160@syzkaller.appspotmail.com Reported by: syzbot+70c74c1aa232633355ca@syzkaller.appspotmail.com Reported by: syzbot+2c663776a52828373d41@syzkaller.appspotmail.com Reviewed by: cem, jhb MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D31730 --- sys/crypto/aesni/aesni_wrap.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/sys/crypto/aesni/aesni_wrap.c b/sys/crypto/aesni/aesni_wrap.c index 95f7e191d00d..4d2a45b7e4c4 100644 --- a/sys/crypto/aesni/aesni_wrap.c +++ b/sys/crypto/aesni/aesni_wrap.c @@ -213,9 +213,10 @@ aesni_encrypt_icm(int rounds, const void *key_schedule, size_t len, __m128i ctr5, ctr6, ctr7, ctr8; __m128i BSWAP_EPI64; __m128i tout[8]; + __m128i block; struct blocks8 *top; const struct blocks8 *blks; - size_t i, cnt; + size_t i, cnt, resid; BSWAP_EPI64 = _mm_set_epi8(8,9,10,11,12,13,14,15,0,1,2,3,4,5,6,7); @@ -273,12 +274,19 @@ aesni_encrypt_icm(int rounds, const void *key_schedule, size_t len, to += AES_BLOCK_LEN; } - /* handle remaining partial round */ - if (len % AES_BLOCK_LEN != 0) { + /* + * Handle remaining partial round. Copy the remaining payload onto the + * stack to ensure that the full block can be loaded safely. + */ + resid = len % AES_BLOCK_LEN; + if (resid != 0) { tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64); tot = aesni_enc(rounds - 1, key_schedule, tmp1); - tot = tot ^ _mm_loadu_si128((const __m128i *)from); - memcpy(to, &tot, len % AES_BLOCK_LEN); + block = _mm_setzero_si128(); + memcpy(&block, from, resid); + tot = tot ^ _mm_loadu_si128(&block); + memcpy(to, &tot, resid); + explicit_bzero(&block, sizeof(block)); } }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202108301823.17UINZJZ089198>