Skip to content

Commit 8e1fa89

Browse files
smuellerDDherbertx
authored andcommitted
crypto: algif_aead - skip SGL entries with NULL page
The TX SGL may contain SGL entries that are assigned a NULL page. This may happen if a multi-stage AIO operation is performed where the data for each stage is pointed to by one SGL entry. Upon completion of that stage, af_alg_pull_tsgl will assign NULL to the SGL entry. The NULL cipher used to copy the AAD from TX SGL to the destination buffer, however, cannot handle the case where the SGL starts with an SGL entry having a NULL page. Thus, the code needs to advance the start pointer into the SGL to the first non-NULL entry. This fixes a crash visible on Intel x86 32 bit using the libkcapi test suite. Cc: <stable@vger.kernel.org> Fixes: 72548b0 ("crypto: algif_aead - copy AAD from src to dst") Signed-off-by: Stephan Mueller <smueller@chronox.de> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
1 parent 1d9ddde commit 8e1fa89

File tree

1 file changed

+24
-9
lines changed

1 file changed

+24
-9
lines changed

crypto/algif_aead.c

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,10 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
101101
struct aead_tfm *aeadc = pask->private;
102102
struct crypto_aead *tfm = aeadc->aead;
103103
struct crypto_skcipher *null_tfm = aeadc->null_tfm;
104-
unsigned int as = crypto_aead_authsize(tfm);
104+
unsigned int i, as = crypto_aead_authsize(tfm);
105105
struct af_alg_async_req *areq;
106-
struct af_alg_tsgl *tsgl;
107-
struct scatterlist *src;
106+
struct af_alg_tsgl *tsgl, *tmp;
107+
struct scatterlist *rsgl_src, *tsgl_src = NULL;
108108
int err = 0;
109109
size_t used = 0; /* [in] TX bufs to be en/decrypted */
110110
size_t outlen = 0; /* [out] RX bufs produced by kernel */
@@ -178,7 +178,22 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
178178
}
179179

180180
processed = used + ctx->aead_assoclen;
181-
tsgl = list_first_entry(&ctx->tsgl_list, struct af_alg_tsgl, list);
181+
list_for_each_entry_safe(tsgl, tmp, &ctx->tsgl_list, list) {
182+
for (i = 0; i < tsgl->cur; i++) {
183+
struct scatterlist *process_sg = tsgl->sg + i;
184+
185+
if (!(process_sg->length) || !sg_page(process_sg))
186+
continue;
187+
tsgl_src = process_sg;
188+
break;
189+
}
190+
if (tsgl_src)
191+
break;
192+
}
193+
if (processed && !tsgl_src) {
194+
err = -EFAULT;
195+
goto free;
196+
}
182197

183198
/*
184199
* Copy of AAD from source to destination
@@ -194,7 +209,7 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
194209
*/
195210

196211
/* Use the RX SGL as source (and destination) for crypto op. */
197-
src = areq->first_rsgl.sgl.sg;
212+
rsgl_src = areq->first_rsgl.sgl.sg;
198213

199214
if (ctx->enc) {
200215
/*
@@ -207,7 +222,7 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
207222
* v v
208223
* RX SGL: AAD || PT || Tag
209224
*/
210-
err = crypto_aead_copy_sgl(null_tfm, tsgl->sg,
225+
err = crypto_aead_copy_sgl(null_tfm, tsgl_src,
211226
areq->first_rsgl.sgl.sg, processed);
212227
if (err)
213228
goto free;
@@ -225,7 +240,7 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
225240
*/
226241

227242
/* Copy AAD || CT to RX SGL buffer for in-place operation. */
228-
err = crypto_aead_copy_sgl(null_tfm, tsgl->sg,
243+
err = crypto_aead_copy_sgl(null_tfm, tsgl_src,
229244
areq->first_rsgl.sgl.sg, outlen);
230245
if (err)
231246
goto free;
@@ -257,11 +272,11 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
257272
areq->tsgl);
258273
} else
259274
/* no RX SGL present (e.g. authentication only) */
260-
src = areq->tsgl;
275+
rsgl_src = areq->tsgl;
261276
}
262277

263278
/* Initialize the crypto operation */
264-
aead_request_set_crypt(&areq->cra_u.aead_req, src,
279+
aead_request_set_crypt(&areq->cra_u.aead_req, rsgl_src,
265280
areq->first_rsgl.sgl.sg, used, ctx->iv);
266281
aead_request_set_ad(&areq->cra_u.aead_req, ctx->aead_assoclen);
267282
aead_request_set_tfm(&areq->cra_u.aead_req, tfm);

0 commit comments

Comments
 (0)