From 84fea065dbb7a1fd4b1f0493e38f36a347a1a615 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 5 Nov 2020 23:26:02 +0000 Subject: [PATCH] Don't modify the destination pointer in ioctl requests. This breaks the case where the original pointer was NULL but an in-line IV was used. Reviewed by: markj Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D27064 --- sys/opencrypto/cryptodev.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/sys/opencrypto/cryptodev.c b/sys/opencrypto/cryptodev.c index 3a5da7d2e57a..7982b4342f1f 100644 --- a/sys/opencrypto/cryptodev.c +++ b/sys/opencrypto/cryptodev.c @@ -381,7 +381,7 @@ static struct csession *csecreate(struct fcrypt *, crypto_session_t, struct auth_hash *, void *); static void csefree(struct csession *); -static int cryptodev_op(struct csession *, struct crypt_op *, +static int cryptodev_op(struct csession *, const struct crypt_op *, struct ucred *, struct thread *td); static int cryptodev_aead(struct csession *, struct crypt_aead *, struct ucred *, struct thread *); @@ -942,12 +942,13 @@ cod_free(struct cryptop_data *cod) static int cryptodev_op( struct csession *cse, - struct crypt_op *cop, + const struct crypt_op *cop, struct ucred *active_cred, struct thread *td) { struct cryptop_data *cod = NULL; struct cryptop *crp = NULL; + char *dst; int error; if (cop->len > 256*1024-4) { @@ -980,6 +981,7 @@ cryptodev_op( } cod = cod_alloc(cse, 0, cop->len + cse->hashsize, td); + dst = cop->dst; crp = crypto_getreq(cse->cses, M_WAITOK); @@ -1082,7 +1084,7 @@ cryptodev_op( crp->crp_iv_start = 0; crp->crp_payload_start += cse->ivsize; crp->crp_payload_length -= cse->ivsize; - cop->dst += cse->ivsize; + dst += cse->ivsize; } if (cop->mac != NULL && crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) { @@ -1127,7 +1129,7 @@ cryptodev_op( if (cop->dst != NULL) { error = copyout(cod->obuf != NULL ? cod->obuf : - cod->buf + crp->crp_payload_start, cop->dst, + cod->buf + crp->crp_payload_start, dst, crp->crp_payload_length); if (error) { SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); @@ -1160,6 +1162,7 @@ cryptodev_aead( { struct cryptop_data *cod = NULL; struct cryptop *crp = NULL; + char *dst; int error; if (caead->len > 256*1024-4 || caead->aadlen > 256*1024-4) { @@ -1186,6 +1189,7 @@ cryptodev_aead( } cod = cod_alloc(cse, caead->aadlen, caead->len + cse->hashsize, td); + dst = caead->dst; crp = crypto_getreq(cse->cses, M_WAITOK); @@ -1277,7 +1281,7 @@ cryptodev_aead( crp->crp_iv_start = crp->crp_payload_start; crp->crp_payload_start += cse->ivsize; crp->crp_payload_length -= cse->ivsize; - caead->dst += cse->ivsize; + dst += cse->ivsize; } if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) { @@ -1322,7 +1326,7 @@ cryptodev_aead( if (caead->dst != NULL) { error = copyout(cod->obuf != NULL ? cod->obuf : - cod->buf + crp->crp_payload_start, caead->dst, + cod->buf + crp->crp_payload_start, dst, crp->crp_payload_length); if (error) { SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);