Control startup of PROC_CERT and PROC_IKEV2.
authortobhe <tobhe@openbsd.org>
Tue, 13 Feb 2024 12:25:11 +0000 (12:25 +0000)
committertobhe <tobhe@openbsd.org>
Tue, 13 Feb 2024 12:25:11 +0000 (12:25 +0000)
Currenly PROC_PARENT sends the configuration to both PROC_CERT and
PROC_IKEV2 and finishes by sending IMSG_CTL_ACTIVE to PROC_IKEV2.

However, when PROC_IKEV2 receives IMSG_CTL_ACTIVE it does not know
the state of PROC_CERT: PROC_CERT might not have processed the
initial configuration while PROC_IKEV2 already sends requests to
PROC_CERT, causing failed requests, or even crashes (NULL deref of
ca_certs).

In order to make sure that PROC_CERT is ready before
IMSG_CTL_ACTIVE is sent to PROC_IKEV2 that startup protocol
is changed as follows:

(1) PROC_PARENT sends configuration to both PROC_CERT and PROC_IKEV2
(2) PROC_PARENT sends IMSG_CTL_ACTIVE to PROC_CERT
(3) PROC_CERT acks IMSG_CTL_ACTIVE by sending it back to PROC_PARENT
(4) PROC_PARENT now knows that PROC_CERT is ready and has processed
    all messages from step (1)
(5) PROC_PARENT sends IMSG_CTL_ACTIVE to PROC_IKEV2 and knows that
    IMSG_CTL_ACTIVE will be processed by PROC_IKEV2 after all
    messages from step (1)
(6) PROC_IKEV2 can now assume that PROC_CERT is ready because it has
    already processed IMSG_CTL_ACTIVE

from markus@

sbin/iked/ca.c
sbin/iked/config.c
sbin/iked/iked.c

index 8eb9de5..3c41834 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ca.c,v 1.100 2024/02/06 13:10:56 tobhe Exp $  */
+/*     $OpenBSD: ca.c,v 1.101 2024/02/13 12:25:11 tobhe Exp $  */
 
 /*
  * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
@@ -332,6 +332,14 @@ ca_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
        unsigned int             mode;
 
        switch (imsg->hdr.type) {
+       case IMSG_CTL_ACTIVE:
+       case IMSG_CTL_PASSIVE:
+               /*
+                * send back to indicate we have processed
+                * all messages from parent.
+                */
+               proc_compose(&env->sc_ps, PROC_PARENT, imsg->hdr.type, NULL, 0);
+               break;
        case IMSG_CTL_RESET:
                IMSG_SIZE_CHECK(imsg, &mode);
                memcpy(&mode, imsg->data, sizeof(mode));
index cc26eee..6398e64 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: config.c,v 1.95 2024/01/17 08:25:02 claudio Exp $     */
+/*     $OpenBSD: config.c,v 1.96 2024/02/13 12:25:11 tobhe Exp $       */
 
 /*
  * Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
@@ -507,8 +507,14 @@ config_setmode(struct iked *env, unsigned int passive)
 {
        unsigned int     type;
 
+       /*
+        * In order to control the startup of the processes,
+        * the messages are sent in this order:
+        *   PROC_PARENT -> PROC_CERT -> PROC_PARENT -> PROC_IKEV2
+        * so PROC_CERT is ready before PROC_IKEV2 is activated.
+        */
        type = passive ? IMSG_CTL_PASSIVE : IMSG_CTL_ACTIVE;
-       proc_compose(&env->sc_ps, PROC_IKEV2, type, NULL, 0);
+       proc_compose(&env->sc_ps, PROC_CERT, type, NULL, 0);
 
        return (0);
 }
index e370424..f1e6020 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: iked.c,v 1.67 2024/01/15 15:29:00 tobhe Exp $ */
+/*     $OpenBSD: iked.c,v 1.68 2024/02/13 12:25:11 tobhe Exp $ */
 
 /*
  * Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
@@ -422,6 +422,10 @@ parent_dispatch_ca(int fd, struct privsep_proc *p, struct imsg *imsg)
        struct iked     *env = iked_env;
 
        switch (imsg->hdr.type) {
+       case IMSG_CTL_ACTIVE:
+       case IMSG_CTL_PASSIVE:
+               proc_forward_imsg(&env->sc_ps, imsg, PROC_IKEV2, -1);
+               break;
        case IMSG_OCSP_FD:
                ocsp_connect(env, imsg);
                break;