summaryrefslogtreecommitdiffstats
path: root/test/ohdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/ohdr.c')
-rw-r--r--test/ohdr.c129
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)