Hi Gary,

On Thu, 22 Oct 2026 23:30:26 -0700, Gary E. Miller wrote:
> I'm all for preventing a buffer overflow, but why are you remiving
> the stuff before the # in the path?

It doesn't remove it: what goes in front of the device is the same as
before.  The old code copied all of dev.path in, then cut it at its
first '#' ("Avoid accumulating multiple device names"); the patch
inserts the same thing, the strcspn(dev.path, "#") bytes before any
'#', then a '#'.  The source path before the '#' stays, and so does
the device after it.

I ran the same packets through the JSON passthrough driver built from
master (d627ef33d) and with the patch, source gpsd://example.com:2947:

  TPV, "device":"/dev/ttyS0"
    master:  "device":"gpsd://example.com:2947#/dev/ttyS0"
    patched: "device":"gpsd://example.com:2947#/dev/ttyS0"
  DEVICE, "path":"/dev/ttyS0"
    master:  "path":"gpsd://example.com:2947#/dev/ttyS0"
    patched: "path":"gpsd://example.com:2947#/dev/ttyS0"
  TPV, source gpsd://example.com:2947#/dev/ttyUSB0
    master:  "device":"gpsd://example.com:2947#/dev/ttyS0"
    patched: "device":"gpsd://example.com:2947#/dev/ttyS0"
  TPV already holding "gpsd://example.com:2947#/dev/ttyS0"
    master and patched: passed unchanged
  DEVICES, paths /dev/ttyS0 and /dev/ttyS1
    master:  "gpsd://example.com:2947#/dev/ttyS0", "/dev/ttyS1"
    patched: "gpsd://example.com:2947#/dev/ttyS0",
             "gpsd://example.com:2947#/dev/ttyS1"

The DEVICES reply is the one difference: master stops scanning at the
packet's old length, so the second path, pushed past it by the first
insert, keeps its bare name.  (This packet is short; in a full DEVICES
reply it takes a few devices behind a longer source name.)

> Also you said:
>
> " A JSON packet can be nearly as long as outbuffer,"
>
> #define GPS_JSON_RESPONSE_MAX   10240
>   char buffer[GPS_JSON_RESPONSE_MAX * 2];
>
> Comments?

Fair point, that sentence left out where such a packet comes from.
GPS_JSON_RESPONSE_MAX bounds what a gpsd sends, and that buffer is
libgps's read buffer (struct privdata_t, include/gps.h).
path_rewrite() works on gpsd's own lexer.outbuffer, INOUTSTASHSZ =
MAX_PACKET_LENGTH * 2 + 1 = 18433 bytes (include/gpsd.h), and nothing
on the reading side holds a gpsd:// source to GPS_JSON_RESPONSE_MAX:
the JSON lexer in packet.c passes on any object that fits outbuffer.
A TPV padded to each length, through packet_parse() on master:

  10240 bytes: JSON_PACKET, outbuflen 10240
  18000 bytes: JSON_PACKET, outbuflen 18000
  18432 bytes: JSON_PACKET, outbuflen 18432

So a well-behaved gpsd never comes near the overflow.  It takes a
source that sends more than a gpsd would, or anything on the path
between the two, since a gpsd:// link is plain TCP: a packet a little
short of 18432 bytes, with a "device" value near its end.

I'll send a v2 in this thread that says this in the commit message.
The code is the same as v1.

Thanks,
Ana

Reply via email to