--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: bookworm
X-Debbugs-Cc: [email protected]
Control: affects -1 + src:gpsd
User: [email protected]
Usertags: pu
[ Reason ]
CVE-2025-67268
CVE-2025-67269
[ Impact ]
CVE are not fixed
[ Tests ]
Automated during build
[ Risks ]
Low
[ Checklist ]
X ] *all* changes are documented in the d/changelog
X ] I reviewed all changes and I approve them
X ] attach debdiff against the package in (old)stable
X ] the issue is verified as fixed in unstable
[ Changes ]
CVE patches and salsaCI fix including a patch removing a systematic rebuild of
all rdeps (superseded and considered bad for salsa)
[ Other info ]
diff -Nru gpsd-3.22/debian/.gitlab-ci.yml gpsd-3.22/debian/.gitlab-ci.yml
--- gpsd-3.22/debian/.gitlab-ci.yml 2022-09-11 14:45:05.000000000 +0000
+++ gpsd-3.22/debian/.gitlab-ci.yml 2026-01-18 11:45:58.000000000 +0000
@@ -1,10 +1,9 @@
include:
- https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/salsa-ci.yml
- https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/pipeline-jobs.yml
- - https://bzed.pages.debian.net/reverse-dependency-ci/gpsd.yml
variables:
- RELEASE: 'unstable'
+ RELEASE: 'bookworm'
SALSA_CI_DISABLE_APTLY: 0
SALSA_CI_DISABLE_AUTOPKGTEST: 0
SALSA_CI_DISABLE_BLHC: 0
@@ -13,5 +12,3 @@
SALSA_CI_DISABLE_REPROTEST: 1
SALSA_CI_DISABLE_BUILD_PACKAGE_ALL: 0
SALSA_CI_DISABLE_BUILD_PACKAGE_ANY: 0
- SALSA_CI_ENABLE_REVERSE_DEPENDENCY_BUILD: 1
-
diff -Nru gpsd-3.22/debian/changelog gpsd-3.22/debian/changelog
--- gpsd-3.22/debian/changelog 2022-09-11 14:45:05.000000000 +0000
+++ gpsd-3.22/debian/changelog 2026-01-18 11:45:58.000000000 +0000
@@ -1,3 +1,30 @@
+gpsd (3.22-4.1+deb12u1) bookworm; urgency=medium
+
+ * Non-Maintainer Upload by LTS team
+ * Remove BD: makedev, breaks debusine
+ * Fix CVE-2025-67268 (Closes: #1124800).
+ gpsd contains a heap-based out-of-bounds write
+ vulnerability in the drivers/driver_nmea2000.c file.
+ The hnd_129540 function, which handles NMEA2000 PGN 129540
+ (GNSS Satellites in View) packets, fails to validate the
+ user-supplied satellite count against the size of the skyview
+ array (184 elements). This allows an attacker to write beyond
+ the bounds of the array by providing a satellite count up
+ to 255, leading to memory corruption, Denial of Service (DoS),
+ and potentially arbitrary code execution.
+ * Fix CVE-2025-67269 (Closes: #1124799).
+ An integer underflow vulnerability exists in the `nextstate()`
+ function in `gpsd/packet.c`.
+ When parsing a NAVCOM packet, the payload length is calculated
+ using `lexer->length = (size_t)c - 4` without checking if
+ the input byte `c` is less than 4. This results in an unsigned
+ integer underflow, setting `lexer->length` to a very large value
+ (near `SIZE_MAX`). The parser then enters a loop attempting to
+ consume this massive number of bytes, causing 100% CPU utilization
+ and a Denial of Service (DoS) condition.
+
+ -- Bastien Roucariès <[email protected]> Sun, 18 Jan 2026 12:45:58 +0100
+
gpsd (3.22-4.1) unstable; urgency=medium
* Non-maintainer upload
diff -Nru gpsd-3.22/debian/control gpsd-3.22/debian/control
--- gpsd-3.22/debian/control 2022-09-11 14:45:05.000000000 +0000
+++ gpsd-3.22/debian/control 2026-01-18 11:45:58.000000000 +0000
@@ -10,7 +10,7 @@
xsltproc, docbook-xsl, docbook-xml,
libncurses-dev,
libusb-1.0-0-dev,
- libdbus-1-dev, libglib2.0-dev, libdbus-glib-1-dev, makedev,
+ libdbus-1-dev, libglib2.0-dev, libdbus-glib-1-dev,
libbluetooth-dev [linux-any],
python3-matplotlib, python3-gps, python3-gi, python3-cairo, gir1.2-gtk-3.0,
python3-serial, python3-gi-cairo,
qtbase5-dev,
diff -Nru gpsd-3.22/debian/patches/CVE-2025-67268.patch
gpsd-3.22/debian/patches/CVE-2025-67268.patch
--- gpsd-3.22/debian/patches/CVE-2025-67268.patch 1970-01-01
00:00:00.000000000 +0000
+++ gpsd-3.22/debian/patches/CVE-2025-67268.patch 2026-01-18
11:45:58.000000000 +0000
@@ -0,0 +1,374 @@
+From: "Gary E. Miller" <[email protected]>
+Date: Sat, 17 Jan 2026 17:43:51 +0100
+Subject: [PATCH] drivers/driver_nmea2000.c: Fix issue 356,
+ skyview buffer overrun.
+
+origin:
https://gitlab.com/gpsd/gpsd/-/commit/dc966aa74c075d0a6535811d98628625cbfbe3f4
+debian-bug: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1124800
+---
+ drivers/driver_nmea2000.c | 123 ++++++++++++++++++++++++++--------------------
+ 1 file changed, 71 insertions(+), 52 deletions(-)
+
+diff --git a/drivers/driver_nmea2000.c b/drivers/driver_nmea2000.c
+index c97287f..35ba163 100644
+--- a/drivers/driver_nmea2000.c
++++ b/drivers/driver_nmea2000.c
+@@ -12,11 +12,11 @@
+ * Message contents can be had from canboat/analyzer:
+ * analyzer -explain
+ *
+- * This file is Copyright 2012 by the GPSD project
++ * This file is Copyright by the GPSD project
+ * SPDX-License-Identifier: BSD-2-clause
+ */
+
+-#include "../include/gpsd_config.h" /* must be before all includes */
++#include "../include/gpsd_config.h" // must be before all includes
+
+ #if defined(NMEA2000_ENABLE)
+
+@@ -68,7 +68,7 @@ typedef struct PGN
+
+ #if LOG_FILE
+ FILE *logFile = NULL;
+-#endif /* of if LOG_FILE */
++#endif // of if LOG_FILE
+
+ extern bool __attribute__ ((weak)) gpsd_add_device(const char *device_name,
+ bool flag_nowait);
+@@ -89,14 +89,14 @@ static int scale_int(int32_t var, const int64_t factor)
+ static void print_data(struct gps_context_t *context,
+ unsigned char *buffer, int len, PGN *pgn)
+ {
+- if ((libgps_debuglevel >= LOG_IO) != 0) {
+- int l1, l2, ptr;
++ if (LOG_IO <= libgps_debuglevel) {
++ int l1;
+ char bu[128];
+
+- ptr = 0;
+- l2 = sprintf(&bu[ptr], "got data:%6u:%3d: ", pgn->pgn, len);
++ int ptr = 0;
++ int l2 = sprintf(&bu[ptr], "got data:%6u:%3d: ", pgn->pgn, len);
+ ptr += l2;
+- for (l1=0;l1<len;l1++) {
++ for (l1 = 0; l1 < len; l1++) {
+ if (((l1 % 20) == 0) && (l1 != 0)) {
+ GPSD_LOG(LOG_IO, &context->errout, "%s\n", bu);
+ ptr = 0;
+@@ -276,7 +276,7 @@ static gps_mask_t hnd_127258(unsigned char *bu, int len,
PGN *pgn,
+ struct gps_device_t *session)
+ {
+ print_data(session->context, bu, len, pgn);
+- /* FIXME? Get magnetic variation */
++ // FIXME? Get magnetic variation
+ GPSD_LOG(LOG_DATA, &session->context->errout,
+ "pgn %6d(%3d):\n", pgn->pgn, session->driver.nmea2000.unit);
+ return(0);
+@@ -358,7 +358,7 @@ static gps_mask_t hnd_126992(unsigned char *bu, int len,
PGN *pgn,
+ {
+ // uint8_t sid;
+ // uint8_t source;
+- uint64_t usecs; /* time in us */
++ uint64_t usecs; // time in us
+
+ print_data(session->context, bu, len, pgn);
+ GPSD_LOG(LOG_DATA, &session->context->errout,
+@@ -434,6 +434,7 @@ static gps_mask_t hnd_129540(unsigned char *bu, int len,
PGN *pgn,
+ struct gps_device_t *session)
+ {
+ int l1;
++ int expected_len;
+
+ print_data(session->context, bu, len, pgn);
+ GPSD_LOG(LOG_DATA, &session->context->errout,
+@@ -441,24 +442,39 @@ static gps_mask_t hnd_129540(unsigned char *bu, int len,
PGN *pgn,
+
+ session->driver.nmea2000.sid[2] = bu[0];
+ session->gpsdata.satellites_visible = (int)bu[2];
++ if (MAXCHANNELS <= session->gpsdata.satellites_visible) {
++ // Handle a CVE for overrunning skyview[]
++ GPSD_LOG(LOG_WARN, &session->context->errout,
++ "pgn %6d(%3d): Too many sats %d\n",
++ pgn->pgn, session->driver.nmea2000.unit,
++ session->gpsdata.satellites_visible);
++ session->gpsdata.satellites_visible = MAXCHANNELS;
++ }
++ expected_len = 3 + (12 * session->gpsdata.satellites_visible);
++ if (len != expected_len) {
++ GPSD_LOG(LOG_WARN, &session->context->errout,
++ "pgn %6d(%3d): wrong length %d s/b %d\n",
++ pgn->pgn, session->driver.nmea2000.unit,
++ len, expected_len);
++ return 0;
++ }
+
+ memset(session->gpsdata.skyview, '\0', sizeof(session->gpsdata.skyview));
+- for (l1=0;l1<session->gpsdata.satellites_visible;l1++) {
+- int svt;
+- double azi, elev, snr;
+-
+- elev = getles16(bu, 3+12*l1+1) * 1e-4 * RAD_2_DEG;
+- azi = getleu16(bu, 3+12*l1+3) * 1e-4 * RAD_2_DEG;
+- snr = getles16(bu, 3+12*l1+5) * 1e-2;
++ for (l1 = 0; l1 < session->gpsdata.satellites_visible; l1++) {
++ int offset = 3 + (12 * l1);
++ double elev = getles16(bu, offset + 1) * 1e-4 * RAD_2_DEG;
++ double azi = getleu16(bu, offset + 3) * 1e-4 * RAD_2_DEG;
++ double snr = getles16(bu, offset + 5) * 1e-2;
+
+- svt = (int)(bu[3+12*l1+11] & 0x0f);
++ int svt = (int)(bu[offset + 11] & 0x0f);
+
+- session->gpsdata.skyview[l1].elevation = (short) (round(elev));
+- session->gpsdata.skyview[l1].azimuth = (short) (round(azi));
++ session->gpsdata.skyview[l1].elevation = elev;
++ session->gpsdata.skyview[l1].azimuth = azi;
+ session->gpsdata.skyview[l1].ss = snr;
+- session->gpsdata.skyview[l1].PRN = (short)bu[3+12*l1+0];
++ session->gpsdata.skyview[l1].PRN = (int16_t)bu[offset];
+ session->gpsdata.skyview[l1].used = false;
+- if ((svt == 2) || (svt == 5)) {
++ if ((2 == svt) ||
++ (5 == svt)) {
+ session->gpsdata.skyview[l1].used = true;
+ }
+ }
+@@ -588,7 +604,7 @@ static gps_mask_t hnd_129029(unsigned char *bu, int len,
PGN *pgn,
+ struct gps_device_t *session)
+ {
+ gps_mask_t mask;
+- uint64_t usecs; /* time in us */
++ uint64_t usecs; // time in us
+
+ print_data(session->context, bu, len, pgn);
+ GPSD_LOG(LOG_DATA, &session->context->errout,
+@@ -675,7 +691,7 @@ static gps_mask_t hnd_129038(unsigned char *bu, int len,
PGN *pgn,
+ (unsigned int)ais_direction((unsigned int)getleu16(bu, 21), 1.0);
+ ais->type1.turn = ais_turn_rate((int)getles16(bu, 23));
+ ais->type1.status = (unsigned int) ((bu[25] >> 0) & 0x0f);
+- ais->type1.maneuver = 0; /* Not transmitted ???? */
++ ais->type1.maneuver = 0; // Not transmitted ????
+ decode_ais_channel_info(bu, len, 163, session);
+
+ return(ONLINE_SET | AIS_SET);
+@@ -730,8 +746,9 @@ static gps_mask_t hnd_129039(unsigned char *bu, int len,
PGN *pgn,
+
+ /*
+ * PGN 129040: AIS Class B Extended Position Report
++ *
++ * No test case for this message at the moment
+ */
+-/* No test case for this message at the moment */
+ static gps_mask_t hnd_129040(unsigned char *bu, int len, PGN *pgn,
+ struct gps_device_t *session)
+ {
+@@ -781,8 +798,8 @@ static gps_mask_t hnd_129040(unsigned char *bu, int len,
PGN *pgn,
+ ais->type19.epfd = (unsigned int) ((bu[23] >> 4) & 0x0f);
+ ais->type19.dte = (unsigned int) ((bu[52] >> 0) & 0x01);
+ ais->type19.assigned = (bool) ((bu[52] >> 1) & 0x01);
+- for (l=0;l<AIS_SHIPNAME_MAXLEN;l++) {
+- ais->type19.shipname[l] = (char) bu[32+l];
++ for (l = 0; l < AIS_SHIPNAME_MAXLEN; l++) {
++ ais->type19.shipname[l] = (char)bu[32+l];
+ }
+ ais->type19.shipname[AIS_SHIPNAME_MAXLEN] = (char) 0;
+ decode_ais_channel_info(bu, len, 422, session);
+@@ -914,7 +931,7 @@ static gps_mask_t hnd_129794(unsigned char *bu, int len,
PGN *pgn,
+ ais->type5.draught = (unsigned int) (getleu16(bu, 51)/10);
+ ais->type5.dte = (unsigned int) ((bu[73] >> 6) & 0x01);
+
+- for (l=0,cpy_stop=0;l<7;l++) {
++ for (l = 0, cpy_stop = 0; l < 7; l++) {
+ char next;
+
+ next = (char) bu[9+l];
+@@ -929,7 +946,7 @@ static gps_mask_t hnd_129794(unsigned char *bu, int len,
PGN *pgn,
+ }
+ ais->type5.callsign[7] = (char) 0;
+
+- for (l=0,cpy_stop=0;l<AIS_SHIPNAME_MAXLEN;l++) {
++ for (l = 0, cpy_stop = 0; l < AIS_SHIPNAME_MAXLEN; l++) {
+ char next;
+
+ next = (char) bu[16+l];
+@@ -944,7 +961,7 @@ static gps_mask_t hnd_129794(unsigned char *bu, int len,
PGN *pgn,
+ }
+ ais->type5.shipname[AIS_SHIPNAME_MAXLEN] = (char) 0;
+
+- for (l=0,cpy_stop=0;l<20;l++) {
++ for (l = 0, cpy_stop = 0; l < 20; l++) {
+ char next;
+
+ next = (char) bu[53+l];
+@@ -978,7 +995,7 @@ static gps_mask_t hnd_129794(unsigned char *bu, int len,
PGN *pgn,
+ date2.tm_year+1900,
+ ais->type5.hour,
+ ais->type5.minute);
+-#endif /* of #if NMEA2000_DEBUG_AIS */
++#endif // end of #if NMEA2000_DEBUG_AIS
+ decode_ais_channel_info(bu, len, 592, session);
+ return(ONLINE_SET | AIS_SET);
+ }
+@@ -988,8 +1005,9 @@ static gps_mask_t hnd_129794(unsigned char *bu, int len,
PGN *pgn,
+
+ /*
+ * PGN 129798: AIS SAR Aircraft Position Report
++ *
++ * No test case for this message at the moment
+ */
+-/* No test case for this message at the moment */
+ static gps_mask_t hnd_129798(unsigned char *bu, int len, PGN *pgn,
+ struct gps_device_t *session)
+ {
+@@ -1016,8 +1034,8 @@ static gps_mask_t hnd_129798(unsigned char *bu, int len,
PGN *pgn,
+ ais->type9.alt = (unsigned int) (getleu64(bu, 21)/1000000);
+ ais->type9.regional = (unsigned int) ((bu[29] >> 0) & 0xff);
+ ais->type9.dte = (unsigned int) ((bu[30] >> 0) & 0x01);
+-/* ais->type9.spare = (bu[30] >> 1) & 0x7f; */
+- ais->type9.assigned = 0; /* Not transmitted ???? */
++// ais->type9.spare = (bu[30] >> 1) & 0x7f;
++ ais->type9.assigned = 0; // Not transmitted ????
+ decode_ais_channel_info(bu, len, 163, session);
+
+ return(ONLINE_SET | AIS_SET);
+@@ -1028,8 +1046,9 @@ static gps_mask_t hnd_129798(unsigned char *bu, int len,
PGN *pgn,
+
+ /*
+ * PGN 129802: AIS Safety Related Broadcast Message
++ *
++ * No test case for this message at the moment
+ */
+-/* No test case for this message at the moment */
+ static gps_mask_t hnd_129802(unsigned char *bu, int len, PGN *pgn,
+ struct gps_device_t *session)
+ {
+@@ -1043,8 +1062,8 @@ static gps_mask_t hnd_129802(unsigned char *bu, int len,
PGN *pgn,
+ if (decode_ais_header(session->context, bu, len, ais, 0x3fffffff) != 0) {
+ int l;
+
+-/* ais->type14.channel = (bu[ 5] >> 0) & 0x1f; */
+- for (l=0;l<36;l++) {
++// ais->type14.channel = (bu[ 5] >> 0) & 0x1f;
++ for (l = 0; l < 36; l++) {
+ ais->type14.text[l] = (char) bu[6+l];
+ }
+ ais->type14.text[36] = (char) 0;
+@@ -1079,7 +1098,7 @@ static gps_mask_t hnd_129809(unsigned char *bu, int len,
PGN *pgn,
+ "NMEA2000: AIS message 24A from %09u stashed.\n",
+ ais->mmsi);
+
+- for (l=0;l<AIS_SHIPNAME_MAXLEN;l++) {
++ for (l = 0; l < AIS_SHIPNAME_MAXLEN; l++) {
+ ais->type24.shipname[l] = (char) bu[ 5+l];
+ saveptr->shipname[l] = (char) bu[ 5+l];
+ }
+@@ -1119,12 +1138,12 @@ static gps_mask_t hnd_129810(unsigned char *bu, int
len, PGN *pgn,
+
+ ais->type24.shiptype = (unsigned int) ((bu[ 5] >> 0) & 0xff);
+
+- for (l=0;l<7;l++) {
++ for (l = 0; l < 7; l++) {
+ ais->type24.vendorid[l] = (char) bu[ 6+l];
+ }
+ ais->type24.vendorid[7] = (char) 0;
+
+- for (l=0;l<7;l++) {
++ for (l = 0; l < 7; l++) {
+ ais->type24.callsign[l] = (char) bu[13+l];
+ }
+ ais->type24.callsign[7] = (char )0;
+@@ -1158,7 +1177,7 @@ static gps_mask_t hnd_129810(unsigned char *bu, int len,
PGN *pgn,
+ for (i = 0; i < MAX_TYPE24_INTERLEAVE; i++) {
+ if (session->driver.aivdm.context[0].type24_queue.ships[i].mmsi ==
+ ais->mmsi) {
+- for (l=0;l<AIS_SHIPNAME_MAXLEN;l++) {
++ for (l = 0; l < AIS_SHIPNAME_MAXLEN; l++) {
+ ais->type24.shipname[l] =
+ (char)(session->driver.aivdm.context[0].type24_queue.ships[i].shipname[l]);
+ }
+@@ -1566,7 +1585,7 @@ static void find_pgn(struct can_frame *frame, struct
gps_device_t *session)
+ frame->can_id & 0x1ffffff);
+ if ((frame->can_dlc & 0x0f) > 0) {
+ int l1;
+- for(l1=0;l1<(frame->can_dlc & 0x0f);l1++) {
++ for(l1 = 0; l1 < (frame->can_dlc & 0x0f); l1++) {
+ (void)fprintf(logFile, "%02x", frame->data[l1]);
+ }
+ }
+@@ -1591,8 +1610,8 @@ static void find_pgn(struct can_frame *frame, struct
gps_device_t *session)
+ if (!session->driver.nmea2000.unit_valid) {
+ unsigned int l1, l2;
+
+- for (l1=0;l1<NMEA2000_NETS;l1++) {
+- for (l2=0;l2<NMEA2000_UNITS;l2++) {
++ for (l1 = 0; l1 < NMEA2000_NETS; l1++) {
++ for (l2 = 0; l2 < NMEA2000_UNITS; l2++) {
+ if (session == nmea2000_units[l1][l2]) {
+ session->driver.nmea2000.unit = l2;
+ session->driver.nmea2000.unit_valid = true;
+@@ -1641,7 +1660,7 @@ static void find_pgn(struct can_frame *frame, struct
gps_device_t *session)
+ "pgn %6d:%s \n", work->pgn, work->name);
+ session->driver.nmea2000.workpgn = (void *) work;
+ session->lexer.outbuflen = frame->can_dlc & 0x0f;
+- for (l2=0;l2<session->lexer.outbuflen;l2++) {
++ for (l2 = 0; l2 < session->lexer.outbuflen; l2++) {
+ session->lexer.outbuffer[l2]= frame->data[l2];
+ }
+ } else if ((frame->data[0] & 0x1f) == 0) {
+@@ -1659,7 +1678,7 @@ static void find_pgn(struct can_frame *frame, struct
gps_device_t *session)
+ #endif /* of #if NMEA2000_FAST_DEBUG */
+ session->lexer.inbuflen = 0;
+ session->driver.nmea2000.idx += 1;
+- for (l2=2;l2<8;l2++) {
++ for (l2 = 2; l2 < 8; l2++) {
+ session->lexer.inbuffer[session->lexer.inbuflen++] =
+ frame->data[l2];
+ }
+@@ -1668,7 +1687,7 @@ static void find_pgn(struct can_frame *frame, struct
gps_device_t *session)
+ } else if (frame->data[0] == session->driver.nmea2000.idx) {
+ unsigned int l2;
+
+- for (l2=1;l2<8;l2++) {
++ for (l2 = 1; l2 < 8; l2++) {
+ if (session->driver.nmea2000.fast_packet_len >
+ session->lexer.inbuflen) {
+
session->lexer.inbuffer[session->lexer.inbuflen++] =
+@@ -1689,7 +1708,7 @@ static void find_pgn(struct can_frame *frame, struct
gps_device_t *session)
+ session->driver.nmea2000.workpgn = (void *) work;
+ session->lexer.outbuflen =
+ session->driver.nmea2000.fast_packet_len;
+- for(l2 = 0;l2 < (unsigned
int)session->lexer.outbuflen;
++ for(l2 = 0; l2 < (unsigned
int)session->lexer.outbuflen;
+ l2++) {
+ session->lexer.outbuffer[l2] =
+ session->lexer.inbuffer[l2];
+@@ -1791,7 +1810,7 @@ int nmea2000_open(struct gps_device_t *session)
+ (void)strlcpy(interface_name, session->gpsdata.dev.path + 11,
+ sizeof(interface_name));
+ unit_ptr = NULL;
+- for (l=0;l<strnlen(interface_name,sizeof(interface_name));l++) {
++ for (l = 0; l < strnlen(interface_name, sizeof(interface_name)); l++) {
+ if (interface_name[l] == ':') {
+ unit_ptr = &interface_name[l+1];
+ interface_name[l] = 0;
+@@ -1908,7 +1927,7 @@ int nmea2000_open(struct gps_device_t *session)
+ interface_name,
+ MIN(sizeof(can_interface_name[0]), sizeof(interface_name)));
+ session->driver.nmea2000.unit_valid = false;
+- for (l=0;l<NMEA2000_UNITS;l++) {
++ for (l = 0; l < NMEA2000_UNITS; l++) {
+ nmea2000_units[can_net][l] = NULL;
+ }
+ }
+@@ -1931,8 +1950,8 @@ void nmea2000_close(struct gps_device_t *session)
+ if (session->driver.nmea2000.unit_valid) {
+ unsigned int l1, l2;
+
+- for (l1=0;l1<NMEA2000_NETS;l1++) {
+- for (l2=0;l2<NMEA2000_UNITS;l2++) {
++ for (l1 = 0; l1 < NMEA2000_NETS; l1++) {
++ for (l2 = 0; l2 < NMEA2000_UNITS; l2++) {
+ if (session == nmea2000_units[l1][l2]) {
+ session->driver.nmea2000.unit_valid = false;
+ session->driver.nmea2000.unit = 0;
diff -Nru gpsd-3.22/debian/patches/CVE-2025-67269.patch
gpsd-3.22/debian/patches/CVE-2025-67269.patch
--- gpsd-3.22/debian/patches/CVE-2025-67269.patch 1970-01-01
00:00:00.000000000 +0000
+++ gpsd-3.22/debian/patches/CVE-2025-67269.patch 2026-01-18
11:45:58.000000000 +0000
@@ -0,0 +1,167 @@
+From: "Gary E. Miller" <[email protected]>
+Date: Wed, 3 Dec 2025 19:04:03 -0800
+Subject: [PATCH] gpsd/packet.c: Fix integer underflow is malicious Navcom
+ packet
+
+Causes DoS. Fix issue 358
+origin: backport,
https://gitlab.com/gpsd/gpsd/-/commit/ffa1d6f40bca0b035fc7f5e563160ebb67199da7
+bug-debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1124799
+---
+ gpsd/packet.c | 81 +++++++++++++++++++++++++++++++++++++++++++++--------------
+ 1 file changed, 62 insertions(+), 19 deletions(-)
+
+diff --git a/gpsd/packet.c b/gpsd/packet.c
+index c7692cc..6ac5eca 100644
+--- a/gpsd/packet.c
++++ b/gpsd/packet.c
+@@ -891,15 +891,21 @@ static bool nextstate(struct gps_lexer_t *lexer,
unsigned char c)
+ #endif /* SIRF_ENABLE || SKYTRAQ_ENABLE */
+ #ifdef SIRF_ENABLE
+ case SIRF_LEADER_2:
+- lexer->length = (size_t) (c << 8);
++ // first part of length, MSB
++ lexer->length = (c & 0x7f) << 8;
++ if (lexer->length > MAX_PACKET_LENGTH) {
++ lexer->length = 0;
++ return character_pushback(lexer, GROUND_STATE);
++ } // else
+ lexer->state = SIRF_LENGTH_1;
+ break;
+ case SIRF_LENGTH_1:
+ lexer->length += c + 2;
+- if (lexer->length <= MAX_PACKET_LENGTH)
+- lexer->state = SIRF_PAYLOAD;
+- else
++ if (lexer->length > MAX_PACKET_LENGTH) {
++ lexer->length = 0;
+ return character_pushback(lexer, GROUND_STATE);
++ } // else
++ lexer->state = SIRF_PAYLOAD;
+ break;
+ case SIRF_PAYLOAD:
+ if (--lexer->length == 0)
+@@ -935,8 +941,10 @@ static bool nextstate(struct gps_lexer_t *lexer, unsigned
char c)
+ lexer->length += c;
+ if ( 0 == lexer->length )
+ return character_pushback(lexer, GROUND_STATE);
+- if (lexer->length > MAX_PACKET_LENGTH)
++ if (MAX_PACKET_LENGTH < lexer->length) {
++ lexer->length = 0;
+ return character_pushback(lexer, GROUND_STATE);
++ }
+ lexer->state = SKY_PAYLOAD;
+ break;
+ case SKY_PAYLOAD:
+@@ -1101,14 +1109,29 @@ static bool nextstate(struct gps_lexer_t *lexer,
unsigned char c)
+ return character_pushback(lexer, GROUND_STATE);
+ break;
+ case NAVCOM_LEADER_3:
++ // command ID
+ lexer->state = NAVCOM_ID;
+ break;
+ case NAVCOM_ID:
+- lexer->length = (size_t) c - 4;
++ /* Length LSB
++ * Navcom length includes command ID, length bytes. and checksum.
++ * So for more than just the payload length.
++ * Minimum 4 bytes */
++ if (4 > c) {
++ return character_pushback(lexer, GROUND_STATE);
++ }
++ lexer->length = c;
+ lexer->state = NAVCOM_LENGTH_1;
+ break;
+ case NAVCOM_LENGTH_1:
++ // Length USB. Navcom allows payload length up to 65,531
+ lexer->length += (c << 8);
++ // don't count ID, length and checksum in payload length
++ lexer->length -= 4;
++ if (MAX_PACKET_LENGTH < lexer->length) {
++ lexer->length = 0;
++ return character_pushback(lexer, GROUND_STATE);
++ } // else
+ lexer->state = NAVCOM_LENGTH_2;
+ break;
+ case NAVCOM_LENGTH_2:
+@@ -1223,13 +1246,15 @@ static bool nextstate(struct gps_lexer_t *lexer,
unsigned char c)
+ lexer->state = ZODIAC_RECOGNIZED;
+ break;
+ }
+- lexer->length *= 2; /* word count to byte count */
+- lexer->length += 2; /* checksum */
+- /* 10 bytes is the length of the Zodiac header */
+- if (lexer->length <= MAX_PACKET_LENGTH - 10)
+- lexer->state = ZODIAC_PAYLOAD;
+- else
++ lexer->length *= 2; // word count to byte count
++ lexer->length += 2; // checksum
++ // 10 bytes is the length of the Zodiac header
++ // no idea what Zodiac max length really is
++ if ((MAX_PACKET_LENGTH - 10) < lexer->length) {
++ lexer->length = 0;
+ return character_pushback(lexer, GROUND_STATE);
++ } // else
++ lexer->state = ZODIAC_PAYLOAD;
+ break;
+ case ZODIAC_PAYLOAD:
+ if (--lexer->length == 0)
+@@ -1255,10 +1280,17 @@ static bool nextstate(struct gps_lexer_t *lexer,
unsigned char c)
+ break;
+ case UBX_LENGTH_1:
+ lexer->length += (c << 8);
+- if (lexer->length <= MAX_PACKET_LENGTH)
++ if (0 == lexer->length) {
++ // no payload
++ lexer->state = UBX_CHECKSUM_A;
++ } else if (MAX_PACKET_LENGTH >= lexer->length) {
++ // normal size payload
+ lexer->state = UBX_LENGTH_2;
+- else
++ } else {
++ // bad length
++ lexer->length = 0;
+ return character_pushback(lexer, GROUND_STATE);
++ }
+ break;
+ case UBX_LENGTH_2:
+ lexer->state = UBX_PAYLOAD;
+@@ -1392,15 +1424,16 @@ static bool nextstate(struct gps_lexer_t *lexer,
unsigned char c)
+ lexer->state = GEOSTAR_MESSAGE_ID_2;
+ break;
+ case GEOSTAR_MESSAGE_ID_2:
+- lexer->length = (size_t)(c * 4);
++ lexer->length = c * 4;
+ lexer->state = GEOSTAR_LENGTH_1;
+ break;
+ case GEOSTAR_LENGTH_1:
+ lexer->length += (c << 8) * 4;
+- if (lexer->length <= MAX_PACKET_LENGTH)
+- lexer->state = GEOSTAR_LENGTH_2;
+- else
++ if (MAX_PACKET_LENGTH < lexer->length) {
++ lexer->length = 0;
+ return character_pushback(lexer, GROUND_STATE);
++ } // else
++ lexer->state = GEOSTAR_LENGTH_2;
+ break;
+ case GEOSTAR_LENGTH_2:
+ lexer->state = GEOSTAR_PAYLOAD;
+@@ -1645,7 +1678,17 @@ static bool nextstate(struct gps_lexer_t *lexer,
unsigned char c)
+ #endif /* STASH_ENABLE */
+ }
+
+- return true; /* no pushback */
++ /* Catch length overflow. Should not happen.
++ * length is size_t, so underflow looks like overflow too. */
++ if (MAX_PACKET_LENGTH <= lexer->length) {
++ GPSD_LOG(LOG_WARN, &lexer->errout,
++ "Too long: %zu state %u %s c x%x\n",
++ lexer->length, lexer->state, state_table[lexer->state], c);
++ // exit(255);
++ lexer->length = 0;
++ return character_pushback(lexer, GROUND_STATE);
++ }
++ return true; // no pushback
+ }
+
+ static void packet_accept(struct gps_lexer_t *lexer, int packet_type)
diff -Nru gpsd-3.22/debian/patches/series gpsd-3.22/debian/patches/series
--- gpsd-3.22/debian/patches/series 2022-09-11 14:45:05.000000000 +0000
+++ gpsd-3.22/debian/patches/series 2026-01-18 11:45:58.000000000 +0000
@@ -1,7 +1,7 @@
-# helper script, not an actual patch
-# add_patch.sh
7f30d88d0_gpsd-timebase.c-Don-t-compute-wrong-GPS-rollover-after-2020-10-23
full-systemd-support
gpsd_hotplug_rules_disable_generic_serial_converters
ignore-test-xgps_deps_check
gpsmon-gpsmon.c-Fix-silly-warning.patch
+CVE-2025-67268.patch
+CVE-2025-67269.patch
signature.asc
Description: This is a digitally signed message part.
--- End Message ---