]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Handle a couple of NULL QUIC ctx.qc values
authorViktor Dukhovni <openssl-users@dukhovni.org>
Wed, 11 Sep 2024 09:44:43 +0000 (19:44 +1000)
committerNeil Horman <nhorman@openssl.org>
Mon, 17 Feb 2025 16:27:32 +0000 (11:27 -0500)
Now that we also QUIC server (listener) handles, we may have a NULL quic
connection (ctx.qc), and so need to either return early or handle the
NULL `qc` gracefully.

Reviewed-by: Sasa Nedvedicky <sashan@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/25432)

ssl/quic/quic_impl.c

index f0be772336ef6312a80fe895e73f1abda38b801f..671426e04fa38afc8f26a5ea3d1235cb3ee445a8 100644 (file)
@@ -1301,7 +1301,13 @@ int ossl_quic_handle_events(SSL *s)
         return 0;
 
     qctx_lock(&ctx);
-    if (ctx.qc->started)
+    /*
+     * TODO(QUIC SERVER): We should always tick the engine, whether the current
+     * connection is started or not.  When ticking the engine, we MUST avoid
+     * inadvertently starting connections that haven't started, the guards
+     * don't belong here.
+     */
+    if (ctx.qc == NULL || ctx.qc->started)
         ossl_quic_reactor_tick(ossl_quic_obj_get0_reactor(ctx.obj), 0);
     qctx_unlock(&ctx);
     return 1;
@@ -1318,18 +1324,25 @@ QUIC_TAKES_LOCK
 int ossl_quic_get_event_timeout(SSL *s, struct timeval *tv, int *is_infinite)
 {
     QCTX ctx;
-    OSSL_TIME deadline = ossl_time_infinite();
+    QUIC_REACTOR *reactor;
+    OSSL_TIME deadline;
+    OSSL_TIME basetime;
 
     if (!expect_quic_any(s, &ctx))
         return 0;
 
     qctx_lock(&ctx);
 
-    if (ctx.qc->started)
-        deadline
-            = ossl_quic_reactor_get_tick_deadline(ossl_quic_channel_get_reactor(ctx.qc->ch));
+    reactor = ossl_quic_obj_get0_reactor(ctx.obj);
+    /*
+     * TODO(QUIC SERVER): There's no longer a way to indicate infinite timeout,
+     * should this now be the responsibility of
+     * ossl_quic_reactor_get_tick_deadline()?
+     */
+    deadline = ossl_quic_reactor_get_tick_deadline(reactor);
 
     if (ossl_time_is_infinite(deadline)) {
+        qctx_unlock(&ctx);
         *is_infinite = 1;
 
         /*
@@ -1338,14 +1351,24 @@ int ossl_quic_get_event_timeout(SSL *s, struct timeval *tv, int *is_infinite)
          */
         tv->tv_sec  = 1000000;
         tv->tv_usec = 0;
-
-        qctx_unlock(&ctx);
         return 1;
     }
 
-    *tv = ossl_time_to_timeval(ossl_time_subtract(deadline, get_time(ctx.qc)));
-    *is_infinite = 0;
+    /*
+     * TODO(QUIC SERVER): The clock override callback belongs at the engine
+     * (DOMAIN) not the QC layer, which would make `basetime` independent of
+     * the object type.
+     */
+    if (ctx.qc)
+        basetime = get_time(ctx.qc);
+    else
+        basetime = ossl_time_now();
+
     qctx_unlock(&ctx);
+
+    *tv = ossl_time_to_timeval(ossl_time_subtract(deadline, basetime));
+    *is_infinite = 0;
+
     return 1;
 }