From 0181fafb2134a177328443a60b5e29c4ee1041cb Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Tue, 16 May 2023 12:05:07 -0700 Subject: [PATCH] candump: check for a too-long frame length. If the frame length is longer than the maximum, report an error in the file. Fixes #19062, preventing the overflow on a buffer on the stack (assuming your compiler doesn't call a bounds-checknig version of memcpy() if the size of the target space is known). --- wiretap/candump.c | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/wiretap/candump.c b/wiretap/candump.c index 62f89e7b564..43863b45cf7 100644 --- a/wiretap/candump.c +++ b/wiretap/candump.c @@ -34,8 +34,9 @@ void register_candump(void); wtap_rec *rec, Buffer *buf, int *err, gchar **err_info); -static void -candump_write_packet(wtap_rec *rec, Buffer *buf, const msg_t *msg) +static gboolean +candump_write_packet(wtap_rec *rec, Buffer *buf, const msg_t *msg, int *err, + gchar **err_info) { static const char *can_proto_name = "can-hostendian"; static const char *canfd_proto_name = "canfd"; @@ -56,6 +57,18 @@ candump_write_packet(wtap_rec *rec, Buffer *buf, const msg_t *msg) { canfd_frame_t canfd_frame = {0}; + /* + * There's a maximum of CANFD_MAX_DLEN bytes in a CAN-FD frame. + */ + if (msg->data.length > CANFD_MAX_DLEN) { + *err = WTAP_ERR_BAD_FILE; + if (err_info != NULL) { + *err_info = g_strdup_printf("candump: File has %u-byte CAN FD packet, bigger than maximum of %u", + msg->data.length, CANFD_MAX_DLEN); + } + return FALSE; + } + canfd_frame.can_id = msg->id; canfd_frame.flags = msg->flags; canfd_frame.len = msg->data.length; @@ -67,6 +80,18 @@ candump_write_packet(wtap_rec *rec, Buffer *buf, const msg_t *msg) { can_frame_t can_frame = {0}; + /* + * There's a maximum of CAN_MAX_DLEN bytes in a CAN frame. + */ + if (msg->data.length > CAN_MAX_DLEN) { + *err = WTAP_ERR_BAD_FILE; + if (err_info != NULL) { + *err_info = g_strdup_printf("candump: File has %u-byte CAN packet, bigger than maximum of %u", + msg->data.length, CAN_MAX_DLEN); + } + return FALSE; + } + can_frame.can_id = msg->id; can_frame.can_dlc = msg->data.length; memcpy(can_frame.data, msg->data.data, msg->data.length); @@ -82,6 +107,8 @@ candump_write_packet(wtap_rec *rec, Buffer *buf, const msg_t *msg) rec->rec_header.packet_header.caplen = packet_length; rec->rec_header.packet_header.len = packet_length; + + return TRUE; } static gboolean @@ -188,9 +215,7 @@ candump_read(wtap *wth, wtap_rec *rec, Buffer *buf, int *err, gchar **err_info, ws_debug_printf("%s: Stopped at offset %" PRIi64 "\n", G_STRFUNC, file_tell(wth->fh)); #endif - candump_write_packet(rec, buf, &msg); - - return TRUE; + return candump_write_packet(rec, buf, &msg, err, err_info); } static gboolean @@ -214,9 +239,7 @@ candump_seek_read(wtap *wth , gint64 seek_off, wtap_rec *rec, if (!candump_parse(wth->random_fh, &msg, NULL, err, err_info)) return FALSE; - candump_write_packet(rec, buf, &msg); - - return TRUE; + return candump_write_packet(rec, buf, &msg, err, err_info); } /* -- GitLab