The branch stable/14 has been updated by markj:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=cdf6e2d9feec03b0995c54be46d70471c3d69e5f

commit cdf6e2d9feec03b0995c54be46d70471c3d69e5f
Author:     Mark Johnston <[email protected]>
AuthorDate: 2025-05-09 00:16:53 +0000
Commit:     Mark Johnston <[email protected]>
CommitDate: 2025-06-01 19:53:29 +0000

    krb5: Fix handling of transient crypto request failures
    
    - Instead of using CRYPTO_F_DONE to decide whether a request has
      completed, use a custom protocol of setting crp_opaque = NULL in the
      callback and checking that instead.  CRYPTO_F_DONE is set independent
      of whether an error occurred, but for transient errors signaled by
      EAGAIN, we want to simply retry the request.
    - Clear CRYPTO_F_DONE before retrying the request.
    - Panic if the request truly failed, as we currently have no way to
      pass hard errors back up.
    
    Reviewed by:    jhb
    MFC after:      2 weeks
    Differential Revision:  https://reviews.freebsd.org/D50238
    
    (cherry picked from commit 04421fda140b92eb0d22bc4c0f81b6de05f21225)
---
 sys/kgssapi/krb5/kcrypto_aes.c | 30 +++++++++++++++++++-----------
 1 file changed, 19 insertions(+), 11 deletions(-)

diff --git a/sys/kgssapi/krb5/kcrypto_aes.c b/sys/kgssapi/krb5/kcrypto_aes.c
index 39d3ee1aac2b..fa871b695226 100644
--- a/sys/kgssapi/krb5/kcrypto_aes.c
+++ b/sys/kgssapi/krb5/kcrypto_aes.c
@@ -117,19 +117,24 @@ aes_random_to_key(struct krb5_key_state *ks, const void 
*in)
 static int
 aes_crypto_cb(struct cryptop *crp)
 {
-       int error;
        struct aes_state *as = (struct aes_state *) crp->crp_opaque;
 
-       if (CRYPTO_SESS_SYNC(crp->crp_session))
+       if (CRYPTO_SESS_SYNC(crp->crp_session)) {
+               KASSERT(crp->crp_etype == 0,
+                   ("%s: callback with error %d", __func__, crp->crp_etype));
                return (0);
+       }
 
-       error = crp->crp_etype;
-       if (error == EAGAIN)
-               error = crypto_dispatch(crp);
-       mtx_lock(&as->as_lock);
-       if (error || (crp->crp_flags & CRYPTO_F_DONE))
+       if (crp->crp_etype == EAGAIN) {
+               crp->crp_etype = 0;
+               crp->crp_flags &= ~CRYPTO_F_DONE;
+               (void)crypto_dispatch(crp);
+       } else {
+               mtx_lock(&as->as_lock);
+               crp->crp_opaque = NULL;
                wakeup(crp);
-       mtx_unlock(&as->as_lock);
+               mtx_unlock(&as->as_lock);
+       }
 
        return (0);
 }
@@ -165,11 +170,12 @@ aes_encrypt_1(const struct krb5_key_state *ks, int 
buftype, void *buf,
 
        if (!CRYPTO_SESS_SYNC(as->as_session_aes)) {
                mtx_lock(&as->as_lock);
-               if (!error && !(crp->crp_flags & CRYPTO_F_DONE))
+               if (error == 0 && crp->crp_opaque != NULL)
                        error = msleep(crp, &as->as_lock, 0, "gssaes", 0);
                mtx_unlock(&as->as_lock);
        }
-
+       if (crp->crp_etype != 0)
+               panic("%s: crypto req failed: %d", __func__, crp->crp_etype);
        crypto_freereq(crp);
 }
 
@@ -335,11 +341,13 @@ aes_checksum(const struct krb5_key_state *ks, int usage,
 
        if (!CRYPTO_SESS_SYNC(as->as_session_sha1)) {
                mtx_lock(&as->as_lock);
-               if (!error && !(crp->crp_flags & CRYPTO_F_DONE))
+               if (error == 0 && crp->crp_opaque != NULL)
                        error = msleep(crp, &as->as_lock, 0, "gssaes", 0);
                mtx_unlock(&as->as_lock);
        }
 
+       if (crp->crp_etype != 0)
+               panic("%s: crypto req failed: %d", __func__, crp->crp_etype);
        crypto_freereq(crp);
 }
 

Reply via email to