diff options
Diffstat (limited to 'test/ohdr.c')
-rw-r--r-- | test/ohdr.c | 129 |
1 files changed, 108 insertions, 21 deletions
diff --git a/test/ohdr.c b/test/ohdr.c index 54040e1..60d32b7 100644 --- a/test/ohdr.c +++ b/test/ohdr.c @@ -34,6 +34,13 @@ #define H5G_FRIEND /* suppress error about including H5Gpkg */ #include "H5Gpkg.h" +/* + * This file needs to access private routines from the H5FD package. + */ +#define H5FD_FRIEND /* suppress error about including H5FDpkg */ +#define H5FD_TESTING +#include "H5FDpkg.h" + const char *FILENAME[] = {"ohdr", "ohdr_min_a", "ohdr_min_b", NULL}; /* used for object header size comparison */ @@ -296,7 +303,10 @@ test_ohdr_cache(char *filename, hid_t fapl) return SUCCEED; error: - H5E_BEGIN_TRY { H5Fclose(file); } + H5E_BEGIN_TRY + { + H5Fclose(file); + } H5E_END_TRY; return FAIL; @@ -454,6 +464,59 @@ error: } /* test_ohdr_swmr() */ /* + * Tests bad object header messages. + * + * Currently tests for CVE-2020-10810 fixes but can be expanded to handle + * other CVE badness. + */ + +/* This is a generated file that can be obtained from: + * + * https://nvd.nist.gov/vuln/detail/CVE-2020-10810 + * + * It was formerly named H5AC_unpin_entry_POC + */ +#define CVE_2020_10810_FILENAME "cve_2020_10810.h5" + +static herr_t +test_ohdr_badness(hid_t fapl) +{ + hid_t fid = H5I_INVALID_HID; + + /* CVE-2020-10810 involved a malformed fsinfo message + * This test ensures the fundamental problem is fixed. Running it under + * valgrind et al. will ensure that the memory leaks and invalid access + * are fixed. + */ + TESTING("Fix for CVE-2020-10810"); + + H5E_BEGIN_TRY + { + /* This should fail due to the malformed fsinfo message. It should + * fail gracefully and not segfault. + */ + fid = H5Fopen(CVE_2020_10810_FILENAME, H5F_ACC_RDWR, fapl); + } + H5E_END_TRY; + + if (fid >= 0) + FAIL_PUTS_ERROR("should not have been able to open malformed file"); + + PASSED(); + + return SUCCEED; + +error: + H5E_BEGIN_TRY + { + H5Fclose(fid); + } + H5E_END_TRY; + + return FAIL; +} + +/* * To test objects with unknown messages in a file with: * a) H5O_BOGUS_VALID_ID: * --the bogus_id is within the range of H5O_msg_class_g[] @@ -485,7 +548,7 @@ test_unknown(unsigned bogus_id, char *filename, hid_t fapl) done in the source directory. */ HDstrncpy(testfile, FILE_BOGUS, TESTFILE_LEN); testfile[TESTFILE_LEN - 1] = '\0'; - HDstrncat(testfile, ".copy", 5); + HDstrncat(testfile, ".copy", sizeof(testfile) - HDstrlen(testfile) - 1); /* Make a copy of the data file from svn. */ if (h5_make_local_copy(FILE_BOGUS, testfile) < 0) @@ -549,7 +612,10 @@ test_unknown(unsigned bogus_id, char *filename, hid_t fapl) TESTING("object in r/o file with unknown header message & 'fail if unknown always' flag set"); /* Attempt to open the dataset with the unknown header message, and "fail if unknown always" flag */ - H5E_BEGIN_TRY { did = H5Dopen2(loc_bogus, "Dataset3", H5P_DEFAULT); } + H5E_BEGIN_TRY + { + did = H5Dopen2(loc_bogus, "Dataset3", H5P_DEFAULT); + } H5E_END_TRY; if (did >= 0) { H5Dclose(did); @@ -713,7 +779,10 @@ test_unknown(unsigned bogus_id, char *filename, hid_t fapl) /* Attempt to open the dataset with the unknown header message, and "fail if unknown and open for write" * flag */ - H5E_BEGIN_TRY { did = H5Dopen2(loc_bogus, "Dataset2", H5P_DEFAULT); } + H5E_BEGIN_TRY + { + did = H5Dopen2(loc_bogus, "Dataset2", H5P_DEFAULT); + } H5E_END_TRY; if (did >= 0) { H5Dclose(did); @@ -725,7 +794,10 @@ test_unknown(unsigned bogus_id, char *filename, hid_t fapl) TESTING("object in r/w file with unknown header message & 'fail if unknown always' flag set"); /* Attempt to open the dataset with the unknown header message, and "fail if unknown always" flag */ - H5E_BEGIN_TRY { did = H5Dopen2(loc_bogus, "Dataset3", H5P_DEFAULT); } + H5E_BEGIN_TRY + { + did = H5Dopen2(loc_bogus, "Dataset3", H5P_DEFAULT); + } H5E_END_TRY; if (did >= 0) { H5Dclose(did); @@ -780,7 +852,7 @@ count_attributes(hid_t dset_id) * On success, stores size in `size_out` pointer. */ static herr_t -_oh_getsize(hid_t did, hsize_t *size_out) +oh_getsize(hid_t did, hsize_t *size_out) { H5O_native_info_t ninfo; @@ -803,9 +875,9 @@ oh_compare(hid_t did1, hid_t did2) hsize_t space1 = 0; hsize_t space2 = 0; - if (FAIL == _oh_getsize(did1, &space1)) + if (FAIL == oh_getsize(did1, &space1)) return -1; - if (FAIL == _oh_getsize(did2, &space2)) + if (FAIL == oh_getsize(did2, &space2)) return -2; if (space1 < space2) @@ -907,7 +979,7 @@ test_minimized_dset_ohdr_attribute_addition(hid_t fapl_id) /* Read the data back and verify */ if (H5Aread(aid, H5T_NATIVE_CHAR, out_buf) < 0) TEST_ERROR; - if (HDstrcmp(in_buf, out_buf)) + if (HDstrcmp(in_buf, out_buf) != 0) TEST_ERROR; /* modify the string attribute */ @@ -922,7 +994,7 @@ test_minimized_dset_ohdr_attribute_addition(hid_t fapl_id) /* Read the data back and verify */ if (H5Aread(aid, H5T_NATIVE_CHAR, out_buf) < 0) TEST_ERROR; - if (HDstrcmp(in_buf, out_buf)) + if (HDstrcmp(in_buf, out_buf) != 0) TEST_ERROR; /* Close */ @@ -1748,13 +1820,12 @@ main(void) herr_t ret; /* Generic return value */ /* Get the VFD to use */ - env_h5_drvr = HDgetenv("HDF5_DRIVER"); + env_h5_drvr = HDgetenv(HDF5_DRIVER); if (env_h5_drvr == NULL) env_h5_drvr = "nomatch"; /* Check for VFD which stores data in multiple files */ - single_file_vfd = (hbool_t)(HDstrcmp(env_h5_drvr, "split") && HDstrcmp(env_h5_drvr, "multi") && - HDstrcmp(env_h5_drvr, "family")); + single_file_vfd = !h5_driver_uses_multiple_files(env_h5_drvr, 0); /* Reset library */ h5_reset(); @@ -1774,7 +1845,10 @@ main(void) char msg[80]; /* Message for file format version */ /* Set version bounds before opening the file */ - H5E_BEGIN_TRY { ret = H5Pset_libver_bounds(fapl, low, high); } + H5E_BEGIN_TRY + { + ret = H5Pset_libver_bounds(fapl, low, high); + } H5E_END_TRY; if (ret < 0) /* Invalid low/high combinations */ @@ -1967,7 +2041,10 @@ main(void) if (ro != time_new) TEST_ERROR time_new = 33333333; - H5E_BEGIN_TRY { ret = H5O_msg_write(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new); } + H5E_BEGIN_TRY + { + ret = H5O_msg_write(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new); + } H5E_END_TRY; if (ret >= 0) TEST_ERROR @@ -2029,15 +2106,22 @@ main(void) } /* high */ } /* low */ + /* Verify bad ohdr message fixes work */ + test_ohdr_badness(fapl); + /* Verify symbol table messages are cached */ if (h5_verify_cached_stabs(FILENAME, fapl) < 0) TEST_ERROR - /* A test to exercise the re-read of the object header for SWMR access */ - if (test_ohdr_swmr(TRUE) < 0) - TEST_ERROR - if (test_ohdr_swmr(FALSE) < 0) - TEST_ERROR + if (H5FD__supports_swmr_test(env_h5_drvr)) { + /* A test to exercise the re-read of the object header for SWMR access */ + if (test_ohdr_swmr(TRUE) < 0) + TEST_ERROR + if (test_ohdr_swmr(FALSE) < 0) + TEST_ERROR + } + else + HDputs("Skipped SWMR tests for SWMR-incompatible VFD"); /* Pop API context */ if (api_ctx_pushed && H5CX_pop(FALSE) < 0) @@ -2050,7 +2134,10 @@ main(void) error: HDputs("*** TESTS FAILED ***"); - H5E_BEGIN_TRY { H5Fclose(file); } + H5E_BEGIN_TRY + { + H5Fclose(file); + } H5E_END_TRY; if (api_ctx_pushed) |