104 lines
3.5 KiB
Diff
104 lines
3.5 KiB
Diff
|
From 0181fafb2134a177328443a60b5e29c4ee1041cb Mon Sep 17 00:00:00 2001
|
||
|
From: Guy Harris <gharris@sonic.net>
|
||
|
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
|
||
|
|