commit 50d0b774af96dbdb933b8ca806fee2ded381ff75 Author: Kurt Stutsman Date: Wed Apr 22 18:13:30 2015 -0400 [x86] crypto: aesni - fix memory usage in GCM decryption Message-id: <1429726410-30521-1-git-send-email-kstutsma@redhat.com> Patchwork-id: 111185 O-Subject: [RHEL7 PATCH] x86/crypto: aesni - fix memory usage in GCM decryption Bugzilla: 1212178 CVE: CVE-2015-3331 RH-Acked-by: Steve Best RH-Acked-by: Jarod Wilson RH-Acked-by: Herbert Xu From: Stephan Mueller Bugzilla: 1212178 Build: https://brewweb.devel.redhat.com/taskinfo?taskID=9004327 Tested: boot test only This is a straightfoward cherry-pick of an upstream commit. There is a not a reproducer and the instructions to reproduce are vague, so I've only performed a boot test. upstream commit ccfe8c3f7e52ae83155cb038753f4c75b774ca8a Author: Stephan Mueller Date: Thu Mar 12 09:17:51 2015 +0100 The kernel crypto API logic requires the caller to provide the length of (ciphertext || authentication tag) as cryptlen for the AEAD decryption operation. Thus, the cipher implementation must calculate the size of the plaintext output itself and cannot simply use cryptlen. The RFC4106 GCM decryption operation tries to overwrite cryptlen memory in req->dst. As the destination buffer for decryption only needs to hold the plaintext memory but cryptlen references the input buffer holding (ciphertext || authentication tag), the assumption of the destination buffer length in RFC4106 GCM operation leads to a too large size. This patch simply uses the already calculated plaintext size. In addition, this patch fixes the offset calculation of the AAD buffer pointer: as mentioned before, cryptlen already includes the size of the tag. Thus, the tag does not need to be added. With the addition, the AAD will be written beyond the already allocated buffer. Note, this fixes a kernel crash that can be triggered from user space via AF_ALG(aead) -- simply use the libkcapi test application from [1] and update it to use rfc4106-gcm-aes. Using [1], the changes were tested using CAVS vectors to demonstrate that the crypto operation still delivers the right results. [1] http://www.chronox.de/libkcapi.html CC: Tadeusz Struk Cc: stable@vger.kernel.org Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu (cherry picked from commit ccfe8c3f7e52ae83155cb038753f4c75b774ca8a) Signed-off-by: Rafael Aquini diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c index 487893a54ea6..2b13b4645765 100644 --- a/arch/x86/crypto/aesni-intel_glue.c +++ b/arch/x86/crypto/aesni-intel_glue.c @@ -1038,7 +1038,7 @@ static int __driver_rfc4106_decrypt(struct aead_request *req) src = kmalloc(req->cryptlen + req->assoclen, GFP_ATOMIC); if (!src) return -ENOMEM; - assoc = (src + req->cryptlen + auth_tag_len); + assoc = (src + req->cryptlen); scatterwalk_map_and_copy(src, req->src, 0, req->cryptlen, 0); scatterwalk_map_and_copy(assoc, req->assoc, 0, req->assoclen, 0); @@ -1063,7 +1063,7 @@ static int __driver_rfc4106_decrypt(struct aead_request *req) scatterwalk_done(&src_sg_walk, 0, 0); scatterwalk_done(&assoc_sg_walk, 0, 0); } else { - scatterwalk_map_and_copy(dst, req->dst, 0, req->cryptlen, 1); + scatterwalk_map_and_copy(dst, req->dst, 0, tempCipherLen, 1); kfree(src); } return retval;