Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix vuln OSV-2024-381 #5202

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open

Conversation

aled-ua
Copy link
Contributor

@aled-ua aled-ua commented Jan 2, 2025

[Warning] This PR is generated by AI

  1. PR Title: Fix Heap-Buffer-Overflow Vulnerability in HDF5 - OSV-2024-381

  2. PR Description:

    • Bug Type: Heap-buffer-overflow
    • Summary: A vulnerability was identified in the HDF5 library, where the program attempted to access memory beyond the allocated heap buffer. Specifically, in certain scenarios, the calculations for buffer sizes (overlap_size and new_accum_size) exceeded the allocated buffer size (alloc_size), leading to a heap-buffer-overflow. This occurred due to the lack of bounds checking on these calculated values.
    • Fix Summary: The patch introduces bounds checking to ensure that the calculated buffer sizes do not exceed the allocated size. If an overflow is detected, an error is logged, and the operation is aborted, preventing the overflow from occurring. This fix enhances the security and stability of the HDF5 program by eliminating the potential for memory corruption and undefined behavior caused by out-of-bounds memory access.
  3. Sanitizer Report Summary:
    The sanitizer detected a heap-buffer-overflow when the program attempted to read 361 bytes from an offset -41 into a 520-byte heap buffer. The overflow occurred due to an incorrect calculation and lack of bounds checking in the H5F__accum_free function at /src/H5Faccum.c:885:17. This issue propagated through multiple function calls, ultimately leading to a memory access violation.

  4. Full Sanitizer Report:

    ==15010==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x516000000c57 at pc 0x55f9731d2407 bp 0x7ffd22de46e0 sp 0x7ffd22de3ea0
    READ of size 361 at 0x516000000c57 thread T0
        #0 0x55f9731d2406 in __asan_memmove (/root/out/h5_extended_fuzzer+0x23b406)
        #1 0x55f97416544f in H5F__accum_free /root/src/H5Faccum.c:885:17
        #2 0x55f9736aaa5f in H5MF_xfree /root/src/H5MF.c:1093:13
        #3 0x55f9736c020a in H5MF__aggr_reset /root/src/H5MFaggr.c:725:21
        #4 0x55f9736bfcb2 in H5MF_free_aggrs /root/src/H5MFaggr.c:789:13
        #5 0x55f9736afd56 in H5MF__close_aggrfs /root/src/H5MF.c:1725:9
        #6 0x55f9736ae5b9 in H5MF_close /root/src/H5MF.c:1512:26
        #7 0x55f97347ec54 in H5F__dest /root/src/H5Fint.c:1488:21
        #8 0x55f973483ab3 in H5F_try_close /root/src/H5Fint.c:2680:9
        #9 0x55f9734827d8 in H5F__close /root/src/H5Fint.c:2482:9
        #10 0x55f973ff0dc0 in H5VL__native_file_close /root/src/H5VLnative_file.c:777:13
        #11 0x55f973f9fa69 in H5VL__file_close /root/src/H5VLcallback.c:4326:25
        #12 0x55f973f9f4ca in H5VL_file_close /root/src/H5VLcallback.c:4360:9
        #13 0x55f97348d876 in H5F__close_cb /root/src/H5Fint.c:249:9
        #14 0x55f97369168c in H5I__dec_ref /root/src/H5Iint.c:1076:30
        #15 0x55f973691d10 in H5I__dec_app_ref /root/src/H5Iint.c:1156:22
        #16 0x55f973691b8f in H5I_dec_app_ref /root/src/H5Iint.c:1201:22
        #17 0x55f97344ad85 in H5Fclose /root/src/H5F.c:1040:9
        #18 0x55f973214bd8 in LLVMFuzzerTestOneInput /root/src/h5_extended_fuzzer.c:39:7
        #19 0x55f97311ff04 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) 
        #20 0x55f973109036 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) 
        #21 0x55f97310eaea in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) 
        #22 0x55f9731392a6 in main 
        #23 0x7fec9be9c1c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
        #24 0x7fec9be9c28a in __libc_start_main csu/../csu/libc-start.c:360:3
        #25 0x55f973103c04 in _start (/root/out/h5_extended_fuzzer+0x16cc04)
    
    0x516000000c57 is located 41 bytes before 520-byte region [0x516000000c80,0x516000000e88)
    allocated by thread T0 here:
        #0 0x55f9731d4033 in malloc (/root/out/h5_extended_fuzzer+0x23d033)
        #1 0x55f973561bd9 in H5FL__malloc /root/src/H5FL.c:211:30
        #2 0x55f973562b03 in H5FL_blk_malloc /root/src/H5FL.c:773:48
        #3 0x55f9735647b4 in H5FL_blk_realloc /root/src/H5FL.c:947:21
        #4 0x55f9741626b4 in H5F__accum_write /root/src/H5Faccum.c:700:47
    
  5. Files Modified:

    • src/H5Faccum.c
    --- a/src/H5Faccum.c
    +++ b/src/H5Faccum.c
    @@ -880,6 +880,13 @@
                    H5_CHECKED_ASSIGN(overlap_size, size_t, (addr + size) - accum->loc, haddr_t);
                    new_accum_size = accum->size - overlap_size;
    
    +                /* Ensure overlap_size and new_accum_size are within bounds */
    +                if (overlap_size > accum->alloc_size || new_accum_size > accum->alloc_size) {
    +                    HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "calculated sizes exceed allocated buffer size");
    +                }
    +
                    /* Move the accumulator buffer information to eliminate the freed block */
                    memmove(accum->buf, accum->buf + overlap_size, new_accum_size);
  6. Patch Validation:
    The patch has been validated using the provided PoC. It successfully resolves the heap-buffer-overflow issue identified in the sanitizer report. The program no longer exhibits the memory violation, and no new issues were introduced.

  7. Links:

mattjala
mattjala previously approved these changes Jan 2, 2025
hyoklee
hyoklee previously approved these changes Jan 2, 2025
src/H5Faccum.c Outdated
@@ -881,6 +881,12 @@ H5F__accum_free(H5F_shared_t *f_sh, H5FD_mem_t H5_ATTR_UNUSED type, haddr_t addr
H5_CHECKED_ASSIGN(overlap_size, size_t, (addr + size) - accum->loc, haddr_t);
new_accum_size = accum->size - overlap_size;

/* Ensure overlap_size and new_accum_size are within bounds */
if (overlap_size > accum->alloc_size || new_accum_size > accum->alloc_size) {
Copy link
Collaborator

@jhendersonHDF jhendersonHDF Jan 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes the specific vulnerability, but a more complete fix may be needed here. Consider the case where both overlap_size and new_accum_size end up slightly below accum->alloc_size. It may make more sense to calculate a pointer to the last valid byte in accum->buf and then make use of the H5_IS_BUFFER_OVERFLOW macro from H5private.h.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes the specific vulnerability, but a more complete fix may be needed here. Consider the case where both overlap_size and new_accum_size end up slightly below accum->alloc_size. It may make more sense to calculate a pointer to the last valid byte in accum->buf and then make use of the H5_IS_BUFFER_OVERFLOW macro from H5private.h.

You are right. The current fix does not fully resolve the overflow

@aled-ua aled-ua dismissed stale reviews from hyoklee and mattjala via d0ae121 January 9, 2025 02:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants