Skip to content

Commit 68b6dea

Browse files
danieljordan10herbertx
authored andcommitted
crypto: pcrypt - Delay write to padata->info
These three events can race when pcrypt is used multiple times in a template ("pcrypt(pcrypt(...))"): 1. [taskA] The caller makes the crypto request via crypto_aead_encrypt() 2. [kworkerB] padata serializes the inner pcrypt request 3. [kworkerC] padata serializes the outer pcrypt request 3 might finish before the call to crypto_aead_encrypt() returns in 1, resulting in two possible issues. First, a use-after-free of the crypto request's memory when, for example, taskA writes to the outer pcrypt request's padata->info in pcrypt_aead_enc() after kworkerC completes the request. Second, the outer pcrypt request overwrites the inner pcrypt request's return code with -EINPROGRESS, making a successful request appear to fail. For instance, kworkerB writes the outer pcrypt request's padata->info in pcrypt_aead_done() and then taskA overwrites it in pcrypt_aead_enc(). Avoid both situations by delaying the write of padata->info until after the inner crypto request's return code is checked. This prevents the use-after-free by not touching the crypto request's memory after the next-inner crypto request is made, and stops padata->info from being overwritten. Fixes: 5068c7a ("crypto: pcrypt - Add pcrypt crypto parallelization wrapper") Reported-by: [email protected] Signed-off-by: Daniel Jordan <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
1 parent 83bff10 commit 68b6dea

File tree

1 file changed

+8
-4
lines changed

1 file changed

+8
-4
lines changed

crypto/pcrypt.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,14 @@ static void pcrypt_aead_enc(struct padata_priv *padata)
7878
{
7979
struct pcrypt_request *preq = pcrypt_padata_request(padata);
8080
struct aead_request *req = pcrypt_request_ctx(preq);
81+
int ret;
8182

82-
padata->info = crypto_aead_encrypt(req);
83+
ret = crypto_aead_encrypt(req);
8384

84-
if (padata->info == -EINPROGRESS)
85+
if (ret == -EINPROGRESS)
8586
return;
8687

88+
padata->info = ret;
8789
padata_do_serial(padata);
8890
}
8991

@@ -123,12 +125,14 @@ static void pcrypt_aead_dec(struct padata_priv *padata)
123125
{
124126
struct pcrypt_request *preq = pcrypt_padata_request(padata);
125127
struct aead_request *req = pcrypt_request_ctx(preq);
128+
int ret;
126129

127-
padata->info = crypto_aead_decrypt(req);
130+
ret = crypto_aead_decrypt(req);
128131

129-
if (padata->info == -EINPROGRESS)
132+
if (ret == -EINPROGRESS)
130133
return;
131134

135+
padata->info = ret;
132136
padata_do_serial(padata);
133137
}
134138

0 commit comments

Comments
 (0)