From 02cffb51a9fc048defac1085cb71d5567ae3f4fc Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Fri, 18 Jun 2021 16:22:54 -0700 Subject: [PATCH] erf: handle errors in some routines more completely. Have them take error code and error information string arguments and, for various failures, fill them in as "internal error" indications. Check their return codes to see if they got an error. --- wiretap/erf-common.h | 2 +- wiretap/erf.c | 190 ++++++++++++++++++++++++++++++++++++------- wiretap/libpcap.c | 2 +- 3 files changed, 164 insertions(+), 30 deletions(-) diff --git a/wiretap/erf-common.h b/wiretap/erf-common.h index 7635ffcdae..a14cf00917 100644 --- a/wiretap/erf-common.h +++ b/wiretap/erf-common.h @@ -23,7 +23,7 @@ typedef struct erf_private erf_t; erf_t* erf_priv_create(void); erf_t* erf_priv_free(erf_t* erf_priv); -int erf_populate_interface_from_header(erf_t* erf_priv, wtap *wth, union wtap_pseudo_header *pseudo_header); +int erf_populate_interface_from_header(erf_t* erf_priv, wtap *wth, union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info); #endif /* __W_ERF_COMMON_H__ */ diff --git a/wiretap/erf.c b/wiretap/erf.c index 86dc04600f..c9114e81fe 100644 --- a/wiretap/erf.c +++ b/wiretap/erf.c @@ -65,10 +65,10 @@ static gboolean erf_seek_read(wtap *wth, gint64 seek_off, int *err, gchar **err_info); static void erf_close(wtap *wth); -static int populate_summary_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo_header *pseudo_header, Buffer *buf, guint32 packet_size, GPtrArray *anchor_mappings_to_update); +static int populate_summary_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo_header *pseudo_header, Buffer *buf, guint32 packet_size, GPtrArray *anchor_mappings_to_update, int *err, gchar **err_info); static int erf_update_anchors_from_header(erf_t *erf_priv, wtap_rec *rec, union wtap_pseudo_header *pseudo_header, guint64 host_id, GPtrArray *anchor_mappings_to_update); static int erf_get_source_from_header(union wtap_pseudo_header *pseudo_header, guint64 *host_id, guint8 *source_id); -static int erf_populate_interface(erf_t* erf_priv, wtap *wth, union wtap_pseudo_header *pseudo_header, guint64 host_id, guint8 source_id, guint8 if_num); +static int erf_populate_interface(erf_t* erf_priv, wtap *wth, union wtap_pseudo_header *pseudo_header, guint64 host_id, guint8 source_id, guint8 if_num, int *err, gchar **err_info); typedef struct { gboolean write_next_extra_meta; @@ -595,7 +595,10 @@ static gboolean erf_read(wtap *wth, wtap_rec *rec, Buffer *buf, */ if ((erf_header.type & 0x7F) == ERF_TYPE_META && packet_size > 0) { - populate_summary_info((erf_t*) wth->priv, wth, &rec->rec_header.packet_header.pseudo_header, buf, packet_size, anchor_mappings_to_update); + if (populate_summary_info((erf_t*) wth->priv, wth, &rec->rec_header.packet_header.pseudo_header, buf, packet_size, anchor_mappings_to_update, err, err_info) < 0) { + g_ptr_array_free(anchor_mappings_to_update, TRUE); + return FALSE; + } } } while ( erf_header.type == ERF_TYPE_PAD ); @@ -671,6 +674,7 @@ static gboolean erf_read_header(wtap *wth, FILE_T fh, int i = 0; int max = sizeof(pseudo_header->erf.ehdr_list)/sizeof(struct erf_ehdr); erf_t *priv = (erf_t*)wth->priv; + int interface_id; guint64 host_id = ERF_META_HOST_ID_IMPLICIT; guint8 source_id = 0; @@ -792,8 +796,11 @@ static gboolean erf_read_header(wtap *wth, FILE_T fh, i++; } - /* XXX: erf_priv pointer needs to change if used as common function for other dissectors! */ - rec->rec_header.packet_header.interface_id = (guint) erf_populate_interface((erf_t*) wth->priv, wth, pseudo_header, host_id, source_id, if_num); + interface_id = erf_populate_interface((erf_t*) wth->priv, wth, pseudo_header, host_id, source_id, if_num, err, err_info); + if (interface_id < 0) { + return FALSE; + } + rec->rec_header.packet_header.interface_id = (guint) interface_id; /* Try to find comment links using Anchor ID. Done here after we found the first Host ID and have updated the implicit Host ID. */ erf_update_anchors_from_header(priv, rec, pseudo_header, host_id, anchor_mappings_to_update); @@ -2101,7 +2108,7 @@ static int erf_get_source_from_header(union wtap_pseudo_header *pseudo_header, g return 0; } -int erf_populate_interface_from_header(erf_t *erf_priv, wtap *wth, union wtap_pseudo_header *pseudo_header) +int erf_populate_interface_from_header(erf_t *erf_priv, wtap *wth, union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info) { guint64 host_id; guint8 source_id; @@ -2114,7 +2121,7 @@ int erf_populate_interface_from_header(erf_t *erf_priv, wtap *wth, union wtap_ps erf_get_source_from_header(pseudo_header, &host_id, &source_id); - return erf_populate_interface(erf_priv, wth, pseudo_header, host_id, source_id, if_num); + return erf_populate_interface(erf_priv, wth, pseudo_header, host_id, source_id, if_num, err, err_info); } static struct erf_if_mapping* erf_find_interface_mapping(erf_t *erf_priv, guint64 host_id, guint8 source_id) @@ -2416,14 +2423,33 @@ static int erf_update_implicit_host_id(erf_t *erf_priv, wtap *wth, guint64 impli return 0; } -static int erf_populate_interface(erf_t *erf_priv, wtap *wth, union wtap_pseudo_header *pseudo_header, guint64 host_id, guint8 source_id, guint8 if_num) +static int erf_populate_interface(erf_t *erf_priv, wtap *wth, union wtap_pseudo_header *pseudo_header, guint64 host_id, guint8 source_id, guint8 if_num, int *err, gchar **err_info) { wtap_block_t int_data; wtapng_if_descr_mandatory_t* int_data_mand; struct erf_if_mapping* if_map = NULL; - if (!wth || !pseudo_header || !erf_priv || if_num > 3) + if (!wth) { + *err = WTAP_ERR_INTERNAL; + *err_info = g_strdup_printf("erf: erf_populate_interface called with wth NULL"); return -1; + } + if (!pseudo_header) { + *err = WTAP_ERR_INTERNAL; + *err_info = g_strdup_printf("erf: erf_populate_interface called with pseudo_header NULL"); + return -1; + } + if (!erf_priv) { + *err = WTAP_ERR_INTERNAL; + *err_info = g_strdup_printf("erf: erf_populate_interface called with erf_priv NULL"); + return -1; + } + if (if_num > 3) { + *err = WTAP_ERR_INTERNAL; + *err_info = g_strdup_printf("erf: erf_populate_interface called with if_num %u > 3", + if_num); + return -1; + } if (host_id == ERF_META_HOST_ID_IMPLICIT) { /* Defaults to ERF_META_HOST_ID_IMPLICIT so we can update mapping later */ @@ -2513,7 +2539,7 @@ static guint32 erf_meta_read_tag(struct erf_meta_tag* tag, guint8 *tag_ptr, guin return tagtotallength; } -static int populate_capture_host_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo_header *pseudo_header _U_, struct erf_meta_read_state *state) +static int populate_capture_host_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo_header *pseudo_header _U_, struct erf_meta_read_state *state, int *err, gchar **err_info) { struct erf_meta_tag tag = {0, 0, NULL}; @@ -2527,8 +2553,26 @@ static int populate_capture_host_info(erf_t *erf_priv, wtap *wth, union wtap_pse gchar* modelcpu = NULL; guint32 tagtotallength; - if (!wth || !state || !wth->shb_hdrs || (wth->shb_hdrs->len == 0)) + if (!wth) { + *err = WTAP_ERR_INTERNAL; + *err_info = g_strdup_printf("erf: populate_capture_host_info called with wth NULL"); return -1; + } + if (!state) { + *err = WTAP_ERR_INTERNAL; + *err_info = g_strdup_printf("erf: populate_capture_host_info called with state NULL"); + return -1; + } + if (!wth->shb_hdrs) { + *err = WTAP_ERR_INTERNAL; + *err_info = g_strdup_printf("erf: populate_capture_host_info called with wth->shb_hdrs NULL"); + return -1; + } + if (wth->shb_hdrs->len == 0) { + *err = WTAP_ERR_INTERNAL; + *err_info = g_strdup_printf("erf: populate_capture_host_info called with wth->shb_hdrs->len 0"); + return -1; + } /* XXX: wth->shb_hdr is already created by different layer, using directly for now. */ /* XXX: Only one section header is supported at this time */ @@ -2669,14 +2713,22 @@ static int populate_capture_host_info(erf_t *erf_priv, wtap *wth, union wtap_pse return 1; } -static int populate_module_info(erf_t *erf_priv _U_, wtap *wth, union wtap_pseudo_header *pseudo_header _U_, struct erf_meta_read_state *state) +static int populate_module_info(erf_t *erf_priv _U_, wtap *wth, union wtap_pseudo_header *pseudo_header _U_, struct erf_meta_read_state *state, int *err, gchar **err_info) { struct erf_meta_tag tag = {0, 0, NULL}; guint32 tagtotallength; - if (!wth || !state) + if (!wth) { + *err = WTAP_ERR_INTERNAL; + *err_info = g_strdup_printf("erf: populate_module_info called with wth NULL"); return -1; + } + if (!state) { + *err = WTAP_ERR_INTERNAL; + *err_info = g_strdup_printf("erf: populate_module_info called with stat NULL"); + return -1; + } if (state->if_map->module_gentime > state->gen_time) { return 0; @@ -2710,7 +2762,7 @@ static int populate_module_info(erf_t *erf_priv _U_, wtap *wth, union wtap_pseud return 1; } -static int populate_interface_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo_header *pseudo_header, struct erf_meta_read_state *state) +static int populate_interface_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo_header *pseudo_header, struct erf_meta_read_state *state, int *err, gchar **err_info) { struct erf_meta_tag tag = {0, 0, NULL}; guint32 tagtotallength; @@ -2721,8 +2773,26 @@ static int populate_interface_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo guint32 if_num = 0; struct erf_if_info* if_info = NULL; - if (!wth || !state || !pseudo_header || !state->if_map) + if (!wth) { + *err = WTAP_ERR_INTERNAL; + *err_info = g_strdup_printf("erf: populate_interface_info called with wth NULL"); return -1; + } + if (!state) { + *err = WTAP_ERR_INTERNAL; + *err_info = g_strdup_printf("erf: populate_interface_info called with state NULL"); + return -1; + } + if (!pseudo_header) { + *err = WTAP_ERR_INTERNAL; + *err_info = g_strdup_printf("erf: populate_interface_info called with pseudo_header NULL"); + return -1; + } + if (!state->if_map) { + *err = WTAP_ERR_INTERNAL; + *err_info = g_strdup_printf("erf: populate_interface_info called with state->if_map NULL"); + return -1; + } /* Section ID of interface is defined to match ERF interface id. */ if_num = state->sectionid - 1; @@ -2766,7 +2836,10 @@ static int populate_interface_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo /* If the interface is valid but uninitialized, create it */ if (interface_index == -1) { - interface_index = erf_populate_interface(erf_priv, wth, pseudo_header, state->if_map->host_id, state->if_map->source_id, (guint8) if_num); + interface_index = erf_populate_interface(erf_priv, wth, pseudo_header, state->if_map->host_id, state->if_map->source_id, (guint8) if_num, err, err_info); + if (interface_index == -1) { + return -1; + } } } @@ -2778,6 +2851,8 @@ static int populate_interface_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo /* timing/unknown port */ return 0; } else { + *err = WTAP_ERR_INTERNAL; + *err_info = g_strdup_printf("erf: populate_interface_info got interface_index %d < 0 and != -2", interface_index); return -1; } } @@ -2904,7 +2979,7 @@ static int populate_interface_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo return 1; } -static int populate_stream_info(erf_t *erf_priv _U_, wtap *wth, union wtap_pseudo_header *pseudo_header, struct erf_meta_read_state *state) +static int populate_stream_info(erf_t *erf_priv _U_, wtap *wth, union wtap_pseudo_header *pseudo_header, struct erf_meta_read_state *state, int *err, gchar **err_info) { struct erf_meta_tag tag = {0, 0, NULL}; guint32 tagtotallength; @@ -2918,8 +2993,26 @@ static int populate_stream_info(erf_t *erf_priv _U_, wtap *wth, union wtap_pseud guint32 remaining_len_tmp; struct erf_if_info* if_info = NULL; - if (!wth || !pseudo_header || !state || !state->if_map) + if (!wth) { + *err = WTAP_ERR_INTERNAL; + *err_info = g_strdup_printf("erf: populate_stream_info called with wth NULL"); return -1; + } + if (!pseudo_header) { + *err = WTAP_ERR_INTERNAL; + *err_info = g_strdup_printf("erf: populate_stream_info called with pseudo_header NULL"); + return -1; + } + if (!state) { + *err = WTAP_ERR_INTERNAL; + *err_info = g_strdup_printf("erf: populate_stream_info called with state NULL"); + return -1; + } + if (!state->if_map) { + *err = WTAP_ERR_INTERNAL; + *err_info = g_strdup_printf("erf: populate_stream_info called with state->if_map NULL"); + return -1; + } tag_ptr_tmp = state->tag_ptr; remaining_len_tmp = state->remaining_len; @@ -3042,14 +3135,27 @@ static int populate_stream_info(erf_t *erf_priv _U_, wtap *wth, union wtap_pseud return 1; } -static int populate_anchor_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo_header *pseudo_header, struct erf_meta_read_state *state, GPtrArray *anchor_mappings_to_update) { +static int populate_anchor_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo_header *pseudo_header, struct erf_meta_read_state *state, GPtrArray *anchor_mappings_to_update, int *err, gchar **err_info) { struct erf_meta_tag tag = {0, 0, NULL}; guint32 tagtotallength; gchar *comment_ptr = NULL; guint i = 0; - if (!wth || !state || !pseudo_header) + if (!wth) { + *err = WTAP_ERR_INTERNAL; + *err_info = g_strdup_printf("erf: populate_anchor_info called with wth NULL"); return -1; + } + if (!state) { + *err = WTAP_ERR_INTERNAL; + *err_info = g_strdup_printf("erf: populate_anchor_info called with state NULL"); + return -1; + } + if (!pseudo_header) { + *err = WTAP_ERR_INTERNAL; + *err_info = g_strdup_printf("erf: populate_anchor_info called with pseudo_header NULL"); + return -1; + } if (!anchor_mappings_to_update || anchor_mappings_to_update->len == 0) return 0; @@ -3106,7 +3212,7 @@ static int populate_anchor_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo_he } /* Populates the capture and interface information for display on the Capture File Properties */ -static int populate_summary_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo_header *pseudo_header, Buffer *buf, guint32 packet_size, GPtrArray *anchor_mappings_to_update) +static int populate_summary_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo_header *pseudo_header, Buffer *buf, guint32 packet_size, GPtrArray *anchor_mappings_to_update, int *err, gchar **err_info) { struct erf_meta_read_state state = {0}; struct erf_meta_read_state *state_post = NULL; @@ -3118,8 +3224,21 @@ static int populate_summary_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo_h struct erf_meta_tag tag = {0, 0, NULL}; guint32 tagtotallength; - if (!erf_priv || !wth || !pseudo_header) + if (!wth) { + *err = WTAP_ERR_INTERNAL; + *err_info = g_strdup_printf("erf: populate_summary_info called with wth NULL"); return -1; + } + if (!pseudo_header) { + *err = WTAP_ERR_INTERNAL; + *err_info = g_strdup_printf("erf: populate_summary_info called with pseudo_header NULL"); + return -1; + } + if (!erf_priv) { + *err = WTAP_ERR_INTERNAL; + *err_info = g_strdup_printf("erf: populate_summary_info called with erf_priv NULL"); + return -1; + } erf_get_source_from_header(pseudo_header, &host_id, &source_id); @@ -3230,7 +3349,10 @@ static int populate_summary_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo_h */ if (state.sectionid & 0x8000) { if(state.sectiontype & (ERF_META_SECTION_INFO)) { - populate_anchor_info(erf_priv, wth, pseudo_header, &state, anchor_mappings_to_update); + /* TODO: do we care if it returns 0 or 1? */ + if (populate_anchor_info(erf_priv, wth, pseudo_header, &state, anchor_mappings_to_update, err, err_info) < 0) { + return -1; + } } continue; } @@ -3243,14 +3365,22 @@ static int populate_summary_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo_h switch (state.sectiontype) { case ERF_META_SECTION_CAPTURE: case ERF_META_SECTION_HOST: - /* TODO: use return code */ - populate_capture_host_info(erf_priv, wth, pseudo_header, &state); + /* TODO: do we care if it returns 0 or 1? */ + if (populate_capture_host_info(erf_priv, wth, pseudo_header, &state, err, err_info) < 0) { + return -1; + } break; case ERF_META_SECTION_MODULE: - populate_module_info(erf_priv, wth, pseudo_header, &state); + /* TODO: do we care if it returns 0 or 1? */ + if (populate_module_info(erf_priv, wth, pseudo_header, &state, err, err_info) < 0) { + return -1; + } break; case ERF_META_SECTION_INTERFACE: - populate_interface_info(erf_priv, wth, pseudo_header, &state); + /* TODO: do we care if it returns 0 or 1? */ + if (populate_interface_info(erf_priv, wth, pseudo_header, &state, err, err_info) < 0) { + return -1; + } break; case ERF_META_SECTION_STREAM: /* @@ -3275,7 +3405,11 @@ static int populate_summary_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo_h state_post = (struct erf_meta_read_state*) item->data; switch (state_post->sectiontype) { case ERF_META_SECTION_STREAM: - populate_stream_info(erf_priv, wth, pseudo_header, state_post); + if (populate_stream_info(erf_priv, wth, pseudo_header, state_post, err, err_info) < 0) { + g_list_foreach(post_list, erf_free_data, NULL); + g_list_free(post_list); + return -1; + } break; } } while ((item = g_list_next(item))); diff --git a/wiretap/libpcap.c b/wiretap/libpcap.c index a5518ccf08..204ffc0c2b 100644 --- a/wiretap/libpcap.c +++ b/wiretap/libpcap.c @@ -910,7 +910,7 @@ libpcap_read_packet(wtap *wth, FILE_T fh, wtap_rec *rec, int interface_id; /* Set interface ID for ERF format */ rec->presence_flags |= WTAP_HAS_INTERFACE_ID; - if ((interface_id = erf_populate_interface_from_header((erf_t*) libpcap->encap_priv, wth, &rec->rec_header.packet_header.pseudo_header)) < 0) + if ((interface_id = erf_populate_interface_from_header((erf_t*) libpcap->encap_priv, wth, &rec->rec_header.packet_header.pseudo_header, err, err_info)) < 0) return FALSE; rec->rec_header.packet_header.interface_id = (guint) interface_id;