Flesh out static dtrace probes for /dev/crypto ioctl errors.

In particular, no probes were present for AEAD requests, but also for
some other error cases in other ioctl requests.

MFC after:	2 weeks
Sponsored by:	Chelsio Communications
This commit is contained in:
John Baldwin 2018-01-11 00:22:24 +00:00
parent dc045f499a
commit 776a2127ef
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=327803

View File

@ -443,6 +443,7 @@ cryptof_ioctl(
default: default:
CRYPTDEB("invalid cipher"); CRYPTDEB("invalid cipher");
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EINVAL); return (EINVAL);
} }
@ -490,6 +491,7 @@ cryptof_ioctl(
break; break;
default: default:
CRYPTDEB("invalid mac"); CRYPTDEB("invalid mac");
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EINVAL); return (EINVAL);
} }
@ -503,6 +505,8 @@ cryptof_ioctl(
sop->keylen < txform->minkey) { sop->keylen < txform->minkey) {
CRYPTDEB("invalid cipher parameters"); CRYPTDEB("invalid cipher parameters");
error = EINVAL; error = EINVAL;
SDT_PROBE1(opencrypto, dev, ioctl, error,
__LINE__);
goto bail; goto bail;
} }
@ -511,6 +515,8 @@ cryptof_ioctl(
if ((error = copyin(sop->key, crie.cri_key, if ((error = copyin(sop->key, crie.cri_key,
crie.cri_klen / 8))) { crie.cri_klen / 8))) {
CRYPTDEB("invalid key"); CRYPTDEB("invalid key");
SDT_PROBE1(opencrypto, dev, ioctl, error,
__LINE__);
goto bail; goto bail;
} }
if (thash) if (thash)
@ -524,6 +530,8 @@ cryptof_ioctl(
sop->mackeylen > thash->keysize) { sop->mackeylen > thash->keysize) {
CRYPTDEB("invalid mac key length"); CRYPTDEB("invalid mac key length");
error = EINVAL; error = EINVAL;
SDT_PROBE1(opencrypto, dev, ioctl, error,
__LINE__);
goto bail; goto bail;
} }
@ -533,6 +541,8 @@ cryptof_ioctl(
if ((error = copyin(sop->mackey, cria.cri_key, if ((error = copyin(sop->mackey, cria.cri_key,
cria.cri_klen / 8))) { cria.cri_klen / 8))) {
CRYPTDEB("invalid mac key"); CRYPTDEB("invalid mac key");
SDT_PROBE1(opencrypto, dev, ioctl,
error, __LINE__);
goto bail; goto bail;
} }
} }
@ -548,6 +558,8 @@ cryptof_ioctl(
error = checkforsoftware(&crid); error = checkforsoftware(&crid);
if (error) { if (error) {
CRYPTDEB("checkforsoftware"); CRYPTDEB("checkforsoftware");
SDT_PROBE1(opencrypto, dev, ioctl, error,
__LINE__);
goto bail; goto bail;
} }
} else } else
@ -555,6 +567,7 @@ cryptof_ioctl(
error = crypto_newsession(&sid, (txform ? &crie : &cria), crid); error = crypto_newsession(&sid, (txform ? &crie : &cria), crid);
if (error) { if (error) {
CRYPTDEB("crypto_newsession"); CRYPTDEB("crypto_newsession");
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail; goto bail;
} }
@ -565,6 +578,7 @@ cryptof_ioctl(
if (cse == NULL) { if (cse == NULL) {
crypto_freesession(sid); crypto_freesession(sid);
error = EINVAL; error = EINVAL;
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
CRYPTDEB("csecreate"); CRYPTDEB("csecreate");
goto bail; goto bail;
} }
@ -597,8 +611,10 @@ cryptof_ioctl(
case CIOCFSESSION: case CIOCFSESSION:
ses = *(u_int32_t *)data; ses = *(u_int32_t *)data;
cse = csefind(fcr, ses); cse = csefind(fcr, ses);
if (cse == NULL) if (cse == NULL) {
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EINVAL); return (EINVAL);
}
csedelete(fcr, cse); csedelete(fcr, cse);
error = csefree(cse); error = csefree(cse);
break; break;
@ -628,8 +644,10 @@ cryptof_ioctl(
case CIOCKEY32: case CIOCKEY32:
case CIOCKEY232: case CIOCKEY232:
#endif #endif
if (!crypto_userasymcrypto) if (!crypto_userasymcrypto) {
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EPERM); /* XXX compat? */ return (EPERM); /* XXX compat? */
}
#ifdef COMPAT_FREEBSD32 #ifdef COMPAT_FREEBSD32
if (cmd == CIOCKEY32 || cmd == CIOCKEY232) { if (cmd == CIOCKEY32 || cmd == CIOCKEY232) {
kop = &kopc; kop = &kopc;
@ -663,8 +681,12 @@ cryptof_ioctl(
* fallback to doing them in software. * fallback to doing them in software.
*/ */
*(int *)data = 0; *(int *)data = 0;
} else } else {
error = crypto_getfeat((int *)data); error = crypto_getfeat((int *)data);
if (error)
SDT_PROBE1(opencrypto, dev, ioctl, error,
__LINE__);
}
break; break;
case CIOCFINDDEV: case CIOCFINDDEV:
error = cryptodev_find((struct crypt_find_op *)data); error = cryptodev_find((struct crypt_find_op *)data);
@ -672,12 +694,15 @@ cryptof_ioctl(
case CIOCCRYPTAEAD: case CIOCCRYPTAEAD:
caead = (struct crypt_aead *)data; caead = (struct crypt_aead *)data;
cse = csefind(fcr, caead->ses); cse = csefind(fcr, caead->ses);
if (cse == NULL) if (cse == NULL) {
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EINVAL); return (EINVAL);
}
error = cryptodev_aead(cse, caead, active_cred, td); error = cryptodev_aead(cse, caead, active_cred, td);
break; break;
default: default:
error = EINVAL; error = EINVAL;
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
break; break;
} }
return (error); return (error);
@ -892,12 +917,16 @@ cryptodev_aead(
struct cryptodesc *crde = NULL, *crda = NULL; struct cryptodesc *crde = NULL, *crda = NULL;
int error; int error;
if (caead->len > 256*1024-4 || caead->aadlen > 256*1024-4) if (caead->len > 256*1024-4 || caead->aadlen > 256*1024-4) {
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (E2BIG); return (E2BIG);
}
if (cse->txform == NULL || cse->thash == NULL || caead->tag == NULL || if (cse->txform == NULL || cse->thash == NULL || caead->tag == NULL ||
(caead->len % cse->txform->blocksize) != 0) (caead->len % cse->txform->blocksize) != 0) {
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EINVAL); return (EINVAL);
}
uio = &cse->uio; uio = &cse->uio;
uio->uio_iov = &cse->iovec; uio->uio_iov = &cse->iovec;
@ -915,6 +944,7 @@ cryptodev_aead(
crp = crypto_getreq(2); crp = crypto_getreq(2);
if (crp == NULL) { if (crp == NULL) {
error = ENOMEM; error = ENOMEM;
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail; goto bail;
} }
@ -927,12 +957,16 @@ cryptodev_aead(
} }
if ((error = copyin(caead->aad, cse->uio.uio_iov[0].iov_base, if ((error = copyin(caead->aad, cse->uio.uio_iov[0].iov_base,
caead->aadlen))) caead->aadlen))) {
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail; goto bail;
}
if ((error = copyin(caead->src, (char *)cse->uio.uio_iov[0].iov_base + if ((error = copyin(caead->src, (char *)cse->uio.uio_iov[0].iov_base +
caead->aadlen, caead->len))) caead->aadlen, caead->len))) {
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail; goto bail;
}
/* /*
* For GCM, crd_len covers only the AAD. For other ciphers * For GCM, crd_len covers only the AAD. For other ciphers
@ -973,11 +1007,14 @@ cryptodev_aead(
if (caead->iv) { if (caead->iv) {
if (caead->ivlen > sizeof cse->tmp_iv) { if (caead->ivlen > sizeof cse->tmp_iv) {
error = EINVAL; error = EINVAL;
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail; goto bail;
} }
if ((error = copyin(caead->iv, cse->tmp_iv, caead->ivlen))) if ((error = copyin(caead->iv, cse->tmp_iv, caead->ivlen))) {
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail; goto bail;
}
bcopy(cse->tmp_iv, crde->crd_iv, caead->ivlen); bcopy(cse->tmp_iv, crde->crd_iv, caead->ivlen);
crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT; crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
} else { } else {
@ -987,8 +1024,10 @@ cryptodev_aead(
} }
if ((error = copyin(caead->tag, (caddr_t)cse->uio.uio_iov[0].iov_base + if ((error = copyin(caead->tag, (caddr_t)cse->uio.uio_iov[0].iov_base +
caead->len + caead->aadlen, cse->thash->hashsize))) caead->len + caead->aadlen, cse->thash->hashsize))) {
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail; goto bail;
}
again: again:
/* /*
* Let the dispatch run unlocked, then, interlock against the * Let the dispatch run unlocked, then, interlock against the
@ -1003,8 +1042,10 @@ cryptodev_aead(
error = msleep(crp, &cse->lock, PWAIT, "crydev", 0); error = msleep(crp, &cse->lock, PWAIT, "crydev", 0);
mtx_unlock(&cse->lock); mtx_unlock(&cse->lock);
if (error != 0) if (error != 0) {
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail; goto bail;
}
if (crp->crp_etype == EAGAIN) { if (crp->crp_etype == EAGAIN) {
crp->crp_etype = 0; crp->crp_etype = 0;
@ -1014,22 +1055,28 @@ cryptodev_aead(
if (crp->crp_etype != 0) { if (crp->crp_etype != 0) {
error = crp->crp_etype; error = crp->crp_etype;
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail; goto bail;
} }
if (cse->error) { if (cse->error) {
error = cse->error; error = cse->error;
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail; goto bail;
} }
if (caead->dst && (error = copyout( if (caead->dst && (error = copyout(
(caddr_t)cse->uio.uio_iov[0].iov_base + caead->aadlen, caead->dst, (caddr_t)cse->uio.uio_iov[0].iov_base + caead->aadlen, caead->dst,
caead->len))) caead->len))) {
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail; goto bail;
}
if ((error = copyout((caddr_t)cse->uio.uio_iov[0].iov_base + if ((error = copyout((caddr_t)cse->uio.uio_iov[0].iov_base +
caead->aadlen + caead->len, caead->tag, cse->thash->hashsize))) caead->aadlen + caead->len, caead->tag, cse->thash->hashsize))) {
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail; goto bail;
}
bail: bail:
crypto_freereq(crp); crypto_freereq(crp);
@ -1068,6 +1115,7 @@ cryptodev_key(struct crypt_kop *kop)
int in, out, size, i; int in, out, size, i;
if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) { if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) {
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EFBIG); return (EFBIG);
} }
@ -1077,30 +1125,38 @@ cryptodev_key(struct crypt_kop *kop)
case CRK_MOD_EXP: case CRK_MOD_EXP:
if (in == 3 && out == 1) if (in == 3 && out == 1)
break; break;
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EINVAL); return (EINVAL);
case CRK_MOD_EXP_CRT: case CRK_MOD_EXP_CRT:
if (in == 6 && out == 1) if (in == 6 && out == 1)
break; break;
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EINVAL); return (EINVAL);
case CRK_DSA_SIGN: case CRK_DSA_SIGN:
if (in == 5 && out == 2) if (in == 5 && out == 2)
break; break;
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EINVAL); return (EINVAL);
case CRK_DSA_VERIFY: case CRK_DSA_VERIFY:
if (in == 7 && out == 0) if (in == 7 && out == 0)
break; break;
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EINVAL); return (EINVAL);
case CRK_DH_COMPUTE_KEY: case CRK_DH_COMPUTE_KEY:
if (in == 3 && out == 1) if (in == 3 && out == 1)
break; break;
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EINVAL); return (EINVAL);
default: default:
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EINVAL); return (EINVAL);
} }
krp = (struct cryptkop *)malloc(sizeof *krp, M_XDATA, M_WAITOK|M_ZERO); krp = (struct cryptkop *)malloc(sizeof *krp, M_XDATA, M_WAITOK|M_ZERO);
if (!krp) if (!krp) {
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (ENOMEM); return (ENOMEM);
}
krp->krp_op = kop->crk_op; krp->krp_op = kop->crk_op;
krp->krp_status = kop->crk_status; krp->krp_status = kop->crk_status;
krp->krp_iparams = kop->crk_iparams; krp->krp_iparams = kop->crk_iparams;
@ -1110,9 +1166,11 @@ cryptodev_key(struct crypt_kop *kop)
krp->krp_callback = (int (*) (struct cryptkop *)) cryptodevkey_cb; krp->krp_callback = (int (*) (struct cryptkop *)) cryptodevkey_cb;
for (i = 0; i < CRK_MAXPARAM; i++) { for (i = 0; i < CRK_MAXPARAM; i++) {
if (kop->crk_param[i].crp_nbits > 65536) if (kop->crk_param[i].crp_nbits > 65536) {
/* Limit is the same as in OpenBSD */ /* Limit is the same as in OpenBSD */
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto fail; goto fail;
}
krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits; krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits;
} }
for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) { for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) {
@ -1123,22 +1181,28 @@ cryptodev_key(struct crypt_kop *kop)
if (i >= krp->krp_iparams) if (i >= krp->krp_iparams)
continue; continue;
error = copyin(kop->crk_param[i].crp_p, krp->krp_param[i].crp_p, size); error = copyin(kop->crk_param[i].crp_p, krp->krp_param[i].crp_p, size);
if (error) if (error) {
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto fail; goto fail;
}
} }
error = crypto_kdispatch(krp); error = crypto_kdispatch(krp);
if (error) if (error) {
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto fail; goto fail;
}
error = tsleep(krp, PSOCK, "crydev", 0); error = tsleep(krp, PSOCK, "crydev", 0);
if (error) { if (error) {
/* XXX can this happen? if so, how do we recover? */ /* XXX can this happen? if so, how do we recover? */
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto fail; goto fail;
} }
kop->crk_crid = krp->krp_crid; /* device that did the work */ kop->crk_crid = krp->krp_crid; /* device that did the work */
if (krp->krp_status != 0) { if (krp->krp_status != 0) {
error = krp->krp_status; error = krp->krp_status;
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto fail; goto fail;
} }
@ -1147,8 +1211,10 @@ cryptodev_key(struct crypt_kop *kop)
if (size == 0) if (size == 0)
continue; continue;
error = copyout(krp->krp_param[i].crp_p, kop->crk_param[i].crp_p, size); error = copyout(krp->krp_param[i].crp_p, kop->crk_param[i].crp_p, size);
if (error) if (error) {
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto fail; goto fail;
}
} }
fail: fail: