From 0012145fd6a2a339a435bdbb5999ab0c7dd90707 Mon Sep 17 00:00:00 2001 From: Raphael Hunziker Date: Thu, 10 Sep 2026 19:50:04 +0200 Subject: [PATCH 1/3] navigation: reject JUMP waypoints with an out-of-range target JUMP targets are uploaded as 1 based WP numbers and converted to a zero based index on storage, so a target of 0 ended up stored as -1 and was later used to index the waypoint list. Reject such uploads and refuse a negative target in the mission validation as well. Fixes #11841 --- src/main/navigation/navigation.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/navigation/navigation.c b/src/main/navigation/navigation.c index 7d7cf1629fb..ca54bd3eb2a 100644 --- a/src/main/navigation/navigation.c +++ b/src/main/navigation/navigation.c @@ -5468,6 +5468,11 @@ void setWaypoint(uint8_t wpNumber, const navWaypoint_t * wpData) else if ((wpNumber >= 1) && (wpNumber <= NAV_MAX_WAYPOINTS) && !FLIGHT_MODE(NAV_WP_MODE)) { // WP upload is not allowed why WP mode is active if (wpData->action == NAV_WP_ACTION_WAYPOINT || wpData->action == NAV_WP_ACTION_JUMP || wpData->action == NAV_WP_ACTION_RTH || wpData->action == NAV_WP_ACTION_HOLD_TIME || wpData->action == NAV_WP_ACTION_LAND || wpData->action == NAV_WP_ACTION_SET_POI || wpData->action == NAV_WP_ACTION_SET_HEAD ) { + // JUMP target is a WP number, it has to reference another WP of the mission + if (wpData->action == NAV_WP_ACTION_JUMP && (wpData->p1 < 1 || wpData->p1 > NAV_MAX_WAYPOINTS)) { + return; + } + // Only allow upload next waypoint (continue upload mission) or first waypoint (new mission) static int8_t nonGeoWaypointCount = 0; @@ -6366,7 +6371,7 @@ navArmingBlocker_e navigationIsBlockingArming(bool *usedBypass) if (posControl.waypointCount) { for (uint8_t wp = posControl.startWpIndex; wp < posControl.waypointCount + posControl.startWpIndex; wp++){ if (posControl.waypointList[wp].action == NAV_WP_ACTION_JUMP){ - if (wp == posControl.startWpIndex || posControl.waypointList[wp].p1 >= posControl.waypointCount || + if (wp == posControl.startWpIndex || posControl.waypointList[wp].p1 < 0 || posControl.waypointList[wp].p1 >= posControl.waypointCount || (posControl.waypointList[wp].p1 > (wp - posControl.startWpIndex - 2) && posControl.waypointList[wp].p1 < (wp - posControl.startWpIndex + 2)) || posControl.waypointList[wp].p2 < -1) { return NAV_ARMING_BLOCKER_JUMP_WAYPOINT_ERROR; } From 11a226b219eb30a8fce9a0f3a1e4c893b6e0a130 Mon Sep 17 00:00:00 2001 From: Raffi1202 Date: Fri, 11 Sep 2026 18:08:56 +0200 Subject: [PATCH 2/3] Invalidate the old mission before rejecting its replacement --- src/main/navigation/navigation.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/navigation/navigation.c b/src/main/navigation/navigation.c index ca54bd3eb2a..aff7bb29d96 100644 --- a/src/main/navigation/navigation.c +++ b/src/main/navigation/navigation.c @@ -5468,17 +5468,17 @@ void setWaypoint(uint8_t wpNumber, const navWaypoint_t * wpData) else if ((wpNumber >= 1) && (wpNumber <= NAV_MAX_WAYPOINTS) && !FLIGHT_MODE(NAV_WP_MODE)) { // WP upload is not allowed why WP mode is active if (wpData->action == NAV_WP_ACTION_WAYPOINT || wpData->action == NAV_WP_ACTION_JUMP || wpData->action == NAV_WP_ACTION_RTH || wpData->action == NAV_WP_ACTION_HOLD_TIME || wpData->action == NAV_WP_ACTION_LAND || wpData->action == NAV_WP_ACTION_SET_POI || wpData->action == NAV_WP_ACTION_SET_HEAD ) { - // JUMP target is a WP number, it has to reference another WP of the mission - if (wpData->action == NAV_WP_ACTION_JUMP && (wpData->p1 < 1 || wpData->p1 > NAV_MAX_WAYPOINTS)) { - return; - } - // Only allow upload next waypoint (continue upload mission) or first waypoint (new mission) static int8_t nonGeoWaypointCount = 0; if (wpNumber == (posControl.waypointCount + 1) || wpNumber == 1) { if (wpNumber == 1) { resetWaypointList(); + nonGeoWaypointCount = 0; + } + // Reject the new mission after clearing the previous one, before copying or converting the target. + if (wpData->action == NAV_WP_ACTION_JUMP && (wpData->p1 < 1 || wpData->p1 > NAV_MAX_WAYPOINTS)) { + return; } posControl.waypointList[wpNumber - 1] = *wpData; if(wpData->action == NAV_WP_ACTION_SET_POI || wpData->action == NAV_WP_ACTION_SET_HEAD || wpData->action == NAV_WP_ACTION_JUMP) { From 3645ed52c77719e6c27d910071c3fc81964f69ae Mon Sep 17 00:00:00 2001 From: Raffi1202 <250872901+Raffi1202@users.noreply.github.com> Date: Wed, 23 Sep 2026 14:50:15 +0200 Subject: [PATCH 3/3] Re-run CI