- 
          
- 
                Notifications
    You must be signed in to change notification settings 
- Fork 311
Fix several issues uncovered by CVE-2025-7067 #5938
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
base: develop
Are you sure you want to change the base?
Conversation
| herr_t | ||
| H5FS_sect_add(H5F_t *f, H5FS_t *fspace, H5FS_section_info_t *sect, unsigned flags, void *op_data) | ||
| H5FS_sect_add(H5F_t *f, H5FS_t *fspace, H5FS_section_info_t *sect, unsigned flags, void *op_data, | ||
| bool *merged_or_shrunk) | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Callers of this function need to know whether the free space section passed in was merged or shrunk away, even on failure. Otherwise, calling code can incorrectly assume that it needs to free the passed in section if it was allocated by the calling code and H5FS_sect_add() failed. In some cases, the passed in section will have already been freed, eventually resulting in a double free situation when the calling code frees the section.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An alternative approach would be to pass in a H5FS_section_info_t **, but that seemed uglier and prone to the caller accidentally losing a pointer.
| } /* end if */ | ||
|  | ||
| done: | ||
| if (ret_value < 0) { | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When this function fails, remove everything that was previously inserted into the metadata cache. Otherwise, crashes or assertion failures can occur later on when trying to flush out half-initialized entries that were inserted.
| if (H5MF__add_sect(f, alloc_type, f->shared->fs_man[fs_type], node) < 0) | ||
| if (H5MF__add_sect(f, alloc_type, f->shared->fs_man[fs_type], node, §ion_merged_or_shunk) < 0) { | ||
| if (section_merged_or_shunk) | ||
| node = NULL; | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid double-freeing this section that was allocated above in case H5MF__add_sect() already freed it.
| if (H5MF__add_sect(f, alloc_type, fspace, node) < 0) | ||
| if (H5MF__add_sect(f, alloc_type, fspace, node, NULL) < 0) { | ||
| node->sect_info.addr -= size; | ||
| node->sect_info.size += size; | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reverse the modifications made above on failure.
13e10f6    to
    c67c523      
    Compare
  
    |  | ||
| assert(!H5_addr_defined(f->shared->fs_addr[sm_fshdr_fs_type])); | ||
| assert(!H5_addr_defined(f->shared->fs_addr[sm_fssinfo_fs_type])); | ||
| if (H5_addr_defined(f->shared->fs_addr[sm_fshdr_fs_type])) | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These assertions can be triggered by a file space info message in the file's superblock extension that was specifically crafted. Throwing an error here causes the library to fail to be able to settle the MDFSM, which eventually leads to issues closing the library and leaked memory due to the metadata cache not being able to be flushed and destroyed. In Debug builds this still results in an assertion failure when specifically-crafted files are opened, but addressing that will require significant changes to the metadata cache shutdown process.
An alternative is to simply wipe out these addresses to HADDR_UNDEF and let the following logic take over, but this could end up dropping free space on the floor and also causes far more problems when given a specifically crafted file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this be detected when the file space info message is decoded?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In theory yes, however there was no obvious documentation or information I could find on which of the free space managers are and aren't allowed to have a defined address right after decoding and after asking around the opinion seemed to be that any of the managers could be defined. In this specific case however it seems the assumption is that these particular ones won't have a defined address.
107376c    to
    ef61da4      
    Compare
  
    | assert(sect1); | ||
| assert(sect2); | ||
| assert(sect1->sect_info.type == sect2->sect_info.type); /* Checks "MERGE_SYM" flag */ | ||
| assert(H5_addr_lt(sect1->sect_info.addr, sect2->sect_info.addr)); | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the file given in #5577, an attempt is made to place an overlapping section of file free space into the free space manager. That eventually causes this assertion to trigger. While a true fix would likely involve detecting this situation earlier on, this is probably a non-trivial effort. Since these functions are only checking whether two free space sections can be merged and not actually doing the merging, removing these assertions and just letting them return false seemed appropriate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should leave open an issue to add the correct fix, and note that these assertions should be re enabled at that point
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do. Should I instead comment these out for now then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds good
| * Avoid expunging the entry, as the information needs to be kept around | ||
| * until we finish trying to settle the metadata free space manager(s). | ||
| */ | ||
| if (inserted_section || allocated_section) { | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need this line?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe these checks are actually redundant and can be removed at this point. Previously I was removing the cache entries with expunge_entry and the "free file space" flag, in which case I had two branches with different logic where I didn't want to double free the file space with the call to H5MF_xfree followed by expunge_entry. That caused some problems and needed a switch to remove_entry instead, so I think this line and the other line are no longer relevant.
| * Avoid expunging the entry, as the information needs to be kept around | ||
| * until we finish trying to settle the metadata free space manager(s). | ||
| */ | ||
| if (inserted_header || allocated_header) { | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, is this one just for the assertion?
| Finished reviewing, 2 questions as comments, 2 as replies | 
Fixes several crashes/assertion failures related to CVE-2025-7067
Important
Fixes CVE-2025-7067 issues by updating
H5FS_sect_addto handle section merging/shrinking and improving error handling.H5FS_sect_addinH5FSsection.cnow accepts an additionalbool *merged_or_shrunkparameter to track if sections are merged or shrunk.H5MF__add_sectinH5MF.cto handlemerged_or_shrunkparameter.H5FS_vfd_alloc_hdr_and_section_info_if_neededinH5MF.cto manage allocation failures.freespace.candmf.cto include the new parameter inH5FS_sect_addcalls.This description was created by for ef61da4. You can customize this summary. It will automatically update as commits are pushed.
 for ef61da4. You can customize this summary. It will automatically update as commits are pushed.