Compare commits

..

2 Commits
c9 ... c9-beta

Author SHA1 Message Date
5b45fcd7da import CS gpsd-minimal-3.26.1-1.el9 2025-10-20 08:37:21 +00:00
eabdullin
a6ecc02c0b import CS gpsd-minimal-3.25-4.el9 2023-10-07 10:57:41 +00:00
4 changed files with 1 additions and 709 deletions

View File

@ -1,369 +0,0 @@
commit c65e1a51d2e33acbba93b4f2c73c595edabc21c0
Author: Gary E. Miller <gem@rellim.com>
Date: Tue Dec 2 19:36:04 2025 -0800
drivers/driver_nmea2000.c: Fix issue 356, skyview buffer overrun.
diff --git a/drivers/driver_nmea2000.c b/drivers/driver_nmea2000.c
index 71e04e134..3e40dc768 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;
+ 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;
- 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;
+ int svt = (int)(bu[offset + 11] & 0x0f);
- svt = (int)(bu[3+12*l1+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];
@@ -1792,7 +1811,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;
@@ -1909,7 +1928,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;
}
}
@@ -1933,8 +1952,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;

View File

@ -1,194 +0,0 @@
commit c46d5119736af455835dd2dca304a8cb651d03b9
Author: Gary E. Miller <gem@rellim.com>
Date: Wed Dec 3 19:04:03 2025 -0800
gpsd/packet.c: Fix integer underflow is malicious Navcom packet
Causes DoS. Fix issue 358
diff --git a/gpsd/packet.c b/gpsd/packet.c
index f9a7db8d0..0c2350072 100644
--- a/gpsd/packet.c
+++ b/gpsd/packet.c
@@ -1141,18 +1141,22 @@ static bool nextstate(struct gps_lexer_t *lexer, unsigned char c)
#endif // SIRF_ENABLE || SKYTRAQ_ENABLE
#ifdef SIRF_ENABLE
case SIRF_LEADER_2:
- // first part of length
- 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:
// second part of length
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 (0 == --lexer->length) {
@@ -1194,6 +1198,7 @@ static bool nextstate(struct gps_lexer_t *lexer, unsigned char c)
return character_pushback(lexer, GROUND_STATE);
}
if (MAX_PACKET_LENGTH < lexer->length) {
+ lexer->length = 0;
return character_pushback(lexer, GROUND_STATE);
}
lexer->state = SKY_PAYLOAD;
@@ -1376,14 +1381,29 @@ static bool nextstate(struct gps_lexer_t *lexer, unsigned char c)
}
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:
@@ -1510,11 +1530,11 @@ static bool nextstate(struct gps_lexer_t *lexer, unsigned char c)
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->state = ZODIAC_PAYLOAD;
- } else {
+ 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 (0 == --lexer->length) {
@@ -1549,6 +1569,7 @@ static bool nextstate(struct gps_lexer_t *lexer, unsigned char c)
lexer->state = UBX_LENGTH_2;
} else {
// bad length
+ lexer->length = 0;
return character_pushback(lexer, GROUND_STATE);
}
break;
@@ -1604,6 +1625,7 @@ static bool nextstate(struct gps_lexer_t *lexer, unsigned char c)
lexer->length += (c << 8);
if (MAX_PACKET_LENGTH <= lexer->length) {
// bad length
+ lexer->length = 0;
return character_pushback(lexer, GROUND_STATE);
} // else
@@ -1841,16 +1863,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 (MAX_PACKET_LENGTH >= lexer->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;
@@ -2160,6 +2182,16 @@ static bool nextstate(struct gps_lexer_t *lexer, unsigned char c)
#endif // STASH_ENABLE
}
+ /* 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
}
commit 90f5558a8dc364bed8e2f3e2e4ecdd84f04dde46
Author: Gary E. Miller <gem@rellim.com>
Date: Thu Dec 4 13:56:43 2025 -0800
gpsd/packet.c: Fix a logic hole in previous commit.
Before your reject 0x103 and well as 0x03. Now only rejects, really,
when length less than 4.
diff --git a/gpsd/packet.c b/gpsd/packet.c
index 0c2350072..99109e388 100644
--- a/gpsd/packet.c
+++ b/gpsd/packet.c
@@ -1385,19 +1385,20 @@ static bool nextstate(struct gps_lexer_t *lexer, unsigned char c)
lexer->state = NAVCOM_ID;
break;
case NAVCOM_ID:
- /* 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);
- }
+ // Length LSB
lexer->length = c;
lexer->state = NAVCOM_LENGTH_1;
break;
case NAVCOM_LENGTH_1:
- // Length USB. Navcom allows payload length up to 65,531
+ /* Length USB. Navcom allows payload length up to 32767 - 4
+ * Navcom length includes command ID, length bytes. and checksum.
+ * More than just the payload length.
+ * Minimum 4 bytes */
lexer->length += (c << 8);
+ if (4 >lexer->length ) {
+ // too short
+ return character_pushback(lexer, GROUND_STATE);
+ }
// don't count ID, length and checksum in payload length
lexer->length -= 4;
if (MAX_PACKET_LENGTH < lexer->length) {

View File

@ -1,130 +0,0 @@
commit 5581ba196d826a984fbfaf792b7d58535f9911ce
Author: Gary E. Miller <gem@rellim.com>
Date: Wed Jul 1 17:55:57 2026 -0700
clients/gpsprof.py.in: Quote double quotes in title.
Someone could use the double quote to break out of the
string and add gnuplot commnds.
For issue 404.
Reported by: CuB3y0nd, and Wade Sparks <wsparks@vulncheck.com>
diff --git a/clients/gpsprof.py.in b/clients/gpsprof.py.in
index 5c18f50ff..261e72665 100644
--- a/clients/gpsprof.py.in
+++ b/clients/gpsprof.py.in
@@ -198,6 +198,10 @@ class plotter(object):
if 'subtype' in self.device:
desc += "\\n%s" % self.device['subtype']
+ # escape ", and \n, for gnuplot, to not break strings
+ desc = desc.replace('"', '\\042')
+ desc = desc.replace('\n', '')
+
return desc
def collect(self, verb, log_fp=None):
@@ -1262,10 +1266,10 @@ if __name__ == '__main__':
# Ship the plot to standard output
if not options.title:
options.title = plot.whatami()
- # escape " for gnuplot
- options.title = options.title.replace('"', '\\"')
if options.subtitle:
options.title += '\\n' + options.subtitle
+ # escape " for gnuplot, to not break strings
+ options.title = options.title.replace('"', '\\042')
term_opts = ""
truecolor_terms = ['png', 'sixelgd', 'wxt']
if options.terminal in truecolor_terms:
commit 1a6bb7bcbdf58aa940132e630870af061dc88537
Author: Gary E. Miller <gem@rellim.com>
Date: Tue Jul 7 13:41:54 2026 -0700
clients/gpsprof.py.in: Quote back ticks in title.
Someone could use the back tick to break out of the string and add
gnuplot commnds.
For issue 404.
Reported by: CuB3y0nd, and Wade Sparks <wsparks@vulncheck.com>
diff --git a/clients/gpsprof.py.in b/clients/gpsprof.py.in
index 261e72665..202214769 100644
--- a/clients/gpsprof.py.in
+++ b/clients/gpsprof.py.in
@@ -198,8 +198,9 @@ class plotter(object):
if 'subtype' in self.device:
desc += "\\n%s" % self.device['subtype']
- # escape ", and \n, for gnuplot, to not break strings
+ # escape ", `, and \n, for gnuplot, to not break strings
desc = desc.replace('"', '\\042')
+ desc = desc.replace('`', '\\140')
desc = desc.replace('\n', '')
return desc
@@ -1268,8 +1269,9 @@ if __name__ == '__main__':
options.title = plot.whatami()
if options.subtitle:
options.title += '\\n' + options.subtitle
- # escape " for gnuplot, to not break strings
+ # escape ", and`, for gnuplot, to not break strings
options.title = options.title.replace('"', '\\042')
+ options.title = options.title.replace('"', '\\140')
term_opts = ""
truecolor_terms = ['png', 'sixelgd', 'wxt']
if options.terminal in truecolor_terms:
commit 4c06658e988f4ced1a7a574ce082a22ef625df56
Author: Gary E. Miller <gem@rellim.com>
Date: Tue Jul 7 14:23:56 2026 -0700
clients/gpsprof.py.in: Quote back ticks in title.
Second try. Also quote "terminal".
Someone could use the back tick to break out of the string and add
gnuplot commnds.
For issue 404.
Reported by: CuB3y0nd, and Wade Sparks <wsparks@vulncheck.com>
diff --git a/clients/gpsprof.py.in b/clients/gpsprof.py.in
index 202214769..e91367ee3 100644
--- a/clients/gpsprof.py.in
+++ b/clients/gpsprof.py.in
@@ -200,7 +200,7 @@ class plotter(object):
# escape ", `, and \n, for gnuplot, to not break strings
desc = desc.replace('"', '\\042')
- desc = desc.replace('`', '\\140')
+ desc = desc.replace("\x60", '\\140')
desc = desc.replace('\n', '')
return desc
@@ -1271,13 +1271,19 @@ if __name__ == '__main__':
options.title += '\\n' + options.subtitle
# escape ", and`, for gnuplot, to not break strings
options.title = options.title.replace('"', '\\042')
- options.title = options.title.replace('"', '\\140')
+ options.title = options.title.replace("\x60", '\\140')
term_opts = ""
truecolor_terms = ['png', 'sixelgd', 'wxt']
if options.terminal in truecolor_terms:
term_opts = 'truecolor'
- sys.stdout.write("set terminal %s size 800,950 %s\n"
- "set termoption enhanced\n"
+
+ # escape ", `, and \n, for gnuplot, to not break strings
+ options.terminal = options.terminal.replace('"', '\\042')
+ options.terminal = options.terminal.replace("\x60", '\\140')
+ options.terminal = options.terminal.replace('\n', '')
+
+ sys.stdout.write('set terminal "%s" size 800,950 %s\n'
+ 'set termoption enhanced\n'
% (options.terminal, term_opts))
# double quotes on title so \n is parsed by gnuplot
sys.stdout.write('set title noenhanced "%s\\n\\n"\n' % options.title)

View File

@ -5,7 +5,7 @@
Name: gpsd-minimal
Version: 3.26.1
Release: 2%{?dist}.1
Release: 1%{?dist}
Epoch: 1
Summary: Service daemon for mediating access to a GPS
@ -16,13 +16,6 @@ Source0: https://download-mirror.savannah.gnu.org/releases/gpsd/gpsd-%{ve
Source1: https://github.com/SCons/scons/archive/%{scons_ver}/scons-%{scons_ver}.tar.gz
Source11: gpsd.sysconfig
# fix buffer overflow in NMEA2000 driver
Patch1: gpsd-cve-2025-67268.patch
# fix integer underflow in handling of Navcom packets
Patch2: gpsd-cve-2025-67269.patch
# fix command injection in gpsprof
Patch3: gpsd-cve-2026-58459.patch
BuildRequires: gcc
BuildRequires: dbus-devel
BuildRequires: ncurses-devel
@ -61,7 +54,6 @@ This package contains various clients using gpsd.
%prep
%setup -q -n gpsd-%{version} -a 1
%autopatch -p1
# add note to man pages about limited support
sed -i ':a;$!{N;ba};s|\(\.SH "[^"]*"\)|.SH "NOTE"\n%{note1}\n%{note2}\n\1|3' \
@ -219,13 +211,6 @@ rm -rf %{buildroot}%{_docdir}/gpsd
%{_mandir}/man1/zerk.1*
%changelog
* Mon Jul 13 2026 Miroslav Lichvar <mlichvar@redhat.com> - 1:3.26.1-2.el9_8.1
- fix command injection in gpsprof (CVE-2026-58459)
* Mon Jan 19 2026 Miroslav Lichvar <mlichvar@redhat.com> - 1:3.26.1-2
- fix buffer overflow in NMEA2000 driver (CVE-2025-67268)
- fix integer underflow in handling of Navcom packets (CVE-2025-67269)
* Mon May 19 2025 Miroslav Lichvar <mlichvar@redhat.com> - 1:3.26.1-1
- update to 3.26.1 (RHEL-90132)