netxray: don't allow out-of-range time stamps.

This should squelch Coverity CID 1509369.
This commit is contained in:
Guy Harris 2022-08-16 14:46:44 -07:00
parent b679f22a54
commit 79219b5247
3 changed files with 44 additions and 13 deletions

View File

@ -1687,7 +1687,7 @@ netxray_guess_atm_type(wtap *wth, wtap_rec *rec, Buffer *buf)
typedef struct {
gboolean first_frame;
nstime_t start;
guint32 start_secs;
guint32 nframes;
} netxray_dump_t;
@ -1751,8 +1751,7 @@ netxray_dump_open_1_1(wtap_dumper *wdh, int *err, gchar **err_info _U_)
netxray = g_new(netxray_dump_t, 1);
wdh->priv = (void *)netxray;
netxray->first_frame = TRUE;
netxray->start.secs = 0;
netxray->start.nsecs = 0;
netxray->start_secs = 0;
netxray->nframes = 0;
return TRUE;
@ -1804,12 +1803,25 @@ netxray_dump_1_1(wtap_dumper *wdh,
the stamp of the first packet with the microseconds part 0. */
if (netxray->first_frame) {
netxray->first_frame = FALSE;
netxray->start = rec->ts;
/*
* XXX - NetXRay ran on Windows, where MSVC's localtime()
* can't handle time_t < 0, so *maybe* it makes sense
* to allow time stamps up to 2^32-1 "seconds since the
* Epoch", but maybe the start time in those files is
* signed, in which case we should check against
* G_MININT32 and G_MAXINT32 and make start_secs a
* gint32.
*/
if (rec->ts.secs < 0 || rec->ts.secs > G_MAXUINT32) {
*err = WTAP_ERR_TIME_STAMP_NOT_SUPPORTED;
return FALSE;
}
netxray->start_secs = (guint32)rec->ts.secs;
}
/* build the header for each packet */
memset(&rec_hdr, '\0', sizeof(rec_hdr));
timestamp = ((guint64)rec->ts.secs - (guint64)netxray->start.secs)*1000000
timestamp = ((guint64)rec->ts.secs - (guint64)netxray->start_secs)*1000000
+ ((guint64)rec->ts.nsecs)/1000;
t32 = (guint32)(timestamp%G_GINT64_CONSTANT(4294967296));
rec_hdr.timelo = GUINT32_TO_LE(t32);
@ -1856,7 +1868,7 @@ netxray_dump_finish_1_1(wtap_dumper *wdh, int *err, gchar **err_info _U_)
/* "sniffer" version ? */
memset(&file_hdr, '\0', sizeof file_hdr);
memcpy(file_hdr.version, vers_1_1, sizeof vers_1_1);
file_hdr.start_time = GUINT32_TO_LE(netxray->start.secs);
file_hdr.start_time = GUINT32_TO_LE(netxray->start_secs);
file_hdr.nframes = GUINT32_TO_LE(netxray->nframes);
file_hdr.start_offset = GUINT32_TO_LE(CAPTUREFILE_HEADER_SIZE);
/* XXX - large files? */
@ -1938,8 +1950,7 @@ netxray_dump_open_2_0(wtap_dumper *wdh, int *err, gchar **err_info _U_)
netxray = g_new(netxray_dump_t, 1);
wdh->priv = (void *)netxray;
netxray->first_frame = TRUE;
netxray->start.secs = 0;
netxray->start.nsecs = 0;
netxray->start_secs = 0;
netxray->nframes = 0;
return TRUE;
@ -1991,12 +2002,25 @@ netxray_dump_2_0(wtap_dumper *wdh,
the stamp of the first packet with the microseconds part 0. */
if (netxray->first_frame) {
netxray->first_frame = FALSE;
netxray->start = rec->ts;
/*
* XXX - NetXRay ran on Windows, where MSVC's localtime()
* can't handle time_t < 0, so *maybe* it makes sense
* to allow time stamps up to 2^32-1 "seconds since the
* Epoch", but maybe the start time in those files is
* signed, in which case we should check against
* G_MININT32 and G_MAXINT32 and make start_secs a
* gint32.
*/
if (rec->ts.secs < 0 || rec->ts.secs > G_MAXUINT32) {
*err = WTAP_ERR_TIME_STAMP_NOT_SUPPORTED;
return FALSE;
}
netxray->start_secs = (guint32)rec->ts.secs;
}
/* build the header for each packet */
memset(&rec_hdr, '\0', sizeof(rec_hdr));
timestamp = ((guint64)rec->ts.secs - (guint64)netxray->start.secs)*1000000
timestamp = ((guint64)rec->ts.secs - (guint64)netxray->start_secs)*1000000
+ ((guint64)rec->ts.nsecs)/1000;
t32 = (guint32)(timestamp%G_GINT64_CONSTANT(4294967296));
rec_hdr.timelo = GUINT32_TO_LE(t32);
@ -2074,7 +2098,7 @@ netxray_dump_finish_2_0(wtap_dumper *wdh, int *err, gchar **err_info _U_)
/* "sniffer" version ? */
memset(&file_hdr, '\0', sizeof file_hdr);
memcpy(file_hdr.version, vers_2_001, sizeof vers_2_001);
file_hdr.start_time = GUINT32_TO_LE(netxray->start.secs);
file_hdr.start_time = GUINT32_TO_LE(netxray->start_secs);
file_hdr.nframes = GUINT32_TO_LE(netxray->nframes);
file_hdr.start_offset = GUINT32_TO_LE(CAPTUREFILE_HEADER_SIZE);
/* XXX - large files? */

View File

@ -1381,6 +1381,9 @@ static const char *wtap_errlist[] = {
/* WTAP_ERR_DECOMPRESSION_NOT_SUPPORTED */
"We don't support decompressing that type of compressed file",
/* WTAP_ERR_TIME_STAMP_NOT_SUPPORTED */
"We don't support writing that record's time stamp to that file type",
};
#define WTAP_ERRLIST_SIZE (sizeof wtap_errlist / sizeof wtap_errlist[0])

View File

@ -2302,8 +2302,8 @@ void wtap_cleanup(void);
/**< The file being opened is not a capture file in a known format */
#define WTAP_ERR_UNSUPPORTED -4
/**< Supported file type, but there's something in the file we
can't support */
/**< Supported file type, but there's something in the file we're
reading that we can't support */
#define WTAP_ERR_CANT_WRITE_TO_PIPE -5
/**< Wiretap can't save to a pipe in the specified format */
@ -2374,6 +2374,10 @@ void wtap_cleanup(void);
#define WTAP_ERR_DECOMPRESSION_NOT_SUPPORTED -26
/**< We don't support decompressing that type of compressed file */
#define WTAP_ERR_TIME_STAMP_NOT_SUPPORTED -27
/**< We don't support writing that record's time stamp to that
file type */
#ifdef __cplusplus
}
#endif /* __cplusplus */