Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/H5Zfletcher32.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ H5Z__filter_fletcher32(unsigned flags, size_t H5_ATTR_UNUSED cd_nelmts,
assert(sizeof(uint32_t) >= 4);

if (flags & H5Z_FLAG_REVERSE) { /* Read */
/* A Fletcher32-filtered buffer must contain at least the trailing
* checksum. Reject anything smaller to avoid a size_t underflow
* when computing the data length.
*/
if (nbytes < FLETCHER_LEN)
HGOTO_ERROR(H5E_STORAGE, H5E_OVERFLOW, 0,
"fletcher32 filter input buffer too small to contain checksum");

/* Do checksum if it's enabled for read; otherwise skip it
* to save performance. */
if (!(flags & H5Z_FLAG_SKIP_EDC)) {
Expand Down
142 changes: 92 additions & 50 deletions src/H5Znbit.c

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions test/CMakeTests.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ endforeach ()
set (HDF5_REFERENCE_TEST_FILES
aggr.h5
bad_compound.h5
bad_fletcher32.h5
bad_nbit_decompress.h5
bad_nbit_params.h5
bad_offset.h5
be_data.h5
be_extlink1.h5
Expand Down Expand Up @@ -1165,6 +1168,7 @@ endmacro ()

# generator executables
set (H5_GENERATORS
gen_bad_filters
gen_bad_offset
gen_bad_ohdr
gen_bogus
Expand Down
97 changes: 97 additions & 0 deletions test/dsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -8031,6 +8031,102 @@ test_filters_endianess(void)
return FAIL;
} /* end test_filters_endianess() */

/*-------------------------------------------------------------------------
* Function: test_filter_bad_params
*
* Purpose: Reads datasets from crafted files whose filter metadata has been
* deliberately corrupted, verifying that the library rejects them
* gracefully instead of crashing. These are regression tests for
* GitHub issues #6489 (N-Bit filter: NULL parameter array and
* compressed-buffer over-read) and #6490 (Fletcher32 filter:
* checksum length underflow). The files are produced by
* gen_bad_filters.c.
*
* Return: Success: 0
* Failure: -1
*
*-------------------------------------------------------------------------
*/
static herr_t
test_filter_bad_params(void)
{
/* Each entry: crafted file name and the dataset whose read must fail. */
static const struct {
const char *file;
const char *dset;
} cases[] = {
{"bad_nbit_params.h5", "Nbit_float_data_le"},
{"bad_nbit_decompress.h5", "Nbit_float_data_le"},
{"bad_fletcher32.h5", "Fletcher_float_data_be"},
};
hid_t fid = H5I_INVALID_HID;
hid_t did = H5I_INVALID_HID;
hid_t sid = H5I_INVALID_HID;
void *buf = NULL;
size_t i;

TESTING("filter decode with corrupted filter metadata");

for (i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
const char *data_file = H5_get_srcdir_filename(cases[i].file);
hssize_t npoints;
herr_t status;

if ((fid = H5Fopen(data_file, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
FAIL_STACK_ERROR;
if ((did = H5Dopen2(fid, cases[i].dset, H5P_DEFAULT)) < 0)
FAIL_STACK_ERROR;
if ((sid = H5Dget_space(did)) < 0)
FAIL_STACK_ERROR;
if ((npoints = H5Sget_simple_extent_npoints(sid)) <= 0)
FAIL_STACK_ERROR;
if (NULL == (buf = calloc((size_t)npoints, sizeof(float))))
TEST_ERROR;

/* The corrupted filter metadata must make the read fail cleanly
* (return a negative value) rather than crash. */
H5E_BEGIN_TRY
{
status = H5Dread(did, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf);
}
H5E_END_TRY

if (status >= 0) {
H5_FAILED();
printf(" reading dataset \"%s\" from \"%s\" should have failed\n", cases[i].dset,
cases[i].file);
goto error;
}

free(buf);
buf = NULL;
if (H5Sclose(sid) < 0)
FAIL_STACK_ERROR;
sid = H5I_INVALID_HID;
if (H5Dclose(did) < 0)
FAIL_STACK_ERROR;
did = H5I_INVALID_HID;
if (H5Fclose(fid) < 0)
FAIL_STACK_ERROR;
fid = H5I_INVALID_HID;
}

PASSED();

return SUCCEED;

error:
free(buf);
H5E_BEGIN_TRY
{
H5Sclose(sid);
H5Dclose(did);
H5Fclose(fid);
}
H5E_END_TRY
return FAIL;
} /* end test_filter_bad_params() */

/*-------------------------------------------------------------------------
* Function: test_zero_dims
*
Expand Down Expand Up @@ -19064,6 +19160,7 @@ main(void)

if (driver_is_default_compatible) {
nerrors += (test_filters_endianess() < 0 ? 1 : 0);
nerrors += (test_filter_bad_params() < 0 ? 1 : 0);
}

nerrors += (test_zero_dims(file) < 0 ? 1 : 0);
Expand Down
Loading
Loading