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

Compound conversion with user callback segfaults #3840

Closed
mattjala opened this issue Nov 9, 2023 · 1 comment
Closed

Compound conversion with user callback segfaults #3840

mattjala opened this issue Nov 9, 2023 · 1 comment
Assignees
Labels
Component - C Library Core C library issues (usually in the src directory) Priority - 2. Medium ⏹ It would be nice to have this in the next release Type - Bug / Bugfix Please report security issues to [email protected] instead of creating an issue on GitHub

Comments

@mattjala
Copy link
Contributor

mattjala commented Nov 9, 2023

Describe the bug
When the user defines a conversion function between two compound types that doesn't provide a value for cdata->private, the library will segfault while checking if the two compound types are subsets of one another in H5D__typeinfo_init.

Expected behavior
Type conversion and dataset write should complete without errors. cdata->priv should not be used by the library when a user-defined callback function is specified.

Platform (please complete the following information)

  • HDF5 version: Develop (commit hash 5e787741cd)
  • Ubuntu debian 22.04
  • gcc 11.3.0
  • CMake 3.22.1
  • HDF5 built in Release mode

Additional context
Replication program:

#include "hdf5.h"
#include <stdlib.h>

typedef struct src_t {
     uint32_t a;
     float b;
  } src_t;

typedef struct dst_t {
     float b;
  } dst_t;

herr_t convert(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
    size_t nelmts, size_t buf_stride, size_t bkg_stride, void *buf,
    void *bkg, hid_t dxpl)
{
  herr_t retval = EXIT_SUCCESS;
  switch (cdata->command)
  {
  case H5T_CONV_INIT:
    printf("Initializing conversion function...\n");
    break;
  case H5T_CONV_CONV:
    printf("Converting...\n");
    for (size_t i = 0; i < nelmts; ++i)
      ((dst_t*) buf)[i].b = ((src_t*) buf)[i].b;
    break;
  case H5T_CONV_FREE:
    printf("Finalizing conversion function...\n");
    break;
  default:
    break;
  }
  return retval;
}

int main() {
  hid_t src = H5I_INVALID_HID;
  hid_t dst = H5I_INVALID_HID;
  hid_t file_id = H5I_INVALID_HID;
  hid_t space_id = H5I_INVALID_HID;
  hid_t dset_id = H5I_INVALID_HID;
  
  if ((src = H5Tcreate(H5T_COMPOUND, sizeof(struct src_t))) < 0) {
    printf("src dtype creation failed\n");
  }

  if (H5Tinsert(src, "a", HOFFSET(struct src_t, a), H5T_NATIVE_UINT32) < 0) {
    printf("dtype insertion failed\n");
  }

  if (H5Tinsert(src, "b", HOFFSET(struct src_t, b), H5T_NATIVE_FLOAT) < 0) {
    printf("dtype insertion failed\n");
  }

  if ((dst = H5Tcreate(H5T_COMPOUND, sizeof(struct dst_t))) < 0) {
    printf("dst dtype creation failed\n");
  }

  if (H5Tinsert(dst, "b", HOFFSET(struct dst_t, b), H5T_IEEE_F32LE) < 0) {
    printf("dtype insertion failed\n");
  }

  if (H5Tregister(H5T_PERS_SOFT, "src_t->dst_t", src, dst, &convert) < 0) {
    printf("conversion registration failed\n");
  }

  struct src_t buf[] = {{1, 1.0} , {2, 2.0}, {3, 3.0}, {4, 4.0} , {5, 5.0} };  
  
  if ((file_id = H5Fcreate("conversion_test.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
    printf("file creation failed\n");
  }

  if ((space_id = H5Screate_simple(1, (const hsize_t[]) {5}, NULL)) < 0) {
    printf("space creation failed\n");
  }

  if ((dset_id = H5Dcreate(file_id, "dset", dst, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
    printf("dset creation failed\n");
  }

  printf("Beginning dataset write\n");

  if (H5Dwrite(dset_id, src, space_id, H5S_ALL, H5P_DEFAULT, buf) < 0) {
    printf("write failed\n");
  }

  H5Tclose(dst);
  H5Tclose(src);
  H5Fclose(file_id);
  H5Sclose(space_id);
  H5Dclose(dset_id);
  return 0;
}

Output:

Beginning dataset write
Initializing conversion function...
Segmentation fault (core dumped)

Stack trace from valgrind:

==655903== Invalid read of size 4
==655903==    at 0x49472B6: H5D__scatgath_write (in /home/matthewlarson/Downloads/hdf5/install/lib/libhdf5.so.1000.0.0)
==655903==    by 0x492C539: H5D__contig_write (in /home/matthewlarson/Downloads/hdf5/install/lib/libhdf5.so.1000.0.0)
==655903==    by 0x4942CEB: H5D__write (in /home/matthewlarson/Downloads/hdf5/install/lib/libhdf5.so.1000.0.0)
==655903==    by 0x4B90C7A: H5VL__native_dataset_write (in /home/matthewlarson/Downloads/hdf5/install/lib/libhdf5.so.1000.0.0)
==655903==    by 0x4B7B4BD: H5VL_dataset_write_direct (in /home/matthewlarson/Downloads/hdf5/install/lib/libhdf5.so.1000.0.0)
==655903==    by 0x490C67B: H5D__write_api_common.constprop.0 (in /home/matthewlarson/Downloads/hdf5/install/lib/libhdf5.so.1000.0.0)
==655903==    by 0x491052F: H5Dwrite (in /home/matthewlarson/Downloads/hdf5/install/lib/libhdf5.so.1000.0.0)
==655903==    by 0x1096B0: main (h5example.c:82)
==655903==  Address 0x20 is not stack'd, malloc'd or (recently) free'd
@mattjala mattjala added Merge - To 1.14 Priority - 2. Medium ⏹ It would be nice to have this in the next release Component - C Library Core C library issues (usually in the src directory) Type - Bug / Bugfix Please report security issues to [email protected] instead of creating an issue on GitHub labels Nov 9, 2023
@mattjala mattjala self-assigned this Nov 9, 2023
@mattjala
Copy link
Contributor Author

Fixed in #3842

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component - C Library Core C library issues (usually in the src directory) Priority - 2. Medium ⏹ It would be nice to have this in the next release Type - Bug / Bugfix Please report security issues to [email protected] instead of creating an issue on GitHub
Projects
None yet
Development

No branches or pull requests

1 participant