Skip to content

Commit 3beeefd

Browse files
plugins/ocp: Prevent Seg Fault during Telemetry log Parsing
Invalid length values in the OCP DA 1 and 2 Telemetry Event FIFO entries caused the OCP internal-log command to seg fault. This commit will add checks for invalid lengths and abort the parsing if found. Signed-off-by: jeff-lien-sndk <[email protected]> Reviewed-by: brandon-paupore-sndk <[email protected]>
1 parent bcf72cf commit 3beeefd

File tree

3 files changed

+53
-41
lines changed

3 files changed

+53
-41
lines changed

plugins/ocp/ocp-nvme.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#if !defined(OCP_NVME) || defined(CMD_HEADER_MULTI_READ)
1212
#define OCP_NVME
1313

14-
#define OCP_PLUGIN_VERSION "2.15.3"
14+
#define OCP_PLUGIN_VERSION "2.16.0"
1515
#include "cmd.h"
1616

1717
PLUGIN(NAME("ocp", "OCP cloud SSD extensions", OCP_PLUGIN_VERSION),

plugins/ocp/ocp-telemetry-decode.c

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,7 @@ int parse_ocp_telemetry_string_log(int event_fifo_num, int identifier, int debug
674674
}
675675

676676
#ifdef CONFIG_JSONC
677-
void parse_time_stamp_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
677+
int parse_time_stamp_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
678678
struct json_object *pevent_descriptor_obj, __u8 *pevent_specific_data,
679679
struct json_object *pevent_fifos_object, FILE *fp)
680680
{
@@ -704,7 +704,8 @@ void parse_time_stamp_event(struct nvme_ocp_telemetry_event_descriptor *pevent_d
704704
parse_ocp_telemetry_string_log(0, vu_event_id,
705705
pevent_descriptor->debug_event_class_type,
706706
VU_EVENT_STRING, description_str);
707-
}
707+
} else if (pevent_descriptor->event_data_size < 2)
708+
return -1;
708709

709710
if (pevent_fifos_object != NULL) {
710711
json_add_formatted_var_size_str(pevent_descriptor_obj, STR_CLASS_SPECIFIC_DATA,
@@ -736,9 +737,11 @@ void parse_time_stamp_event(struct nvme_ocp_telemetry_event_descriptor *pevent_d
736737
}
737738
}
738739
}
740+
741+
return 0;
739742
}
740743

741-
void parse_pcie_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
744+
int parse_pcie_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
742745
struct json_object *pevent_descriptor_obj, __u8 *pevent_specific_data,
743746
struct json_object *pevent_fifos_object, FILE *fp)
744747
{
@@ -768,7 +771,8 @@ void parse_pcie_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descrip
768771
parse_ocp_telemetry_string_log(0, vu_event_id,
769772
pevent_descriptor->debug_event_class_type,
770773
VU_EVENT_STRING, description_str);
771-
}
774+
} else if (pevent_descriptor->event_data_size < 1)
775+
return -1;
772776

773777
if (pevent_fifos_object != NULL) {
774778
json_add_formatted_var_size_str(pevent_descriptor_obj, STR_CLASS_SPECIFIC_DATA,
@@ -800,9 +804,11 @@ void parse_pcie_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descrip
800804
}
801805
}
802806
}
807+
808+
return 0;
803809
}
804810

805-
void parse_nvme_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
811+
int parse_nvme_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
806812
struct json_object *pevent_descriptor_obj, __u8 *pevent_specific_data,
807813
struct json_object *pevent_fifos_object, FILE *fp)
808814
{
@@ -833,7 +839,8 @@ void parse_nvme_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descrip
833839
pevent_descriptor->debug_event_class_type,
834840
VU_EVENT_STRING,
835841
description_str);
836-
}
842+
} else if (pevent_descriptor->event_data_size < 2)
843+
return -1;
837844

838845
if (pevent_fifos_object != NULL) {
839846
json_add_formatted_var_size_str(pevent_descriptor_obj, STR_CLASS_SPECIFIC_DATA,
@@ -865,6 +872,8 @@ void parse_nvme_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descrip
865872
}
866873
}
867874
}
875+
876+
return 0;
868877
}
869878

870879
void parse_common_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
@@ -907,7 +916,7 @@ void parse_common_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descr
907916
}
908917
}
909918

910-
void parse_media_wear_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
919+
int parse_media_wear_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
911920
struct json_object *pevent_descriptor_obj, __u8 *pevent_specific_data,
912921
struct json_object *pevent_fifos_object, FILE *fp)
913922
{
@@ -939,7 +948,8 @@ void parse_media_wear_event(struct nvme_ocp_telemetry_event_descriptor *pevent_d
939948
pevent_descriptor->debug_event_class_type,
940949
VU_EVENT_STRING,
941950
description_str);
942-
}
951+
} else if (pevent_descriptor->event_data_size < 3)
952+
return -1;
943953

944954
if (pevent_fifos_object != NULL) {
945955
json_add_formatted_var_size_str(pevent_descriptor_obj, STR_CLASS_SPECIFIC_DATA,
@@ -971,6 +981,8 @@ void parse_media_wear_event(struct nvme_ocp_telemetry_event_descriptor *pevent_d
971981
}
972982
}
973983
}
984+
985+
return 0;
974986
}
975987

976988
int parse_event_fifo(unsigned int fifo_num, unsigned char *pfifo_start,
@@ -982,7 +994,7 @@ int parse_event_fifo(unsigned int fifo_num, unsigned char *pfifo_start,
982994
return -1;
983995
}
984996

985-
int status = 0;
997+
int status = 0, ret = 0;
986998
unsigned int event_fifo_number = fifo_num + 1;
987999
char *description = (char *)malloc((40 + 1) * sizeof(char));
9881000

@@ -1095,21 +1107,21 @@ int parse_event_fifo(unsigned int fifo_num, unsigned char *pfifo_start,
10951107

10961108
switch (pevent_descriptor->debug_event_class_type) {
10971109
case TIME_STAMP_CLASS_TYPE:
1098-
parse_time_stamp_event(pevent_descriptor,
1110+
ret = parse_time_stamp_event(pevent_descriptor,
10991111
pevent_descriptor_obj,
11001112
pevent_specific_data,
11011113
pevent_fifos_object,
11021114
fp);
11031115
break;
11041116
case PCIE_CLASS_TYPE:
1105-
parse_pcie_event(pevent_descriptor,
1117+
ret = parse_pcie_event(pevent_descriptor,
11061118
pevent_descriptor_obj,
11071119
pevent_specific_data,
11081120
pevent_fifos_object,
11091121
fp);
11101122
break;
11111123
case NVME_CLASS_TYPE:
1112-
parse_nvme_event(pevent_descriptor,
1124+
ret = parse_nvme_event(pevent_descriptor,
11131125
pevent_descriptor_obj,
11141126
pevent_specific_data,
11151127
pevent_fifos_object,
@@ -1125,9 +1137,10 @@ int parse_event_fifo(unsigned int fifo_num, unsigned char *pfifo_start,
11251137
pevent_specific_data,
11261138
pevent_fifos_object,
11271139
fp);
1140+
ret = 0;
11281141
break;
11291142
case MEDIA_WEAR_CLASS_TYPE:
1130-
parse_media_wear_event(pevent_descriptor,
1143+
ret = parse_media_wear_event(pevent_descriptor,
11311144
pevent_descriptor_obj,
11321145
pevent_specific_data,
11331146
pevent_fifos_object,
@@ -1138,6 +1151,16 @@ int parse_event_fifo(unsigned int fifo_num, unsigned char *pfifo_start,
11381151
break;
11391152
}
11401153

1154+
if (ret) {
1155+
fprintf(stderr, "ERROR : OCP : Invalid NVMe Event FIFO entry. FIFO: %d, offset: 0x%x\n",
1156+
fifo_num, offset_to_move);
1157+
fprintf(stderr, "ERROR : OCP : Type: 0x%02x, ID: 0x%04x, Size: 0x%02x\n",
1158+
pevent_descriptor->debug_event_class_type,
1159+
pevent_descriptor->event_id,
1160+
pevent_descriptor->event_data_size);
1161+
goto free_desc;
1162+
}
1163+
11411164
if (pevent_descriptor_obj != NULL && pevent_fifo_array != NULL)
11421165
json_array_add_value_object(pevent_fifo_array,
11431166
pevent_descriptor_obj);
@@ -1214,8 +1237,9 @@ int parse_event_fifo(unsigned int fifo_num, unsigned char *pfifo_start,
12141237
json_object_add_value_array(pevent_fifos_object, event_fifo_name,
12151238
pevent_fifo_array);
12161239

1240+
free_desc:
12171241
free(description);
1218-
return 0;
1242+
return ret;
12191243
}
12201244

12211245
int parse_event_fifos(struct json_object *root, struct nvme_ocp_telemetry_offsets *poffsets,
@@ -1610,10 +1634,8 @@ int print_ocp_telemetry_normal(struct ocp_telemetry_parse_options *options)
16101634
fprintf(fp, "%s\n", STR_DA_1_EVENT_FIFO_INFO);
16111635
fprintf(fp, STR_LINE);
16121636
status = parse_event_fifos(NULL, &offsets, fp);
1613-
if (status != 0) {
1614-
nvme_show_error("status: %d\n", status);
1637+
if (status != 0)
16151638
return -1;
1616-
}
16171639

16181640
//Set the DA to 2
16191641
if (options->data_area == 2) {
@@ -1632,10 +1654,8 @@ int print_ocp_telemetry_normal(struct ocp_telemetry_parse_options *options)
16321654
fprintf(fp, "%s\n", STR_DA_2_EVENT_FIFO_INFO);
16331655
fprintf(fp, STR_LINE);
16341656
status = parse_event_fifos(NULL, &offsets, fp);
1635-
if (status != 0) {
1636-
nvme_show_error("status: %d\n", status);
1657+
if (status != 0)
16371658
return -1;
1638-
}
16391659
}
16401660

16411661
fprintf(fp, STR_LINE);
@@ -1719,10 +1739,8 @@ int print_ocp_telemetry_normal(struct ocp_telemetry_parse_options *options)
17191739
printf("%s\n", STR_DA_1_EVENT_FIFO_INFO);
17201740
printf(STR_LINE);
17211741
status = parse_event_fifos(NULL, &offsets, NULL);
1722-
if (status != 0) {
1723-
nvme_show_error("status: %d\n", status);
1742+
if (status != 0)
17241743
return -1;
1725-
}
17261744

17271745
//Set the DA to 2
17281746
if (options->data_area == 2) {
@@ -1740,10 +1758,8 @@ int print_ocp_telemetry_normal(struct ocp_telemetry_parse_options *options)
17401758
printf("%s\n", STR_DA_2_EVENT_FIFO_INFO);
17411759
printf(STR_LINE);
17421760
status = parse_event_fifos(NULL, &offsets, NULL);
1743-
if (status != 0) {
1744-
nvme_show_error("status: %d\n", status);
1761+
if (status != 0)
17451762
return -1;
1746-
}
17471763
}
17481764

17491765
printf(STR_LINE);
@@ -1826,10 +1842,8 @@ int print_ocp_telemetry_json(struct ocp_telemetry_parse_options *options)
18261842

18271843
//Data Area 1 Event FIFOs
18281844
status = parse_event_fifos(root, &offsets, NULL);
1829-
if (status != 0) {
1830-
nvme_show_error("status: %d\n", status, NULL);
1845+
if (status != 0)
18311846
return -1;
1832-
}
18331847

18341848
if (options->data_area == 2) {
18351849
//Set the DA to 2
@@ -1843,10 +1857,8 @@ int print_ocp_telemetry_json(struct ocp_telemetry_parse_options *options)
18431857

18441858
//Data Area 2 Event FIFOs
18451859
status = parse_event_fifos(root, &offsets, NULL);
1846-
if (status != 0) {
1847-
nvme_show_error("status: %d\n", status);
1860+
if (status != 0)
18481861
return -1;
1849-
}
18501862
}
18511863

18521864
if (options->output_file != NULL) {

plugins/ocp/ocp-telemetry-decode.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,9 +1389,9 @@ int get_vu_event_id_ascii_string(int identifier, int debug_event_class, char *de
13891389
* @param pevent_fifos_object, event fifos json object pointer
13901390
* @param fp, input file pointer
13911391
*
1392-
* @return
1392+
* @return 0 success
13931393
*/
1394-
void parse_time_stamp_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
1394+
int parse_time_stamp_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
13951395
struct json_object *pevent_descriptor_obj, __u8 *pevent_specific_data,
13961396
struct json_object *pevent_fifos_object, FILE *fp);
13971397

@@ -1404,9 +1404,9 @@ void parse_time_stamp_event(struct nvme_ocp_telemetry_event_descriptor *pevent_d
14041404
* @param pevent_fifos_object, event fifos json object pointer
14051405
* @param fp, input file pointer
14061406
*
1407-
* @return
1407+
* @return 0 success
14081408
*/
1409-
void parse_pcie_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
1409+
int parse_pcie_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
14101410
struct json_object *pevent_descriptor_obj, __u8 *pevent_specific_data,
14111411
struct json_object *pevent_fifos_object, FILE *fp);
14121412

@@ -1419,9 +1419,9 @@ void parse_pcie_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descrip
14191419
* @param pevent_fifos_object, event fifos json object pointer
14201420
* @param fp, input file pointer
14211421
*
1422-
* @return
1422+
* @return 0 success
14231423
*/
1424-
void parse_nvme_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
1424+
int parse_nvme_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
14251425
struct json_object *pevent_descriptor_obj, __u8 *pevent_specific_data,
14261426
struct json_object *pevent_fifos_object, FILE *fp);
14271427

@@ -1449,9 +1449,9 @@ void parse_common_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descr
14491449
* @param pevent_fifos_object, event fifos json object pointer
14501450
* @param fp, input file pointer
14511451
*
1452-
* @return
1452+
* @return 0 success
14531453
*/
1454-
void parse_media_wear_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
1454+
int parse_media_wear_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
14551455
struct json_object *pevent_descriptor_obj, __u8 *pevent_specific_data,
14561456
struct json_object *pevent_fifos_object, FILE *fp);
14571457
#endif /* OCP_TELEMETRY_DECODE_H */

0 commit comments

Comments
 (0)