untrusted comment: verify with openbsd-78-base.pub RWS3/nvFmk4SWXmGFFiKI5YTKP9rD1JxqZnGVunljdWI3R/5aw5QhARz7m11hkw3jLS0VimENriLHczjGEhJY9CkglEu/+q2AA0= OpenBSD 7.8 errata 027, April 4, 2026: In iked(8) add stricter checks to avoid out-of-bounds read, NULL pointer dereference, and keep the state machine consistent. Apply by doing: signify -Vep /etc/signify/openbsd-78-base.pub -x 027_iked.patch.sig \ -m - | (cd /usr/src && patch -p0) And then rebuild and install iked: cd /usr/src/sbin/iked make obj make make install Index: sbin/iked/ikev2.c =================================================================== RCS file: /cvs/src/sbin/iked/ikev2.c,v diff -u -p -r1.394 ikev2.c --- sbin/iked/ikev2.c 31 Jul 2025 19:02:43 -0000 1.394 +++ sbin/iked/ikev2.c 30 Mar 2026 17:12:00 -0000 @@ -713,7 +713,7 @@ ikev2_recv(struct iked *env, struct iked } if (msg->msg_response) { - if (msg->msg_msgid > sa->sa_reqid) { + if (msg->msg_msgid + 1 != sa->sa_reqid) { ikestat_inc(env, ikes_msg_rcvd_dropped); return; } @@ -4452,6 +4452,9 @@ ikev2_init_create_child_sa(struct iked * uint32_t spi32; int pfs = 0, ret = -1; + if (!sa_stateok(sa, IKEV2_STATE_ESTABLISHED)) + return -1; + if (!ikev2_msg_frompeer(msg) || (sa->sa_stateflags & (IKED_REQ_CHILDSA|IKED_REQ_INF)) == 0) return (0); @@ -4916,6 +4919,9 @@ ikev2_resp_create_child_sa(struct iked * int initiator, protoid, rekeying = 1; int ret = -1; int pfs = 0; + + if (!sa_stateok(sa, IKEV2_STATE_ESTABLISHED)) + return -1; initiator = sa->sa_hdr.sh_initiator ? 1 : 0; Index: sbin/iked/ikev2_pld.c =================================================================== RCS file: /cvs/src/sbin/iked/ikev2_pld.c,v diff -u -p -r1.136 ikev2_pld.c --- sbin/iked/ikev2_pld.c 13 Jul 2024 12:22:46 -0000 1.136 +++ sbin/iked/ikev2_pld.c 30 Mar 2026 17:12:00 -0000 @@ -99,6 +99,8 @@ int ikev2_pld_auth(struct iked *, struc struct iked_message *, size_t, size_t); int ikev2_pld_e(struct iked *, struct ikev2_payload *, struct iked_message *, size_t, size_t); +int ikev2_validate_ef(struct iked_message *, size_t, size_t, + struct ikev2_frag_payload *); int ikev2_pld_ef(struct iked *env, struct ikev2_payload *pld, struct iked_message *msg, size_t offset, size_t left); int ikev2_frags_reassemble(struct iked *env, @@ -1612,6 +1614,22 @@ ikev2_pld_ts(struct iked *env, struct ik } int +ikev2_validate_ef(struct iked_message *msg, size_t offset, size_t left, + struct ikev2_frag_payload *frag) +{ + uint8_t *msgbuf = ibuf_data(msg->msg_data); + + if (left < sizeof(*frag)) { + log_debug("%s: malformed payload: too short for header " + "(%zu < %zu)", __func__, left, sizeof(*frag)); + return (-1); + } + memcpy(frag, msgbuf + offset, sizeof(*frag)); + + return (0); +} + +int ikev2_pld_ef(struct iked *env, struct ikev2_payload *pld, struct iked_message *msg, size_t offset, size_t left) { @@ -1628,8 +1646,9 @@ ikev2_pld_ef(struct iked *env, struct ik int processed = 0; ssize_t elen; - buf = msgbuf + offset; - memcpy(&frag, buf, sizeof(frag)); + if (ikev2_validate_ef(msg, offset, left, &frag) != 0) + return (-1); + frag_num = betoh16(frag.frag_num); frag_total = betoh16(frag.frag_total); @@ -1778,9 +1797,7 @@ ikev2_frags_reassemble(struct iked *env, /* Drop the original request's packets from the retransmit queue */ if (msg->msg_response) - ikev2_msg_dispose(env, &msg->msg_sa->sa_requests, - ikev2_msg_lookup(env, &msg->msg_sa->sa_requests, msg, - msg->msg_exchange)); + ikev2_msg_flushqueue(env, &msg->msg_sa->sa_requests); /* * Parse decrypted payload Index: regress/sbin/iked/parser/common.c =================================================================== RCS file: /cvs/src/regress/sbin/iked/parser/common.c,v diff -u -p -r1.13 common.c --- regress/sbin/iked/parser/common.c 3 Dec 2022 22:34:35 -0000 1.13 +++ regress/sbin/iked/parser/common.c 30 Mar 2026 17:12:00 -0000 @@ -210,8 +210,7 @@ ikev2_ike_sa_setreason(struct iked_sa *s } void -ikev2_msg_dispose(struct iked *env, struct iked_msgqueue *queue, - struct iked_msg_retransmit *mr) +ikev2_msg_flushqueue(struct iked *env, struct iked_msgqueue *queue) { }