HDFGroup / HDFGroup/hdf5

Allow for compile time disabling of loading plugins

Open
#5,160 0 comments 1 reaction 1 assignee Claimed by @glennsong09 View on GitHub
Component - C Library
Dominant language
C
Stars
988
Forks
355
Avg merge
4d 2h
Merged PRs (30d)
12

Description

**Is your feature request related to a problem? Please describe.**

We use hdf5 in a security restricted sandbox environment where we do not allow plugins.

I have been patching H5PL to disable plugins, but I don't think I'm doing it correctly.

**Describe the solution you'd like**

There is already a `H5PL_NO_PLUGIN`, but that is a runtime thing.

It would be great to have a build time flag (I'm using bazel to build HDF5). Something like defining `H5PL_DISALLOW_PLUGINS` or a false value for a `H5PL_ALLOW_PLUGINS`. So then https://github.com/HDFGroup/hdf5/blob/1706413da7104ffed84038fa0f96134928bf1423/src/H5PLint.c#L135 would be something like:

```c
herr_t
H5PL__init_package(void)
{
herr_t ret_value = SUCCEED;

#ifdef H5PL_DISALLOW_PLUGINS
FUNC_ENTER_PACKAGE

H5PL_plugin_control_mask_g = 0;
H5PL_allow_plugins_g = false;

#else /* Allow plugins*/
char *env_var = NULL;

FUNC_ENTER_PACKAGE

/* Check the environment variable to determine if the user wants
* to ignore plugins. The special symbol H5PL_NO_PLUGIN (defined in
* H5PLpublic.h) means we don't want to load plugins.
*/
if (NULL != (env_var = getenv(HDF5_PLUGIN_PRELOAD)))
if (!strcmp(env_var, H5PL_NO_PLUGIN)) {
H5PL_plugin_control_mask_g = 0;
H5PL_allow_plugins_g = false;
}

/* Create the table of previously-loaded plugins */
if (H5PL__create_plugin_cache() < 0)
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINIT, FAIL, "can't create plugin cache");

/* Create the table of search paths for dynamic libraries */
if (H5PL__create_path_table() < 0)
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINIT, FAIL, "can't create plugin search path table");

#endif /* Allow plugins */

done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5PL__init_package() */
```

I have been using this patch (against 1.12.2) for a while, but it would need modification like above:

```diff
diff --show-c-function -u {a,b}/src/H5PLint.c
--- a/src/H5PLint.c 2024-12-02 05:41:37.445491206 +0000
+++ b/src/H5PLint.c 2024-12-02 05:41:48.465482373 +0000
@@ -247,6 +247,8 @@ H5PL_load(H5PL_type_t type, const H5PL_k
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTLOAD, NULL, "Invalid plugin type specified")
}

+// BEGIN MODIFICATION: Do not search for plugins in search paths.
+#if 0
/* Set up the search parameters */
search_params.type = type;
search_params.key = key;
@@ -259,6 +261,8 @@ H5PL_load(H5PL_type_t type, const H5PL_k
if (!found)
if (H5PL__find_plugin_in_path_table(&search_params, &found, &plugin_info) < 0)
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, NULL, "search in path table failed")
+#endif
+// END MODIFICATION: Do not search for plugins in search paths.

/* Set the return value we found the plugin */
if (found)
@@ -312,6 +316,10 @@ H5PL__open(const char *path, H5PL_type_t
/* Initialize out parameters */
*success = FALSE;
*plugin_info = NULL;
+
+// BEGIN MODIFICATION: Disable opening plugin files.
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "HDF5 Plugin unsupported in this environment.")
+#if 0
if (plugin_type)
*plugin_type = H5PL_TYPE_ERROR;

@@ -405,6 +413,9 @@ H5PL__open(const char *path, H5PL_type_t
if (H5PL__add_plugin(loaded_plugin_type, key, handle))
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINSERT, FAIL, "unable to add new plugin to plugin cache")

+#endif
+// END MODIFICATION: Disable opening plugin files.
+
done:
if (!(*success) && handle)
if (H5PL__close(handle) < 0)
@@ -428,7 +439,10 @@ H5PL__close(H5PL_HANDLE handle)
{
FUNC_ENTER_PACKAGE_NOERR

+
+#if 0 // BEGIN MODIFICATION: Plugin disabled. Avoid dlclose.
H5PL_CLOSE_LIB(handle);
+#endif // END MODIFICATION: Plugin disabled. Avoid dlclose.

FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5PL__close() */
diff --show-c-function -u {a,b}/src/H5PLplugin_cache.c
--- a/src/H5PLplugin_cache.c 2024-12-02 06:01:15.960254441 +0000
+++ b/src/H5PLplugin_cache.c 2024-12-02 06:01:08.884262713 +0000
@@ -261,6 +261,7 @@ H5PL__find_plugin_in_cache(const H5PL_se
*found = FALSE;
*plugin_info = NULL;

+#if 0 // BEGIN MODIFICATION: Plugins disabled. Avoid dlsym.
/* Loop over all the plugins, looking for one that matches */
for (u = 0; u < H5PL_num_plugins_g; u++) {

@@ -291,6 +292,8 @@ H5PL__find_plugin_in_cache(const H5PL_se

} /* end for */

+#endif // END MODIFICATION: Plugins disabled. Avoid dlsym.
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5PL__find_plugin_in_cache() */

```

**Describe alternatives you've considered**

Just going it alone with local only patches. This is what we've been doing for a long time.

**Additional context**

The sandboxes we are currently using are:

https://developers.google.com/code-sandboxing/sandbox2

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.