summaryrefslogtreecommitdiff
path: root/libgphoto2
diff options
context:
space:
mode:
authorMarcus Meissner <marcus@jet.franken.de>2022-11-05 09:43:06 +0100
committerGitHub <noreply@github.com>2022-11-05 09:43:06 +0100
commit3067c978af62f34cce4b366f4723c137227b9059 (patch)
tree3a34666844a216cb029dcb0d661e52aa8949d2fb /libgphoto2
parent48136a68094301fe465684abc00dc2bdffa94b4a (diff)
downloadlibgphoto2-3067c978af62f34cce4b366f4723c137227b9059.tar.gz
Wrap unsafe libltdl calls with locking (#848)
* Wrap unsafe libltdl calls with locking https://github.com/gphoto/libgphoto2/issues/166 * 848: do not install internal header gphoto2-port-mutex.h * 848: wrap symbol declarations in #ifdef _GPHOTO2_INTERNAL_CODE * 848: Use proper include guard macro * 848: Encapsulate the lock/unlock code inside functions This hides the pthread usage as an implementation detail inside the gpi_libltdl_lock() and gpi_libltdl_unlock() functions. * 848: Rename from *-mutex.[ch] to *-locking.[ch] The *-lock.[ch] name is implementation neutral. * 848: update libgphoto2_port version number * 848: internal headers do not require __cplusplus checks * 848: add copyright comment at the beginning of *.[ch] * 848: add an unlocked variant of gp_abilities_list_load_dir to avoid lots of unlock/lock codes * 848: remove unnecessary whitespace addition Co-authored-by: kadler15 <spurfan15@gmail.com> Co-authored-by: Hans Ulrich Niedermann <hun@n-dimensional.de>
Diffstat (limited to 'libgphoto2')
-rw-r--r--libgphoto2/gphoto2-abilities-list.c24
-rw-r--r--libgphoto2/gphoto2-camera.c15
2 files changed, 33 insertions, 6 deletions
diff --git a/libgphoto2/gphoto2-abilities-list.c b/libgphoto2/gphoto2-abilities-list.c
index b4a9725d1..7db617aed 100644
--- a/libgphoto2/gphoto2-abilities-list.c
+++ b/libgphoto2/gphoto2-abilities-list.c
@@ -36,6 +36,7 @@
#include <gphoto2/gphoto2-result.h>
#include <gphoto2/gphoto2-port-log.h>
#include <gphoto2/gphoto2-library.h>
+#include <gphoto2/gphoto2-port-locking.h>
#include "libgphoto2/i18n.h"
@@ -185,9 +186,8 @@ foreach_func (const char *filename, lt_ptr data)
return ((fd->result == GP_OK)?0:1);
}
-
-int
-gp_abilities_list_load_dir (CameraAbilitiesList *list, const char *dir,
+static int
+unlocked_gp_abilities_list_load_dir (CameraAbilitiesList *list, const char *dir,
GPContext *context)
{
CameraLibraryIdFunc id;
@@ -295,7 +295,6 @@ gp_abilities_list_load_dir (CameraAbilitiesList *list, const char *dir,
#if !defined(VALGRIND)
lt_dlclose (lh);
#endif
-
new_count = gp_abilities_list_count (list);
if (new_count < 0)
continue;
@@ -310,16 +309,29 @@ gp_abilities_list_load_dir (CameraAbilitiesList *list, const char *dir,
if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL) {
lt_dlexit ();
gp_list_free (flist);
- return (GP_ERROR_CANCEL);
+ return GP_ERROR_CANCEL;
}
}
gp_context_progress_stop (context, p);
lt_dlexit ();
gp_list_free (flist);
- return (GP_OK);
+ return GP_OK;
}
+int
+gp_abilities_list_load_dir (CameraAbilitiesList *list, const char *dir,
+ GPContext *context)
+{
+ int ret;
+
+ gpi_libltdl_lock();
+ ret = unlocked_gp_abilities_list_load_dir (list, dir, context);
+ gpi_libltdl_unlock();
+ return ret;
+}
+
+
/**
* \brief Scans the system for camera drivers.
diff --git a/libgphoto2/gphoto2-camera.c b/libgphoto2/gphoto2-camera.c
index 91828df46..745d7f988 100644
--- a/libgphoto2/gphoto2-camera.c
+++ b/libgphoto2/gphoto2-camera.c
@@ -37,6 +37,7 @@
#include <gphoto2/gphoto2-result.h>
#include <gphoto2/gphoto2-library.h>
#include <gphoto2/gphoto2-port-log.h>
+#include <gphoto2/gphoto2-port-locking.h>
#include "libgphoto2/i18n.h"
@@ -279,8 +280,10 @@ gp_camera_exit (Camera *camera, GPContext *context)
if (camera->pc->lh) {
#if !defined(VALGRIND)
+ gpi_libltdl_lock();
lt_dlclose (camera->pc->lh);
lt_dlexit ();
+ gpi_libltdl_unlock();
#endif
camera->pc->lh = NULL;
}
@@ -777,21 +780,29 @@ gp_camera_init (Camera *camera, GPContext *context)
/* Load the library. */
GP_LOG_D ("Loading '%s'...", camera->pc->a.library);
+ gpi_libltdl_lock();
lt_dlinit ();
camera->pc->lh = lt_dlopenext (camera->pc->a.library);
+ gpi_libltdl_unlock();
if (!camera->pc->lh) {
+ gpi_libltdl_lock();
gp_context_error (context, _("Could not load required "
"camera driver '%s' (%s)."), camera->pc->a.library,
lt_dlerror ());
lt_dlexit ();
+ gpi_libltdl_unlock();
return (GP_ERROR_LIBRARY);
}
/* Initialize the camera */
+ gpi_libltdl_lock();
init_func = lt_dlsym (camera->pc->lh, "camera_init");
+ gpi_libltdl_unlock();
if (!init_func) {
+ gpi_libltdl_lock();
lt_dlclose (camera->pc->lh);
lt_dlexit ();
+ gpi_libltdl_unlock();
camera->pc->lh = NULL;
gp_context_error (context, _("Camera driver '%s' is "
"missing the 'camera_init' function."),
@@ -802,8 +813,10 @@ gp_camera_init (Camera *camera, GPContext *context)
if (strcasecmp (camera->pc->a.model, "Directory Browse")) {
result = gp_port_open (camera->port);
if (result < 0) {
+ gpi_libltdl_lock();
lt_dlclose (camera->pc->lh);
lt_dlexit ();
+ gpi_libltdl_unlock();
camera->pc->lh = NULL;
return (result);
}
@@ -812,8 +825,10 @@ gp_camera_init (Camera *camera, GPContext *context)
result = init_func (camera, context);
if (result < 0) {
gp_port_close (camera->port);
+ gpi_libltdl_lock();
lt_dlclose (camera->pc->lh);
lt_dlexit ();
+ gpi_libltdl_unlock();
camera->pc->lh = NULL;
memset (camera->functions, 0, sizeof (CameraFunctions));
return (result);