Compare commits
No commits in common. "c9" and "c10s" have entirely different histories.
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,2 +1,2 @@
|
||||
SOURCES/gpsd-3.26.1.tar.gz
|
||||
SOURCES/scons-4.5.2.tar.gz
|
||||
/gpsd-3.25.tar.gz
|
||||
/scons-4.5.2.tar.gz
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
5bed7e4eca1874309e0c9de82f8f8354cf09dffb SOURCES/gpsd-3.26.1.tar.gz
|
||||
61b59e617c739051f48cdd45b7638d8831b13d73 SOURCES/scons-4.5.2.tar.gz
|
||||
@ -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;
|
||||
@ -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) {
|
||||
6
gating.yaml
Normal file
6
gating.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
--- !Policy
|
||||
product_versions:
|
||||
- rhel-9
|
||||
decision_context: osci_compose_gate
|
||||
rules:
|
||||
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}
|
||||
84
gpsd-busywait.patch
Normal file
84
gpsd-busywait.patch
Normal file
@ -0,0 +1,84 @@
|
||||
commit e5ba7aa2af74fd22ebbd5c4a6624edcf983863de
|
||||
Author: Michal Schmidt <mschmidt@redhat.com>
|
||||
Date: Fri Aug 4 16:53:01 2023 +0200
|
||||
|
||||
gps/gps.py.in: no busy-waiting when reading from gpsd socket
|
||||
|
||||
ubxtool keeps one CPU 100% busy while it waits for data to read from the
|
||||
gpsd socket. Running it under strace showed that it calls select() with
|
||||
zero timeout in a loop:
|
||||
|
||||
...
|
||||
11:02:34.049629 pselect6(4, [3], [], [], {tv_sec=0, tv_nsec=0}, NULL) = 0 (Timeout)
|
||||
11:02:34.049649 pselect6(4, [3], [], [], {tv_sec=0, tv_nsec=0}, NULL) = 0 (Timeout)
|
||||
11:02:34.049670 pselect6(4, [3], [], [], {tv_sec=0, tv_nsec=0}, NULL) = 0 (Timeout)
|
||||
...
|
||||
|
||||
The busy waiting can be eliminated by passing the actual timeout value
|
||||
to select(). In the reading loop in gps.py, the remaining time can be
|
||||
easily calculated and passed as the argument to the self.ser.waiting()
|
||||
function (which is basically a select() wrapper).
|
||||
|
||||
Fixing this problem exposed a bug in how the received bytes are decoded.
|
||||
decode_func may not consume all input at once. Consumable input may be
|
||||
left in self.out until decode_func returns zero, indicating that it
|
||||
could not process any more input. So decode_func must be called in a
|
||||
loop each time a buffer is received from the socket. The busy waiting
|
||||
was hiding this issue, because decode_func was being called all the
|
||||
time.
|
||||
|
||||
The "elif self.input_is_device:" branch probably needs similar
|
||||
treatment, but I am testing only the gpsd usecase.
|
||||
|
||||
diff --git a/gps/gps.py.in b/gps/gps.py.in
|
||||
index 623a750a0..14d7707ab 100644
|
||||
--- a/gps/gps.py.in
|
||||
+++ b/gps/gps.py.in
|
||||
@@ -384,10 +384,11 @@ class gps_io(object):
|
||||
if self.gpsd_host is not None:
|
||||
# gpsd input
|
||||
start = monotonic()
|
||||
- while (monotonic() - start) < input_wait:
|
||||
+ remaining_time = input_wait
|
||||
+ while remaining_time > 0:
|
||||
# First priority is to be sure the input buffer is read.
|
||||
# This is to prevent input buffer overuns
|
||||
- if 0 < self.ser.waiting():
|
||||
+ if 0 < self.ser.waiting(remaining_time):
|
||||
# We have serial input waiting, get it
|
||||
# No timeout possible
|
||||
# RTCM3 JSON can be over 4.4k long, so go big
|
||||
@@ -397,17 +398,22 @@ class gps_io(object):
|
||||
raw_fd.write(polybytes(new_out))
|
||||
self.out += new_out
|
||||
|
||||
- consumed = decode_func(self.out)
|
||||
- # TODO: the decoder shall return a some current
|
||||
- # statement_identifier # to fill last_statement_identifier
|
||||
- last_statement_identifier = None
|
||||
- #
|
||||
- self.out = self.out[consumed:]
|
||||
- if ((expect_statement_identifier and
|
||||
- (expect_statement_identifier ==
|
||||
- last_statement_identifier))):
|
||||
- # Got what we were waiting for. Done?
|
||||
- ret_code = 0
|
||||
+ while True:
|
||||
+ consumed = decode_func(self.out)
|
||||
+ if consumed == 0:
|
||||
+ break
|
||||
+ # TODO: the decoder shall return a some current
|
||||
+ # statement_identifier # to fill last_statement_identifier
|
||||
+ last_statement_identifier = None
|
||||
+ #
|
||||
+ self.out = self.out[consumed:]
|
||||
+ if ((expect_statement_identifier and
|
||||
+ (expect_statement_identifier ==
|
||||
+ last_statement_identifier))):
|
||||
+ # Got what we were waiting for. Done?
|
||||
+ ret_code = 0
|
||||
+
|
||||
+ remaining_time = start + input_wait - monotonic()
|
||||
|
||||
elif self.input_is_device:
|
||||
# input is a serial device
|
||||
356
gpsd-ipv6.patch
Normal file
356
gpsd-ipv6.patch
Normal file
@ -0,0 +1,356 @@
|
||||
commit 5c080c35fc3d981172a5e4af34d0d92854a5433a
|
||||
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
||||
Date: Tue Jul 25 11:01:14 2023 +0200
|
||||
|
||||
libgps/netlib.c: Rework enabling non-block and make binding configurable.
|
||||
|
||||
Instead of accepting SOCK_NONBLOCK as flags in netlib_connectsock1()
|
||||
specify if the non-blocking mode should be enabled after or before
|
||||
connect().
|
||||
|
||||
Also add a boolean parameter to the function to select between connect()
|
||||
and bind() instead of hardcoding it for TCP vs UDP, which will allow
|
||||
connecting to UDP ports in gps2udp.
|
||||
|
||||
diff --git a/gpsd/libgpsd_core.c b/gpsd/libgpsd_core.c
|
||||
index 47ee5d57e..341e8b80c 100644
|
||||
--- a/gpsd/libgpsd_core.c
|
||||
+++ b/gpsd/libgpsd_core.c
|
||||
@@ -561,7 +561,6 @@ int gpsd_open(struct gps_device_t *session)
|
||||
char server[GPS_PATH_MAX], *host, *port, *device;
|
||||
socket_t dsock;
|
||||
char addrbuf[50]; // INET6_ADDRSTRLEN
|
||||
- int sock_opt;
|
||||
|
||||
session->sourcetype = SOURCE_TCP;
|
||||
(void)strlcpy(server, session->gpsdata.dev.path + 6, sizeof(server));
|
||||
@@ -576,15 +575,9 @@ int gpsd_open(struct gps_device_t *session)
|
||||
GPSD_LOG(LOG_PROG, &session->context->errout,
|
||||
"CORE: opening TCP feed at %s, port %s.\n", host,
|
||||
port);
|
||||
-#if defined(SOCK_NONBLOCK)
|
||||
- sock_opt = SOCK_NONBLOCK;
|
||||
-#else
|
||||
- // macOS has no SOCK_NONBLOCK
|
||||
- sock_opt = 0;
|
||||
-#endif
|
||||
// open non-blocking
|
||||
dsock = netlib_connectsock1(AF_UNSPEC, host, port, "tcp",
|
||||
- sock_opt, addrbuf, sizeof(addrbuf));
|
||||
+ 1, false, addrbuf, sizeof(addrbuf));
|
||||
if (0 > dsock) {
|
||||
GPSD_LOG(LOG_ERROR, &session->context->errout,
|
||||
"CORE: TCP %s IP %s, open error %s(%d).\n",
|
||||
@@ -614,7 +607,8 @@ int gpsd_open(struct gps_device_t *session)
|
||||
GPSD_LOG(LOG_PROG, &session->context->errout,
|
||||
"CORE: opening UDP feed at %s, port %s.\n", host,
|
||||
port);
|
||||
- if (0 > (dsock = netlib_connectsock(AF_UNSPEC, host, port, "udp"))) {
|
||||
+ if (0 > (dsock = netlib_connectsock1(AF_UNSPEC, host, port, "udp",
|
||||
+ 0, true, NULL, 0))) {
|
||||
GPSD_LOG(LOG_ERROR, &session->context->errout,
|
||||
"CORE: UDP device open error %s(%d).\n",
|
||||
netlib_errstr(dsock), dsock);
|
||||
diff --git a/gpsd/net_ntrip.c b/gpsd/net_ntrip.c
|
||||
index 8241995ae..d89bdc1f9 100644
|
||||
--- a/gpsd/net_ntrip.c
|
||||
+++ b/gpsd/net_ntrip.c
|
||||
@@ -856,7 +856,8 @@ static int ntrip_reconnect(struct gps_device_t *device)
|
||||
device->gpsdata.dev.path);
|
||||
dsock = netlib_connectsock1(AF_UNSPEC, device->ntrip.stream.host,
|
||||
device->ntrip.stream.port,
|
||||
- "tcp", SOCK_NONBLOCK, addrbuf, sizeof(addrbuf));
|
||||
+ "tcp", 1, false,
|
||||
+ addrbuf, sizeof(addrbuf));
|
||||
device->gpsdata.gps_fd = dsock;
|
||||
// nonblocking means we have the fd, but the connection is not
|
||||
// finished yet. Connection may fail, later.
|
||||
diff --git a/include/gpsd.h b/include/gpsd.h
|
||||
index 0f6b731eb..2f3260c1e 100644
|
||||
--- a/include/gpsd.h
|
||||
+++ b/include/gpsd.h
|
||||
@@ -1002,7 +1002,7 @@ extern void gpsd_clear_data(struct gps_device_t *);
|
||||
extern socket_t netlib_connectsock(int, const char *, const char *,
|
||||
const char *);
|
||||
extern socket_t netlib_connectsock1(int, const char *, const char *,
|
||||
- const char *, int,
|
||||
+ const char *, int, bool,
|
||||
char *, size_t);
|
||||
// end FIXME
|
||||
extern socket_t netlib_localsocket(const char *, int);
|
||||
diff --git a/libgps/netlib.c b/libgps/netlib.c
|
||||
index e4e763025..5f553fe10 100644
|
||||
--- a/libgps/netlib.c
|
||||
+++ b/libgps/netlib.c
|
||||
@@ -55,8 +55,10 @@
|
||||
* host - host to connect to
|
||||
* service -- aka port
|
||||
* protocol
|
||||
- * flags -- can be SOCK_NONBLOCK for non-blocking connect
|
||||
- * Note: macOS does not have SOCK_NONBLOCK
|
||||
+ * nonblock -- 1 sets the socket as non-blocking before connect() if
|
||||
+ * SOCK_NONBLOCK is supported,
|
||||
+ * >1 sets the socket as non-blocking after connect()
|
||||
+ * bind_me -- call bind() on the socket instead of connect()
|
||||
* addrbuf -- 50 char buf to put string of IP address conencting
|
||||
* INET6_ADDRSTRLEN
|
||||
* addrbuf_sz -- sizeof(adddrbuf)
|
||||
@@ -70,16 +72,15 @@
|
||||
* less than zero on error (NL_*)
|
||||
*/
|
||||
socket_t netlib_connectsock1(int af, const char *host, const char *service,
|
||||
- const char *protocol, int flags,
|
||||
+ const char *protocol, int nonblock, bool bind_me,
|
||||
char *addrbuf, size_t addrbuf_sz)
|
||||
{
|
||||
struct protoent *ppe;
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *result = NULL;
|
||||
struct addrinfo *rp;
|
||||
- int ret, type, proto, one;
|
||||
+ int ret, flags, type, proto, one;
|
||||
socket_t s;
|
||||
- bool bind_me;
|
||||
|
||||
if (NULL != addrbuf) {
|
||||
addrbuf[0] = '\0';
|
||||
@@ -97,9 +98,6 @@ socket_t netlib_connectsock1(int af, const char *host, const char *service,
|
||||
return NL_NOPROTO;
|
||||
}
|
||||
|
||||
- /* we probably ought to pass this in as an explicit flag argument */
|
||||
- bind_me = (SOCK_DGRAM == type);
|
||||
-
|
||||
memset(&hints, 0, sizeof(struct addrinfo));
|
||||
hints.ai_family = af;
|
||||
hints.ai_socktype = type;
|
||||
@@ -107,6 +105,15 @@ socket_t netlib_connectsock1(int af, const char *host, const char *service,
|
||||
if (bind_me) {
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
}
|
||||
+#if defined(SOCK_NONBLOCK)
|
||||
+ flags = nonblock == 1 ? SOCK_NONBLOCK : 0;
|
||||
+#else
|
||||
+ // macOS has no SOCK_NONBLOCK
|
||||
+ flags = 0;
|
||||
+ if (nonblock == 1)
|
||||
+ nonblock = 2;
|
||||
+#endif
|
||||
+
|
||||
// FIXME: need a way to bypass these DNS calls if host is an IP.
|
||||
if ((ret = getaddrinfo(host, service, &hints, &result))) {
|
||||
// result is unchanged on error, so we need to have set it to NULL
|
||||
@@ -219,13 +226,15 @@ socket_t netlib_connectsock1(int af, const char *host, const char *service,
|
||||
sizeof(one));
|
||||
}
|
||||
|
||||
- // set socket to noblocking
|
||||
+ if (nonblock > 1) {
|
||||
+ // set socket to noblocking
|
||||
#ifdef HAVE_FCNTL
|
||||
- (void)fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK);
|
||||
+ (void)fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK);
|
||||
#elif defined(HAVE_WINSOCK2_H)
|
||||
- u_long one1 = 1;
|
||||
- (void)ioctlsocket(s, FIONBIO, &one1);
|
||||
+ u_long one1 = 1;
|
||||
+ (void)ioctlsocket(s, FIONBIO, &one1);
|
||||
#endif
|
||||
+ }
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -235,7 +244,7 @@ socket_t netlib_connectsock1(int af, const char *host, const char *service,
|
||||
socket_t netlib_connectsock(int af, const char *host, const char *service,
|
||||
const char *protocol)
|
||||
{
|
||||
- return netlib_connectsock1(af, host, service, protocol, 0, NULL, 0);
|
||||
+ return netlib_connectsock1(af, host, service, protocol, 2, false, NULL, 0);
|
||||
}
|
||||
|
||||
// Convert NL_* error code to a string
|
||||
|
||||
commit fd6682a6ffd0a5d4d640839422274b582ba38e72
|
||||
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
||||
Date: Tue Jul 25 11:08:19 2023 +0200
|
||||
|
||||
clients/gps2udp.c: Switch to netlib_connectsock1().
|
||||
|
||||
Use netlib_connectsock1() to avoid using obsolete gethostbyname() and
|
||||
support IPv6.
|
||||
|
||||
diff --git a/clients/gps2udp.c b/clients/gps2udp.c
|
||||
index 2d9c6033d..541054d8f 100644
|
||||
--- a/clients/gps2udp.c
|
||||
+++ b/clients/gps2udp.c
|
||||
@@ -21,7 +21,6 @@
|
||||
#ifdef HAVE_GETOPT_LONG
|
||||
#include <getopt.h> // for getopt_long()
|
||||
#endif
|
||||
-#include <netdb.h> /* for gethostbyname() */
|
||||
#include <netinet/in.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
@@ -50,7 +49,6 @@ static struct gps_data_t gpsdata;
|
||||
|
||||
/* UDP socket variables */
|
||||
#define MAX_UDP_DEST 5
|
||||
-static struct sockaddr_in remote[MAX_UDP_DEST];
|
||||
static int sock[MAX_UDP_DEST];
|
||||
static int udpchannel;
|
||||
|
||||
@@ -128,12 +126,10 @@ static int send_udp(char *nmeastring, size_t ind)
|
||||
|
||||
// send message on udp channel
|
||||
for (channel=0; channel < udpchannel; channel ++) {
|
||||
- ssize_t status = sendto(sock[channel],
|
||||
- buffer,
|
||||
- ind,
|
||||
- 0,
|
||||
- (struct sockaddr *)&remote[channel],
|
||||
- (int)sizeof(remote));
|
||||
+ ssize_t status = send(sock[channel],
|
||||
+ buffer,
|
||||
+ ind,
|
||||
+ 0);
|
||||
if (status < (ssize_t)ind) {
|
||||
(void)fprintf(stderr, "gps2udp: failed to send [%s] \n",
|
||||
buffer);
|
||||
@@ -152,9 +148,6 @@ static int open_udp(char **hostport)
|
||||
for (channel = 0; channel < udpchannel; channel++) {
|
||||
char *hostname = NULL;
|
||||
char *portname = NULL;
|
||||
- char *endptr = NULL;
|
||||
- int portnum;
|
||||
- struct hostent *hp;
|
||||
|
||||
if (NULL == hostport[channel]) {
|
||||
// pacify coverity
|
||||
@@ -171,32 +164,13 @@ static int open_udp(char **hostport)
|
||||
return -1;
|
||||
}
|
||||
|
||||
- errno = 0;
|
||||
- portnum = (int)strtol(portname, &endptr, 10);
|
||||
- if (1 > portnum || 65535 < portnum || '\0' != *endptr || 0 != errno) {
|
||||
- (void)fprintf(stderr, "gps2udp: syntax is [-u hostname:port] "
|
||||
- "[%s] is not a valid port number\n", portname);
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- sock[channel]= socket(AF_INET, SOCK_DGRAM, 0);
|
||||
+ sock[channel] = netlib_connectsock1(AF_UNSPEC, hostname, portname, "udp",
|
||||
+ 0, false, NULL, 0);
|
||||
if (0 > sock[channel]) {
|
||||
- (void)fprintf(stderr, "gps2udp: error creating UDP socket\n");
|
||||
+ (void)fprintf(stderr, "gps2udp: error creating UDP socket: %s\n",
|
||||
+ netlib_errstr(sock[channel]));
|
||||
return -1;
|
||||
}
|
||||
-
|
||||
- remote[channel].sin_family = (sa_family_t)AF_INET;
|
||||
- hp = gethostbyname(hostname);
|
||||
- if (NULL == hp) {
|
||||
- (void)fprintf(stderr,
|
||||
- "gps2udp: syntax is [-u hostname:port] [%s]"
|
||||
- " is not a valid hostname\n",
|
||||
- hostname);
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- memcpy( &remote[channel].sin_addr, hp->h_addr_list[0], hp->h_length);
|
||||
- remote[channel].sin_port = htons((in_port_t)portnum);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
commit 749be8acce27f16d74ba727f4819f3e49602882a
|
||||
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
||||
Date: Tue Jul 25 11:10:39 2023 +0200
|
||||
|
||||
clients/lcdgps.c: Switch to netlib_connectsock1().
|
||||
|
||||
Use netlib_connectsock1() to avoid using obsolete gethostbyname() and
|
||||
support IPv6.
|
||||
|
||||
diff --git a/clients/lcdgps.c b/clients/lcdgps.c
|
||||
index 7d0ee6bc8..b311882b0 100644
|
||||
--- a/clients/lcdgps.c
|
||||
+++ b/clients/lcdgps.c
|
||||
@@ -21,11 +21,12 @@
|
||||
*/
|
||||
|
||||
#define LCDDHOST "localhost"
|
||||
-#define LCDDPORT 13666
|
||||
+#define LCDDPORT "13666"
|
||||
|
||||
#define CLIMB 3
|
||||
|
||||
#include "../include/gpsd_config.h" /* must be before all includes */
|
||||
+#include "../include/gpsd.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
@@ -33,7 +34,6 @@
|
||||
#include <getopt.h> // for getopt_long()
|
||||
#endif
|
||||
#include <math.h>
|
||||
-#include <netdb.h> /* for gethostbyname() */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -259,9 +259,6 @@ static void usage( char *prog)
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
- int rc;
|
||||
- struct sockaddr_in localAddr, servAddr;
|
||||
- struct hostent *h;
|
||||
const char *optstring = "?hl:su:V";
|
||||
int n;
|
||||
#ifdef HAVE_GETOPT_LONG
|
||||
@@ -390,41 +387,10 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* Connect to LCDd */
|
||||
- h = gethostbyname(LCDDHOST);
|
||||
- if (h==NULL) {
|
||||
- printf("%s: unknown host '%s'\n",argv[0],LCDDHOST);
|
||||
- exit(EXIT_FAILURE);
|
||||
- }
|
||||
-
|
||||
- servAddr.sin_family = h->h_addrtype;
|
||||
- memcpy((char *) &servAddr.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
|
||||
- servAddr.sin_port = htons(LCDDPORT);
|
||||
-
|
||||
- /* create socket */
|
||||
- sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
- if (BAD_SOCKET(sd)) {
|
||||
- perror("cannot open socket ");
|
||||
- exit(EXIT_FAILURE);
|
||||
- }
|
||||
-
|
||||
- /* bind any port number */
|
||||
- localAddr.sin_family = AF_INET;
|
||||
- localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
- localAddr.sin_port = htons(0);
|
||||
-
|
||||
- /* coverity[uninit_use_in_call] */
|
||||
- rc = bind(sd, (struct sockaddr *) &localAddr, sizeof(localAddr));
|
||||
- if (rc == -1) {
|
||||
- printf("%s: cannot bind port TCP %d\n",argv[0],LCDDPORT);
|
||||
- perror("error ");
|
||||
- exit(EXIT_FAILURE);
|
||||
- }
|
||||
+ sd = netlib_connectsock1(AF_UNSPEC, LCDDHOST, LCDDPORT, "tcp", 0, false, NULL, 0);
|
||||
+ if (0 > sd) {
|
||||
|
||||
- /* connect to server */
|
||||
- /* coverity[uninit_use_in_call] */
|
||||
- rc = connect(sd, (struct sockaddr *) &servAddr, sizeof(servAddr));
|
||||
- if (rc == -1) {
|
||||
- perror("cannot connect ");
|
||||
+ (void)fprintf(stderr, "lcdgps: cannot connect: %s\n", netlib_errstr(sd));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
%global note2 https://access.redhat.com/support/policy/gpsd-support for more details.
|
||||
|
||||
Name: gpsd-minimal
|
||||
Version: 3.26.1
|
||||
Release: 1%{?dist}.1
|
||||
Version: 3.25
|
||||
Release: 4%{?dist}
|
||||
Epoch: 1
|
||||
Summary: Service daemon for mediating access to a GPS
|
||||
|
||||
@ -16,10 +16,12 @@ 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
|
||||
# add missing IPv6 support
|
||||
Patch1: gpsd-ipv6.patch
|
||||
# fix some issues reported by coverity and shellcheck
|
||||
Patch2: gpsd-scanfixes.patch
|
||||
# fix busy wait when reading from gpsd socket
|
||||
Patch3: gpsd-busywait.patch
|
||||
|
||||
BuildRequires: gcc
|
||||
BuildRequires: dbus-devel
|
||||
@ -59,7 +61,9 @@ This package contains various clients using gpsd.
|
||||
|
||||
%prep
|
||||
%setup -q -n gpsd-%{version} -a 1
|
||||
%autopatch -p1
|
||||
%patch -P 1 -p1 -b .ipv6
|
||||
%patch -P 2 -p1 -b .scanfixes
|
||||
%patch -P 3 -p1 -b .busywait
|
||||
|
||||
# add note to man pages about limited support
|
||||
sed -i ':a;$!{N;ba};s|\(\.SH "[^"]*"\)|.SH "NOTE"\n%{note1}\n%{note2}\n\1|3' \
|
||||
@ -183,7 +187,6 @@ rm -rf %{buildroot}%{_docdir}/gpsd
|
||||
%{_bindir}/gpscsv
|
||||
%{_bindir}/gpsdebuginfo
|
||||
%{_bindir}/gpsdecode
|
||||
%{_bindir}/gpslogntp
|
||||
%{_bindir}/gpspipe
|
||||
%{_bindir}/gpsplot
|
||||
%{_bindir}/gpsprof
|
||||
@ -201,7 +204,6 @@ rm -rf %{buildroot}%{_docdir}/gpsd
|
||||
%{_mandir}/man1/gpscsv.1*
|
||||
%{_mandir}/man1/gpsdebuginfo.1*
|
||||
%{_mandir}/man1/gpsdecode.1*
|
||||
%{_mandir}/man1/gpslogntp.1*
|
||||
%{_mandir}/man1/gpspipe.1*
|
||||
%{_mandir}/man1/gpsplot.1*
|
||||
%{_mandir}/man1/gpsprof.1*
|
||||
@ -217,13 +219,6 @@ rm -rf %{buildroot}%{_docdir}/gpsd
|
||||
%{_mandir}/man1/zerk.1*
|
||||
|
||||
%changelog
|
||||
* Mon Jan 05 2026 Miroslav Lichvar <mlichvar@redhat.com> - 1:3.26.1-1.el9_7.1
|
||||
- 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)
|
||||
|
||||
* Tue Aug 08 2023 Miroslav Lichvar <mlichvar@redhat.com> - 1:3.25-4
|
||||
- fix busy wait when reading from gpsd socket
|
||||
|
||||
188
gpsd-scanfixes.patch
Normal file
188
gpsd-scanfixes.patch
Normal file
@ -0,0 +1,188 @@
|
||||
commit 651d505d2b075b9bd87729d2d5d155c29c03fbc1
|
||||
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
||||
Date: Mon Jul 31 15:46:16 2023 +0200
|
||||
|
||||
devtools/tablegen.py: Fix typo in structname.
|
||||
|
||||
diff --git a/devtools/tablegen.py b/devtools/tablegen.py
|
||||
index 7851fceca..3feb64b9e 100755
|
||||
--- a/devtools/tablegen.py
|
||||
+++ b/devtools/tablegen.py
|
||||
@@ -129,7 +129,7 @@ def make_driver_code(wfp):
|
||||
continue
|
||||
offset = offsets[i].split('-')[0]
|
||||
if arrayname:
|
||||
- target = "%s.%s[i].%s" % (structnme, arrayname, name)
|
||||
+ target = "%s.%s[i].%s" % (structname, arrayname, name)
|
||||
offset = "a + " + offset
|
||||
else:
|
||||
target = "%s.%s" % (structname, name)
|
||||
|
||||
commit db2a00f7ee4e66ee57ff66e84cec664444c26d8f
|
||||
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
||||
Date: Mon Jul 31 15:47:10 2023 +0200
|
||||
|
||||
gpsd/net_dgpsip.c: Fix socket check.
|
||||
|
||||
diff --git a/gpsd/net_dgpsip.c b/gpsd/net_dgpsip.c
|
||||
index d6e123b67..8e218ba41 100644
|
||||
--- a/gpsd/net_dgpsip.c
|
||||
+++ b/gpsd/net_dgpsip.c
|
||||
@@ -42,7 +42,7 @@ socket_t dgpsip_open(struct gps_device_t *device, const char *dgpsserver)
|
||||
}
|
||||
|
||||
dsock = netlib_connectsock(AF_UNSPEC, dgpsserver, dgpsport, "tcp");
|
||||
- if (0 <= dsock) {
|
||||
+ if (0 > dsock) {
|
||||
GPSD_LOG(LOG_ERROR, &device->context->errout,
|
||||
"DGPS: can't connect to DGPS server %s, netlib error %s(%d).\n",
|
||||
dgpsserver, netlib_errstr(dsock), dsock);
|
||||
|
||||
commit 60bc3595dbb74f8904037ad64b2a0820c408996b
|
||||
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
||||
Date: Mon Jul 31 15:50:32 2023 +0200
|
||||
|
||||
clients/gpsdebuginfo: Fix issues reported by shellcheck.
|
||||
|
||||
diff --git a/clients/gpsdebuginfo b/clients/gpsdebuginfo
|
||||
index fa970dad9..38a1540b2 100755
|
||||
--- a/clients/gpsdebuginfo
|
||||
+++ b/clients/gpsdebuginfo
|
||||
@@ -7,7 +7,7 @@ exec 2>&1
|
||||
|
||||
# print what we do
|
||||
set -x
|
||||
-if [ 0 != $(id -u) ]; then
|
||||
+if [ 0 != "$(id -u)" ]; then
|
||||
echo "Please run as root"
|
||||
exit 1
|
||||
fi
|
||||
@@ -63,9 +63,9 @@ ls -l /dev/pps* /dev/tty[ASTU]* /dev/gps*
|
||||
if command -v lsusb; then
|
||||
lsusb
|
||||
fi
|
||||
-echo PYTHONPATH $PYTHONPATH
|
||||
+echo PYTHONPATH "$PYTHONPATH"
|
||||
if command -v gpscat; then
|
||||
- head -n 1 `command -v gpscat`
|
||||
+ head -n 1 "$(command -v gpscat)"
|
||||
fi
|
||||
if command -v python; then
|
||||
python -V
|
||||
|
||||
commit e12265d591f07a50d6de54af83ae6246326460ef
|
||||
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
||||
Date: Mon Jul 31 15:50:58 2023 +0200
|
||||
|
||||
gpsinit: Fix issues reported by shellcheck.
|
||||
|
||||
diff --git a/gpsinit b/gpsinit
|
||||
index 5c14f3374..8fc6c92ec 100755
|
||||
--- a/gpsinit
|
||||
+++ b/gpsinit
|
||||
@@ -6,26 +6,23 @@
|
||||
# SPDX-License-Identifier: BSD-2-clause
|
||||
#
|
||||
|
||||
-speed=38400
|
||||
net=0
|
||||
|
||||
version()
|
||||
{
|
||||
- echo `basename $0`" : Version v0.21";
|
||||
+ echo "$(basename "$0") : Version v0.21";
|
||||
}
|
||||
|
||||
usage()
|
||||
{
|
||||
version; echo;
|
||||
- echo "usage :" `basename $0` "[-n <netnumber>] [-s <serial speed>] <can_module_name> [<interface_name>]";
|
||||
- echo " :" `basename $0` "-V";
|
||||
- echo " :" `basename $0` "-h";
|
||||
+ echo "usage : $(basename "$0") [-n <netnumber>] <can_module_name> [<interface_name>]";
|
||||
+ echo " : $(basename "$0") -V";
|
||||
+ echo " : $(basename "$0") -h";
|
||||
echo " Options include:";
|
||||
echo " -? = Print this help message and exit.";
|
||||
echo " -h = Print this help message and exit.";
|
||||
echo " -n = CAN network number, 0 if not given.";
|
||||
- echo " -s = Speed of the slcan hardware port, 38400 if not given.";
|
||||
- echo " = Needed for some slcan modules only.";
|
||||
echo " -V = Print version of this script and exit.";
|
||||
echo " can_module_name = One out of plx_pci, esd_usb2, usb_8dev, vcan, slcan, beaglebone.";
|
||||
echo " interface_name = The interface, the SLCAN module is connected to, i.e. /dev/ttyS0 or /dev/ttyUSB0.";
|
||||
@@ -34,19 +31,19 @@ usage()
|
||||
}
|
||||
|
||||
# -v for version is deprecated 2020
|
||||
-while getopts :n:s:vh opt
|
||||
+while getopts :n:s:vVh opt
|
||||
do
|
||||
case ${opt} in
|
||||
h) usage; exit 0;;
|
||||
n) net=${OPTARG};;
|
||||
- s) speed=${OPTARG};;
|
||||
+ s) ;; # unused
|
||||
\?) usage; exit 1;;
|
||||
v) version; exit 0;;
|
||||
V) version; exit 0;;
|
||||
esac
|
||||
done
|
||||
|
||||
-shift $((${OPTIND} - 1))
|
||||
+shift $((OPTIND - 1))
|
||||
|
||||
candevice=$1
|
||||
|
||||
@@ -54,38 +51,38 @@ case ${candevice} in
|
||||
plx_pci)
|
||||
# For the SJA1000 based PCI or PCI-Express CAN interface
|
||||
modprobe plx_pci;
|
||||
- ip link set can${net} type can tq 250 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1;
|
||||
- ip link set can${net} up;;
|
||||
+ ip link set "can${net}" type can tq 250 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1;
|
||||
+ ip link set "can${net}" up;;
|
||||
esd_usb2)
|
||||
# For an esd usb/2 CAN interface
|
||||
modprobe esd_usb2;
|
||||
- ip link set can${net} type can tq 250 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1;
|
||||
- ip link set can${net} up;;
|
||||
+ ip link set "can${net}" type can tq 250 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1;
|
||||
+ ip link set "can${net}" up;;
|
||||
usb_8dev)
|
||||
# For an 8devices usb2can CAN interface
|
||||
modprobe usb_8dev;
|
||||
- ip link set can${net} type can tq 250 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1;
|
||||
- ip link set can${net} up;;
|
||||
+ ip link set "can${net}" type can tq 250 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1;
|
||||
+ ip link set "can${net}" up;;
|
||||
vcan)
|
||||
# With this setup, CAN frames can be injected into vcan0 by a test
|
||||
modprobe vcan;
|
||||
ip link add type vcan;
|
||||
- ip link set vcan${net} up;;
|
||||
+ ip link set "vcan${net}" up;;
|
||||
slcan)
|
||||
# For a serial line CAN device
|
||||
# No support for devices, that need a setup of the baudrate yet
|
||||
device=${2:-/dev/ttyUSB0};
|
||||
modprobe slcan;
|
||||
- slcan_attach -f -s5 -o ${device};
|
||||
- slcand `basename ${device}`;
|
||||
- ip link set slcan${net} up;;
|
||||
+ slcan_attach -f -s5 -o "${device}";
|
||||
+ slcand "$(basename "${device}")";
|
||||
+ ip link set "slcan${net}" up;;
|
||||
beaglebone)
|
||||
# For CAN interface on a BeagleBone
|
||||
# The d_can driver is part of the kernel
|
||||
- ip link set can${net} type can bitrate 250000 sjw 1;
|
||||
- ip link set can${net} up;;
|
||||
+ ip link set "can${net}" type can bitrate 250000 sjw 1;
|
||||
+ ip link set "can${net}" up;;
|
||||
*)
|
||||
- echo `basename ${0}` ": invalid CAN interface ${1} net${net} device ${2:-(none)}"
|
||||
+ echo "$(basename "$0") : invalid CAN interface ${1} net${net} device ${2:-(none)}"
|
||||
echo;
|
||||
usage;
|
||||
exit 1
|
||||
2
sources
Normal file
2
sources
Normal file
@ -0,0 +1,2 @@
|
||||
SHA512 (gpsd-3.25.tar.gz) = 0684cbd30defa1a328898589e1d61b2431462a774aff56c588bd00c1fbd92ac94cf6fc1f2b981debac78c34ab09fa24f48ed6334f3ecd09e6b8f5faa92ae1085
|
||||
SHA512 (scons-4.5.2.tar.gz) = aa788d9365a8b5119fef404869562f61cb854be7ceadb5f5d47523e262c07f93ea7476166b577edec25339a64dc6a1f4a6f391fa5aeeab3f086a6659fc72e1ce
|
||||
27
tests/smoke/runtest.sh
Executable file
27
tests/smoke/runtest.sh
Executable file
@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
r=0
|
||||
|
||||
executables=$(rpm -ql gpsd-minimal gpsd-minimal-clients | grep -E '/s?bin/')
|
||||
for b in $executables; do
|
||||
case "$(basename "$b")" in
|
||||
gpsdebuginfo)
|
||||
continue;;
|
||||
zerk)
|
||||
h="-h";;
|
||||
*)
|
||||
h="--help";;
|
||||
esac
|
||||
|
||||
if "$b" "$h" |& grep -qi '^usage *:'; then
|
||||
echo "$b OK"
|
||||
else
|
||||
echo "$b FAILED"
|
||||
"$b" "$h" || :
|
||||
r=1
|
||||
fi
|
||||
done
|
||||
|
||||
exit $r
|
||||
7
tests/tests.yml
Normal file
7
tests/tests.yml
Normal file
@ -0,0 +1,7 @@
|
||||
- hosts: localhost
|
||||
roles:
|
||||
- role: standard-test-basic
|
||||
tags:
|
||||
- classic
|
||||
tests:
|
||||
- smoke
|
||||
Loading…
Reference in New Issue
Block a user