Changeset 11124 in ntrip


Ignore:
Timestamp:
Oct 24, 2026, 10:10:29 PM (6 hours ago)
Author:
stuerze
Message:

Some fixes regarding memory corruption from stream data, credential exposure,

Location:
trunk/BNC
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/BNC/CHANGELOG.md

    r11123 r11124  
    5252- FIXED: RINEX QC used the first ephemeris of the file for all epochs (wrong GLONASS elevations, very long run times for daily files)
    5353- FIXED: Ntrip Version 2 streams: longer timeout for the first read after (re)connect, allowing for slow proxy auto-detection and TLS handshake
     54- FIXED: Memory corruption by stream content: VTEC messages with spherical harmonics degree or order 16 (IGS-SSR and RTCM-SSR; with 4 layers BNC crashed), RTCM-SSR metadata with more than 7 entries, names of 31 characters in RTCM 1300/1301/1302; range check of the VTEC parameters from the RTNet engine
     55- FIXED: Password no longer sent in the request line (Ntrip Version 1 via proxy, RTSP) and no longer written to the log (RTSP)
    5456
    5557## 2.13.7 (2026-07-31)
  • trunk/BNC/src/RTCM3/RTCM3Decoder.cpp

    r11084 r11124  
    21732173    for (int i = 0; i < dblinksnum; i++) {
    21742174      int dblinknum = -1;
    2175       char dblinkname[31];
     2175      char dblinkname[32]; // up to 31 characters (5-bit length) + terminating 0
    21762176      GETBITS(dblinknum, 5)
    21772177      if (dblinknum > -1 && dblinknum <= 31) {
  • trunk/BNC/src/RTCM3/clock_and_orbit/clock_orbit.h

    r11048 r11124  
    454454      unsigned int Degree; /* 1-16 */
    455455      unsigned int Order;  /* 1-16 */
    456       double Sinus[VTEC_MAXIONODEGREE][VTEC_MAXIONOORDER];
    457       double Cosinus[VTEC_MAXIONODEGREE][VTEC_MAXIONOORDER];
     456      /* indices 0 .. Degree / 0 .. Order, both up to 16 */
     457      double Sinus[VTEC_MAXIONODEGREE+1][VTEC_MAXIONOORDER+1];
     458      double Cosinus[VTEC_MAXIONODEGREE+1][VTEC_MAXIONOORDER+1];
    458459    } Layers[VTEC_NUMIONOLAYERS];
    459460  };
  • trunk/BNC/src/RTCM3/clock_and_orbit/clock_orbit_rtcm_new.cpp

    r11046 r11124  
    637637      fprintf(stderr, "ssrIod %d providerId %d solId %d numEntries %d \n",
    638638      md->SSRIOD, md->SSRProviderID, md->SSRSolutionID, md->NumEntries);
    639 #endif
     639#endif
     640    if (md->NumEntries > META_MAXNUMENTRIES) { /* DF+063 is 5 bits wide */
     641      md->NumEntries = 0;
     642      return GCOBR_DATAMISMATCH;
     643    }
    640644    for (i = 0; i < md->NumEntries; i++) {
    641645      unsigned int additionalBits;
    … …  
    687691      if (md->Entries[i].nonDefaultIndicator &&
    688692        md->Entries[i].additionalParameterIndicator) {
    689         D_ADDITIONAL_MODEL_PARAMETER_DATA(md->Entries[i].additionalParameterData, additionalBits)
     693        /* DF+071 allows up to 255 bits, only 32 can be stored: skip the
     694           leading excess bits, keep the trailing 32 */
     695        while (additionalBits > 32) {
     696          unsigned int n = (additionalBits - 32 > 32) ? 32 : additionalBits - 32;
     697          SKIPSSRBITS(n)
     698          additionalBits -= n;
     699        }
     700        if (additionalBits)
     701          D_ADDITIONAL_MODEL_PARAMETER_DATA(md->Entries[i].additionalParameterData, additionalBits)
    690702#ifdef BNC_DEBUG_SSR
    691703        fprintf(stderr, "- additional-data-parameter-data     : %d\n", md->Entries[i].additionalParameterData);
  • trunk/BNC/src/RTCM3/crs.h

    r10545 r11124  
    2424  }
    2525  void clear(void) {
    26     memset(_name, '\0', 31 * sizeof(char));
     26    memset(_name, '\0', sizeof(_name));
    2727    _coordinateEpoch = 0;
    2828    _CE              = 0;
    … …  
    3838    void setCoordinateEpochFromCE() {(!_CE) ? _coordinateEpoch = 0.0 : _coordinateEpoch = 1900 + _CE; }
    3939    void setCEFromCoordinateEpoch() {(!_coordinateEpoch) ? _CE = 0 : _CE = _coordinateEpoch -1900; }
    40     char     _name[31];
     40    char     _name[32]; // up to 31 characters (5-bit length) + terminating 0
    4141    double   _coordinateEpoch;
    4242    double   _CE;
    … …  
    5555    }
    5656    void clear() {
    57       memset(_name, '\0', 31 * sizeof(char));
     57      memset(_name, '\0', sizeof(_name));
    5858      _anchor = 0;
    5959      _plateNumber = 0;
    … …  
    7171      }
    7272    }
    73     char             _name[31];
     73    char             _name[32]; // up to 31 characters (5-bit length) + terminating 0
    7474    int              _anchor;           // 0.. global CRS (=> Plate number 0), 1.. plate-fixed CRS
    7575    int              _plateNumber;      // 0.. unknown, 7.. Eurasia
    … …  
    171171       cout << endl;
    172172     }
    173      char           _sourceName[31];
    174      char           _targetName[31];
     173     char           _sourceName[32]; // up to 31 characters (5-bit length) + terminating 0
     174     char           _targetName[32];
    175175     int            _sysIdentNum;
    176176     int            _utilTrafoMessageIndicator;
  • trunk/BNC/src/bncnetqueryrtp.cpp

    r8231 r11124  
    4747  _status = finished;
    4848  if (_socket) {
    49     QByteArray reqStr = "TEARDOWN " + _url.toEncoded() + " RTSP/1.0\r\n"
     49    QByteArray reqStr = "TEARDOWN " + _url.toEncoded(QUrl::RemoveUserInfo) + " RTSP/1.0\r\n"
    5050                      + "CSeq: " + QString("%1").arg(++_CSeq).toLatin1() + "\r\n"
    5151                      + "Session: " + _session + "\r\n"
    … …  
    5959void bncNetQueryRtp::slotKeepAlive() {
    6060  if (_socket) {
    61     QByteArray reqStr = "GET_PARAMETER " + _url.toEncoded() + " RTSP/1.0\r\n"
     61    QByteArray reqStr = "GET_PARAMETER " + _url.toEncoded(QUrl::RemoveUserInfo) + " RTSP/1.0\r\n"
    6262                      + "CSeq: " + QString("%1").arg(++_CSeq).toLatin1() + "\r\n"
    6363                      + "Session: " + _session + "\r\n"
    … …  
    144144
    145145    QByteArray reqStr;
    146     reqStr = "SETUP " + _url.toEncoded() + " RTSP/1.0\r\n"
     146    reqStr = "SETUP " + _url.toEncoded(QUrl::RemoveUserInfo) + " RTSP/1.0\r\n"
    147147           + "CSeq: " + QString("%1").arg(++_CSeq).toLatin1() + "\r\n"
    148148           + "Ntrip-Version: Ntrip/2.0\r\n"
    … …  
    202202          }
    203203
    204           reqStr = "PLAY " + _url.toEncoded() + " RTSP/1.0\r\n"
     204          reqStr = "PLAY " + _url.toEncoded(QUrl::RemoveUserInfo) + " RTSP/1.0\r\n"
    205205                 + "CSeq: " + QString("%1").arg(++_CSeq).toLatin1() + "\r\n"
    206206                 + "Session: " + _session + "\r\n"
    … …  
    216216              while (!line.isEmpty()) {
    217217                if (line.indexOf("200 OK") != -1) {
    218                   emit newMessage(_url.toEncoded().replace(0,1,"")
     218                  emit newMessage(_url.toEncoded(QUrl::RemoveUserInfo).replace(0,1,"")
    219219                            + ": UDP connection established", true);
    220220                  slotKeepAlive();
    … …  
    233233  _socket = 0;
    234234  _status = error;
    235   emit newMessage(_url.toEncoded().replace(0,1,"")
     235  emit newMessage(_url.toEncoded(QUrl::RemoveUserInfo).replace(0,1,"")
    236236                  + ": NetQuery, waiting for connect", true);
    237237}
  • trunk/BNC/src/bncnetqueryv1.cpp

    r8203 r11124  
    225225             + userAndPwd + "\r\n";
    226226  } else {
    227     reqStr = "GET " + _url.toEncoded() + " HTTP/1.0\r\n"
     227    reqStr = "GET " + _url.toEncoded(QUrl::RemoveUserInfo) + " HTTP/1.0\r\n"
    228228             + "User-Agent: NTRIP BNC/" BNCVERSION " (" BNC_OS ")\r\n"
    229229             + "Host: " + _url.host().toLatin1() + "\r\n"
  • trunk/BNC/src/upload/bncrtnetuploadcaster.cpp

    r11058 r11124  
    504504            in >> ui >> vtec.NumLayers;
    505505            vtec.UpdateInterval = (unsigned int)determineUpdateInd(ui);
     506            if (vtec.NumLayers > VTEC_NUMIONOLAYERS) {
     507                vtec.NumLayers = 0;
     508            }
    506509            for (unsigned ll = 0; ll < vtec.NumLayers; ll++) {
    507510                int dummy;
    508511                in >> dummy >> vtec.Layers[ll].Degree >> vtec.Layers[ll].Order
    509512                    >> vtec.Layers[ll].Height;
     513                if (vtec.Layers[ll].Degree < 1 || vtec.Layers[ll].Degree > VTEC_MAXIONODEGREE ||
     514                    vtec.Layers[ll].Order  < 1 || vtec.Layers[ll].Order  > VTEC_MAXIONOORDER) {
     515                    vtec.NumLayers = 0;
     516                    break;
     517                }
    510518                for (unsigned iDeg = 0; iDeg <= vtec.Layers[ll].Degree; iDeg++) {
    511519                    for (unsigned iOrd = 0; iOrd <= vtec.Layers[ll].Order; iOrd++) {
  • trunk/BNC/tests/README.md

    r11087 r11124  
    2828| `tools/fakecaster.py` | local Ntrip caster recording an upload as a BNC raw file (case key `fakecaster`) |
    2929| `tools/bncraw.py` | `info` (streams, time span, RTCM3 message types) and `slice` for raw captures |
     30| `tools/mkcrafted.py` | writes `data/crafted_limits.raw`: crafted frames at the upper field limits |
     31| `tools/ssr_harness.sh` | builds `tools/ssr_harness.cpp` with the SSR decoders under ASan/UBSan and runs it |
    3032| `work/` | scratch output, not versioned |
    3133
    … …  
    9092  'QC Bias File' (code bias check against the other ACs and the file).
    9193
     94* `decoder_limits`: crafted, CRC-valid frames from `tools/mkcrafted.py`
     95  using the largest values the formats allow: VTEC with degree/order 16
     96  (IGS-SSR 4076/201 and RTCM-SSR 1264, 2 and 4 layers) and RTCM 1300/1301/1302
     97  with 31-character names, listed by the RTCM scan in the log. The
     98  coefficients are C(d,o) = (100*d+o)/200 TECU and S = -C, both `.ssr` files
     99  are identical apart from the station ID. These frames overflowed the
     100  coefficient and name arrays; the 4-layer VTEC crashed BNC.
     101
     102## Sanitizer check of the SSR decoders
     103
     104```
     105tests/tools/ssr_harness.sh            # crafted_limits.raw
     106tests/tools/ssr_harness.sh tests/data/*.raw   # real captures
     107```
     108
     109In BNC all SSR target structs are members of one `RTCM3coDecoder` object,
     110so a write beyond one struct corrupts the next member without any
     111AddressSanitizer report. The harness decodes every frame with all three
     112format classes into separately allocated structs, so ASan reports it. It
     113also covers the new RTCM-SSR metadata (message 60 in
     114`crafted_limits.raw`: 7 entries with additional parameters of 40 and 0 bits,
     115and 31 entries, which must be rejected), which `RTCM3Decoder.cpp` does not
     116dispatch at present. Exit code 0 only without sanitizer errors.
     117
    92118## Adding a replay case
    93119
Note: See TracChangeset for help on using the changeset viewer.