Skip to content

NULL Pointer Dereference in H5O__cache_chk_serialize #5384

Open
@sae-as-me

Description

@sae-as-me

Affected Projects

hdf5 v1.14.6 (https://github.com/HDFGroup/hdf5)

Problem Type

CWE-476: NULL Pointer Dereference

Description

Summary

A null pointer read vulnerability was discovered in the H5O__cache_chk_serialize function within the HDF5 Library. This issue occurs when processing certain files, leading to a potential application crash.

Details

The vulnerability arises in the H5O__cache_chk_serialize function defined in src/H5Ocache.c at line 788.
The reason is that the function H5O__cache_chk_serialize did not check the validity of chk_proxy->oh->chunk[chk_proxy->chunkno].image before calling H5MM_memcpy, resulting in a null pointer dereference read.

static herr_t
H5O__cache_chk_serialize(const H5F_t *f, void *image, size_t len, void *_thing)
{
    H5O_chunk_proxy_t *chk_proxy = (H5O_chunk_proxy_t *)_thing; /* Object header chunk to serialize */
    herr_t             ret_value = SUCCEED;

    FUNC_ENTER_PACKAGE

    assert(f);
    assert(image);
    assert(chk_proxy);
    assert(chk_proxy->cache_info.type == H5AC_OHDR_CHK);
    assert(chk_proxy->oh);
    assert(chk_proxy->oh->chunk[chk_proxy->chunkno].size == len);

    /* Serialize messages for this chunk */
    if (H5O__chunk_serialize(f, chk_proxy->oh, chk_proxy->chunkno) < 0)
        HGOTO_ERROR(H5E_OHDR, H5E_CANTSERIALIZE, FAIL,
                    "unable to serialize object header continuation chunk");

    /* copy the chunk into the image -- this is potentially expensive.
     * Can we rework things so that the chunk and the cache share a buffer?
     */
    /* Ensure len does not exceed the size of the source buffer */
    if (len > chk_proxy->oh->chunk[chk_proxy->chunkno].size)
        HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, FAIL, "buffer overflow detected");

    H5MM_memcpy(image, chk_proxy->oh->chunk[chk_proxy->chunkno].image, len);    //read null pointer

done:
    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O__cache_chk_serialize() */

Image

Image

PoC

Steps to reproduce:

  1. Clone the hdf5 repository and build it using the following commands :
export CC='clang'
export CXX='clang++'
export CFLAGS='-fsanitize=address -g'
export CXXFLAGS='-fsanitize=address -g'

export LDFLAGS="${CFLAGS}"
export CMAKE_C_FLAGS="${CC} ${CFLAGS}"
export CMAKE_CXX_FLAGS="${CXX} ${CXXFLAGS}"

mkdir build-dir
cd build-dir
cmake -G "Unix Makefiles" \
    -DCMAKE_BUILD_TYPE:STRING=Release \
    -DBUILD_SHARED_LIBS:BOOL=OFF \
    -DBUILD_TESTING:BOOL=OFF \
    -DCMAKE_VERBOSE_MAKEFILES:BOOL=ON \
    -DHDF5_BUILD_EXAMPLES:BOOL=OFF \
    -DHDF5_BUILD_TOOLS:BOOL=OFF \
    -DHDF5_ENABLE_SANITIZERS:BOOL=ON \
    -DHDF5_ENABLE_Z_LIB_SUPPORT:BOOL=ON \
    ..

cmake --build . --verbose --config Release -j$(nproc)
  1. Compile the fuzzer:
  • harness h5_extended_fuzzer.c from oss-fuzz:
#include "hdf5.h"

#include <unistd.h>

extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
    char filename[256];
    sprintf(filename, "/tmp/libfuzzer.%d", getpid());

    FILE *fp = fopen(filename, "wb");
    if (!fp) {
        return 0;
    }
    fwrite(data, size, 1, fp);
    fclose(fp);

    hid_t fuzz_h5_id = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT);
    if (fuzz_h5_id != H5I_INVALID_HID) {
      hid_t  dataset_id = H5Dopen2(fuzz_h5_id, "dsetname", H5P_DEFAULT);
      if (dataset_id != H5I_INVALID_HID) {
          hid_t attribute_id = H5Aopen_name(dataset_id, "theattr");
          if (attribute_id != H5I_INVALID_HID) {
            H5Aclose(attribute_id);
          }
          H5Dclose(dataset_id);
      }
      H5Fclose(fuzz_h5_id);
    }
    return 0;
}
export LIB_FUZZING_ENGINE='-fsanitize=fuzzer'

$CC $CFLAGS  -std=c99 -c \
  -I$SRC/hdf5/src -I$SRC/hdf5/build-dir/src -I./src/H5FDsubfiling/ \
  $SRC/h5_extended_fuzzer.c
$CXX $CXXFLAGS $LIB_FUZZING_ENGINE h5_extended_fuzzer.o ./build-dir/bin/libhdf5.a -lz -o $OUT/h5_extended_fuzzer
  1. Run the fuzzer to trigger the segmentation fault:

H5O__cache_chk_serialize-npd.zip

./h5_extended_fuzzer ./H5O__cache_chk_serialize-npd

This will cause AddressSanitizer to report a segmentation fault during the execution of the post-processing logic.

ASAN Report

Running: ./H5O__cache_chk_serialize-npd
AddressSanitizer:DEADLYSIGNAL
=================================================================
==443==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7c53e78ca881 bp 0x7ffdcc9df6f0 sp 0x7ffdcc9deeb8 T0)
==443==The signal is caused by a READ memory access.
==443==Hint: address points to the zero page.
    #0 0x7c53e78ca881 in memcpy string/../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:222
    #1 0x5fbdc39da031 in __asan_memcpy (/fuzz/fuzzers/cs/h5_extended_fuzzer+0x2c8031) (BuildId: 4f0aadfc2da7074efe3c033dd7d4d5301b6fc3b1)
    #2 0x5fbdc3d05736 in H5O__cache_chk_serialize /fuzz/project/hdf5/src/H5Ocache.c:788:5
    #3 0x5fbdc3a88e7c in H5C__generate_image /fuzz/project/hdf5/src/H5Centry.c:374:9
    #4 0x5fbdc3a856a1 in H5C__flush_single_entry /fuzz/project/hdf5/src/H5Centry.c:553:17
    #5 0x5fbdc3aadf41 in H5C__flush_ring /fuzz/project/hdf5/src/H5Cint.c:1748:25
    #6 0x5fbdc3a7f3fa in H5C_flush_cache /fuzz/project/hdf5/src/H5C.c:710:17
    #7 0x5fbdc3ac18bc in H5C_flush_tagged_entries /fuzz/project/hdf5/src/H5Ctag.c:654:9
    #8 0x5fbdc3a476dc in H5AC_flush_tagged_metadata /fuzz/project/hdf5/src/H5AC.c:2208:9
    #9 0x5fbdc3b92221 in H5F_flush_tagged_metadata /fuzz/project/hdf5/src/H5Fio.c:421:9
    #10 0x5fbdc3b81432 in H5F_open /fuzz/project/hdf5/src/H5Fint.c:2211:17
    #11 0x5fbdc42faa5b in H5VL__native_file_open /fuzz/project/hdf5/src/H5VLnative_file.c:127:9
    #12 0x5fbdc42c7015 in H5VL__file_open /fuzz/project/hdf5/src/H5VLcallback.c:3714:25
    #13 0x5fbdc42c686a in H5VL_file_open /fuzz/project/hdf5/src/H5VLcallback.c:3832:30
    #14 0x5fbdc3b63b19 in H5F__open_api_common /fuzz/project/hdf5/src/H5F.c:780:29
    #15 0x5fbdc3b6326b in H5Fopen /fuzz/project/hdf5/src/H5F.c:820:22
    #16 0x5fbdc3a1817c in LLVMFuzzerTestOneInput /fuzz/project/h5_extended_fuzzer.c:29:24
    #17 0x5fbdc393e5a3 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/fuzz/fuzzers/cs/h5_extended_fuzzer+0x22c5a3) (BuildId: 4f0aadfc2da7074efe3c033dd7d4d5301b6fc3b1)
    #18 0x5fbdc392831f in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) (/fuzz/fuzzers/cs/h5_extended_fuzzer+0x21631f) (BuildId: 4f0aadfc2da7074efe3c033dd7d4d5301b6fc3b1)
    #19 0x5fbdc392e076 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/fuzz/fuzzers/cs/h5_extended_fuzzer+0x21c076) (BuildId: 4f0aadfc2da7074efe3c033dd7d4d5301b6fc3b1)
    #20 0x5fbdc3957e92 in main (/fuzz/fuzzers/cs/h5_extended_fuzzer+0x245e92) (BuildId: 4f0aadfc2da7074efe3c033dd7d4d5301b6fc3b1)
    #21 0x7c53e782fd8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #22 0x7c53e782fe3f in __libc_start_main csu/../csu/libc-start.c:392:3
    #23 0x5fbdc3922be4 in _start (/fuzz/fuzzers/cs/h5_extended_fuzzer+0x210be4) (BuildId: 4f0aadfc2da7074efe3c033dd7d4d5301b6fc3b1)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV string/../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:222 in memcpy
==443==ABORTING

Metadata

Metadata

Assignees

Labels

Component - C LibraryCore C library issues (usually in the src directory)HDFG-internalInternally coded for use by the HDF GroupPriority - 0. BlockerThis MUST be merged for the release to happenType - SecuritySecurity issues, including library crashers and memory leaks

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions