summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJasem Mutlaq <mutlaqja@ikarustech.com>2020-01-28 10:46:35 +0300
committerGitHub <noreply@github.com>2020-01-28 10:46:35 +0300
commit049f96cc01061be855da09a89f5b87c906deb25f (patch)
treef7e1849676c83e61c3ceb25888346c8c27f7c03e
parent91abbb84263b507ae4e4dc7b46fbe68c8f8c70dd (diff)
parentcd19a02e300b27db24194ccb82b787545260c4b6 (diff)
downloadlibgphoto2-049f96cc01061be855da09a89f5b87c906deb25f.tar.gz
Merge branch 'master' into master
-rw-r--r--Makefile.am2
-rw-r--r--NEWS10
-rw-r--r--SECURITY.md68
-rw-r--r--camlibs/clicksmart310/clicksmart.c25
-rw-r--r--camlibs/clicksmart310/clicksmart.h2
-rw-r--r--camlibs/clicksmart310/library.c6
-rw-r--r--camlibs/kodak/dc240/library.c21
-rw-r--r--camlibs/ptp2/config.c3
-rw-r--r--camlibs/ptp2/music-players.h3
-rw-r--r--camlibs/smal/ultrapocket.c2
-rw-r--r--camlibs/sonix/library.c6
-rw-r--r--camlibs/sonix/sonix.c24
-rw-r--r--examples/sample-afl.c8
-rw-r--r--libgphoto2/ahd_bayer.c6
14 files changed, 144 insertions, 42 deletions
diff --git a/Makefile.am b/Makefile.am
index 9940e1021..31257ff7a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -6,7 +6,7 @@
bin_SCRIPTS = gphoto2-config
EXTRA_DIST = MAINTAINERS TESTERS installcheck.mk
-EXTRA_DIST += HACKING.md
+EXTRA_DIST += HACKING.md SECURITY.md
# Note: @subdirs@ lists all the directories from AC_CONFIG_SUBDIRS()
SUBDIRS = @subdirs@ libgphoto2 camlibs tests examples po packaging doc gphoto-m4
diff --git a/NEWS b/NEWS
index e1c4da523..39a09f345 100644
--- a/NEWS
+++ b/NEWS
@@ -2,16 +2,18 @@ libgphoto2 2.5.23.1 development
lumix:
-* New WIFI Lumix camera driver, using curl and libxml2.
+* New WIFI Lumix camera driver was added, using curl and libxml2.
- Lots of abilities supported already, just capture is not working :/
- Needs libxml2 and libcurl to be built.
+ Lots of abilities supported already, also capture preview.
+ However capture itself is not yet working :/
+ This driver needs libxml2 and libcurl to be built.
ptp2:
* Canon EOS: lock/unlock ui before more operations
* Canon Powershot SX / EOS M: some setup adjustments to make powershot sx work better
* Nikon Keymission 170: try override opcodes to allow capture
* Nikon DSLR: fixed a regression where 5 seconds was longer image capture shutterspeed
+* Sony: adjusted manualfocusing not to autofocus
* bugfixes
* New ids added:
* Sony Alpha RX100V, A7s, RX0 II,
@@ -23,7 +25,7 @@ ptp2:
all:
-* fixed some fuzzer issues, mostly in "outdated" drivers.
+* fixed some issues found by AFL fuzzing, mostly in "outdated" drivers.
------------------------------------------------------------------------------
libgphoto2 2.5.23 release
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 000000000..66d512feb
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,68 @@
+# Security overview
+
+## General
+
+libgphoto2 is a software library to allow accessing USB devices (cameras,
+media players), allowing file system operations (list, download,
+upload, delete), and control operations (get and set settings, and
+remote control).
+
+It consists of a core library, and drivers for both "port" protocols
+like USB, serial, IP and devices (camera drivers).
+
+libgphoto2 only processes images to provide standard formats. For JPEG
+images the libexif library is used for extraction of EXIF data.
+
+Callers of the library can be assumed trusted, also input coming into
+the library via API calls is considered trusted.
+
+Data coming from port drivers (USB, serial, IP, etc) is considered untrusted.
+
+Historically the primary development goals was "make it work", without
+security in mind.
+
+## Attack Surface
+
+The primary attack scenario is a kiosk style photo access computer, where people
+can plug in USB devices in an unattended fashion.
+
+Attack impacts are achieving control over this computer, or blocking its use.
+
+## Bugs considered security issues
+
+(Mostly for CVE assigments rules.)
+
+In scope of a security attack are the autodetecting protocols support,
+like USB.
+
+Also IP (TCP and UDP) based drivers are considered in scope, with
+malicious target devices or man in the middle attacks.
+
+Current day camera drivers are in scope (e.g. all drivers not marked as "outdated").
+
+Triggering memory corruption is considered in scope.
+Triggering endless loops is considered in scope. (would block kiosk style operation)
+
+## Bugs not considered security issues
+
+Serial cameras are not in scope, as they cannot be autodetected and need
+special configuration which makes other attack vectors likely.
+
+Outdated drivers... We have classified a number of older drivers as
+"outdated", and do not recommend to build them by default anymore.
+
+Denial of service attacks of class "crash" or "resource consumption
+(disk)" are not in scope.
+
+- Frontends should auto-recover (restart) after crashes.
+- Resource consumption in terms of diskspace is not in scope, as the
+ library is meant to download large amounts of data (Gigabytes) in
+ regular operation.
+
+Information disclosure is not a relevant attack scenario.
+
+## Bugreports
+
+Bugreports can be filed as github issues.
+
+If you want to report an embargoed security bug report, reach out to marcus@jet.franken.de
diff --git a/camlibs/clicksmart310/clicksmart.c b/camlibs/clicksmart310/clicksmart.c
index 9184c6cb4..a867284c8 100644
--- a/camlibs/clicksmart310/clicksmart.c
+++ b/camlibs/clicksmart310/clicksmart.c
@@ -53,8 +53,7 @@ CLICKSMART_READ (GPPort *port, int index, char *data)
static int
CLICKSMART_READ_STATUS (GPPort *port, char *data)
{
- gp_port_usb_msg_interface_read(port, 0, 0, CS_CH_READY, data, 1);
- return GP_OK;
+ return gp_port_usb_msg_interface_read(port, 0, 0, CS_CH_READY, data, 1);
}
int clicksmart_init (GPPort *port, CameraPrivateLibrary *priv)
@@ -86,8 +85,11 @@ int clicksmart_init (GPPort *port, CameraPrivateLibrary *priv)
CLICKSMART_READ_STATUS (port, &c);
gp_port_usb_msg_interface_write(port, 6, 0, 9, NULL, 0);
- while (c != 1)
- CLICKSMART_READ_STATUS (port, &c);
+ while (c != 1) {
+ int r;
+ if ((r = CLICKSMART_READ_STATUS (port, &c)) < GP_OK)
+ return r;
+ }
buffer = malloc(0x200);
if (!buffer) {
free (temp_catalog);
@@ -131,7 +133,7 @@ int clicksmart_get_res_setting (CameraPrivateLibrary *priv, int n)
int
clicksmart_read_pic_data (CameraPrivateLibrary *priv, GPPort *port,
- unsigned char *data, int n)
+ unsigned char **data, int n)
{
int offset=0;
char c;
@@ -147,7 +149,9 @@ clicksmart_read_pic_data (CameraPrivateLibrary *priv, GPPort *port,
gp_port_usb_msg_interface_write(port, 6, 0x1fff - n, 1, NULL, 0);
c = 0;
while (c != 1){
- CLICKSMART_READ_STATUS (port, &c);
+ int r;
+ if ((r = CLICKSMART_READ_STATUS (port, &c)) < GP_OK)
+ return r;
}
/* Get the size of the data and calculate the size to download, which
* is the next multiple of 0x100. Only for the hi-res photos is the
@@ -161,17 +165,20 @@ clicksmart_read_pic_data (CameraPrivateLibrary *priv, GPPort *port,
remainder = size%0x200;
GP_DEBUG("size: %x, remainder: %x\n", size, remainder);
+ *data = calloc(size + 0x100,1);
+ if (!*data) return GP_ERROR;
/* Download the data */
while (offset < size-remainder) {
GP_DEBUG("offset: %x\n", offset);
- gp_port_read(port, (char *)data + offset, 0x200);
+ if (gp_port_read(port, (char *)*data + offset, 0x200) < GP_OK)
+ break;
offset = offset + 0x200;
}
remainder=((remainder+0xff)/0x100)*0x100;
GP_DEBUG("Second remainder: %x\n", remainder);
if (remainder)
- gp_port_read(port, (char *)data + offset, remainder);
+ gp_port_read(port, (char *)*data + offset, remainder);
gp_port_usb_msg_interface_read(port, 0, 0, CS_READCLOSE, &c, 1);
gp_port_usb_msg_interface_write(port, 0, 2, CS_CH_READY, NULL, 0);
@@ -183,7 +190,7 @@ clicksmart_read_pic_data (CameraPrivateLibrary *priv, GPPort *port,
*/
if (priv->catalog[16*n]) {
- while ( data[size-1] == 0)
+ while ( (*data)[size-1] == 0)
size--;
}
return size;
diff --git a/camlibs/clicksmart310/clicksmart.h b/camlibs/clicksmart310/clicksmart.h
index 35435d1cb..5982ef99c 100644
--- a/camlibs/clicksmart310/clicksmart.h
+++ b/camlibs/clicksmart310/clicksmart.h
@@ -35,7 +35,7 @@ struct _CameraPrivateLibrary {
int clicksmart_init (GPPort *port, CameraPrivateLibrary *priv);
int clicksmart_get_res_setting (CameraPrivateLibrary *priv, int n);
int clicksmart_read_pic_data (CameraPrivateLibrary *priv,
- GPPort *port, unsigned char *data,
+ GPPort *port, unsigned char **data,
int n);
int clicksmart_delete_all_pics (GPPort *port);
diff --git a/camlibs/clicksmart310/library.c b/camlibs/clicksmart310/library.c
index 53853cc58..674c9ec25 100644
--- a/camlibs/clicksmart310/library.c
+++ b/camlibs/clicksmart310/library.c
@@ -195,12 +195,10 @@ get_file_func (CameraFilesystem *fs, const char *folder, const char *filename,
return GP_ERROR;
}
- data = malloc (w*h);
- if(!data)
- return GP_ERROR_NO_MEMORY;
+ data = NULL;
GP_DEBUG("Fetch entry %i\n", k);
- b = clicksmart_read_pic_data (camera->pl, camera->port, data, k);
+ b = clicksmart_read_pic_data (camera->pl, camera->port, &data, k);
if (GP_FILE_TYPE_RAW == type) { /* type is GP_FILE_TYPE_RAW */
gp_file_set_mime_type (file, GP_MIME_RAW);
diff --git a/camlibs/kodak/dc240/library.c b/camlibs/kodak/dc240/library.c
index 5352e9db2..a77d0999c 100644
--- a/camlibs/kodak/dc240/library.c
+++ b/camlibs/kodak/dc240/library.c
@@ -60,6 +60,10 @@
#define GP_MODULE "dc240"
+/* do not sleep during fuzzing */
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+# define usleep(x)
+#endif
/* legacy from dc240.h */
/*
@@ -165,10 +169,13 @@ write_again:
/* Read in the response from the camera if requested */
while (read_response) {
- if (gp_port_read(camera->port, in, 1) >= GP_OK) {
+ int ret;
+ if ((ret=gp_port_read(camera->port, in, 1)) >= GP_OK) {
/* On error, read again */
read_response = 0;
+ break;
}
+ if (ret == GP_ERROR_IO_READ) return ret; /* e.g. device detached? */
}
return GP_OK;
@@ -458,7 +465,10 @@ static int dc240_get_file_size (Camera *camera, const char *folder, const char *
if (dc240_packet_exchange(camera, f, p1, p2, &size, 256, context) < 0)
size = 0;
else {
- gp_file_get_data_and_size (f, (const char**)&fdata, &fsize);
+ int ret;
+ ret = gp_file_get_data_and_size (f, (const char**)&fdata, &fsize);
+ if (ret < GP_OK) return ret;
+ if (!fdata || (fsize < 4)) return GP_ERROR;
size = (fdata[offset] << 24) |
(fdata[offset+1] << 16) |
(fdata[offset+2] << 8 ) |
@@ -753,6 +763,11 @@ int dc240_get_directory_list (Camera *camera, CameraList *list, const char *fold
num_of_entries = be16atoh(&fdata [0]) + 1;
total_size = 2 + (num_of_entries * 20);
GP_DEBUG ("number of file entries : %d, size = %ld", num_of_entries, fsize);
+ if (total_size > fsize) {
+ GP_DEBUG ("total_size %d > fsize %ld", total_size, fsize);
+ gp_file_free (file);
+ return GP_ERROR;
+ }
for (x = 2; x < total_size; x += 20) {
if ((fdata[x] != '.') && (attrib == (unsigned char)fdata[x+11])) {
/* Files have attrib 0x00, Folders have attrib 0x10 */
@@ -793,7 +808,7 @@ int dc240_file_action (Camera *camera, int action, CameraFile *file,
thumb = 1;
/* no break on purpose */
case DC240_ACTION_IMAGE:
- if ((size = dc240_get_file_size(camera, folder, filename, thumb, context)) < 0) {
+ if ((size = dc240_get_file_size(camera, folder, filename, thumb, context)) < GP_OK) {
retval = GP_ERROR;
break;
}
diff --git a/camlibs/ptp2/config.c b/camlibs/ptp2/config.c
index 0cc3f8051..45f56432f 100644
--- a/camlibs/ptp2/config.c
+++ b/camlibs/ptp2/config.c
@@ -5279,7 +5279,6 @@ static struct deviceproptableu8 compressionsetting[] = {
{ N_("NEF+Basic"), 0x05, PTP_VENDOR_NIKON },
{ N_("NEF+Normal"), 0x06, PTP_VENDOR_NIKON },
{ N_("NEF+Fine"), 0x07, PTP_VENDOR_NIKON },
-
{ N_("Standard"), 0x02, PTP_VENDOR_SONY },
{ N_("Fine"), 0x03, PTP_VENDOR_SONY },
{ N_("Extra Fine"), 0x04, PTP_VENDOR_SONY },
@@ -8513,7 +8512,7 @@ static struct submenu nikon_d850_capture_settings[] = {
};
static struct submenu nikon_d7500_capture_settings[] = {
- { N_("Image Quality"), "imagequality", PTP_DPC_CompressionSetting, PTP_VENDOR_NIKON, PTP_DTC_UINT8, _get_Nikon_D7500_Compression, _put_Nikon_7500_Compression },
+ { N_("Image Quality"), "imagequality", PTP_DPC_CompressionSetting, PTP_VENDOR_NIKON, PTP_DTC_UINT8, _get_Nikon_D7500_Compression, _put_Nikon_D7500_Compression },
{ 0,0,0,0,0,0,0 },
};
diff --git a/camlibs/ptp2/music-players.h b/camlibs/ptp2/music-players.h
index a29db1c52..6953318a8 100644
--- a/camlibs/ptp2/music-players.h
+++ b/camlibs/ptp2/music-players.h
@@ -1268,6 +1268,8 @@
{ "Nokia", 0x2e04, "6", 0xc025, DEVICE_FLAGS_ANDROID_BUGS },
/* https://sourceforge.net/p/libmtp/bugs/1783/ */
{ "Nokia", 0x2e04, "6.1", 0xc026, DEVICE_FLAGS_ANDROID_BUGS },
+ /* ndim from gphoto */
+ { "Nokia", 0x2e04, "6.2", 0xc02a, DEVICE_FLAGS_ANDROID_BUGS },
/*
* Qualcomm
@@ -3742,6 +3744,7 @@
{ "Garmin", 0x091e, "Venu", 0x4c9a, DEVICE_FLAGS_ANDROID_BUGS },
/* https://sourceforge.net/p/libmtp/bugs/1852/ */
{ "Garmin", 0x091e, "Fenix 6", 0x4cda, DEVICE_FLAGS_ANDROID_BUGS },
+ { "Garmin", 0x091e, "Fenix 6 Sapphire", 0x4cdb, DEVICE_FLAGS_ANDROID_BUGS },
/*
* Wacom
diff --git a/camlibs/smal/ultrapocket.c b/camlibs/smal/ultrapocket.c
index 3854f07c3..9212dae92 100644
--- a/camlibs/smal/ultrapocket.c
+++ b/camlibs/smal/ultrapocket.c
@@ -169,7 +169,7 @@ getpicture_logitech_pd(Camera *camera, GPContext *context, unsigned char **rd, c
unsigned char *rawdata;
int ptc,pc,id;
- memcpy(command+3, filename, 11); /* the id of the image to transfer */
+ strncpy(command+3, filename, 11); /* the id of the image to transfer */
CHECK_RESULT(ultrapocket_command(port, 1, command, 0x10));
diff --git a/camlibs/sonix/library.c b/camlibs/sonix/library.c
index 2d7546cd2..444eb6a0a 100644
--- a/camlibs/sonix/library.c
+++ b/camlibs/sonix/library.c
@@ -114,6 +114,7 @@ camera_summary (Camera *camera, CameraText *summary, GPContext *context)
ret = sonix_init(camera->port, camera->pl);
if ( ret != GP_OK) {
free(camera->pl);
+ camera->pl = NULL;
return ret;
}
if (!camera->pl->num_pics)
@@ -168,6 +169,7 @@ file_list_func (CameraFilesystem *fs, const char *folder, CameraList *list,
ret = sonix_init(camera->port, camera->pl);
if ( ret != GP_OK) {
free(camera->pl);
+ camera->pl = NULL;
return ret;
}
if(!camera->pl->num_pics) {
@@ -211,6 +213,7 @@ get_file_func (CameraFilesystem *fs, const char *folder, const char *filename,
ret = sonix_init(camera->port, camera->pl);
if ( ret != GP_OK) {
free(camera->pl);
+ camera->pl = NULL;
return ret;
}
if(!camera->pl->num_pics) {
@@ -463,6 +466,7 @@ delete_all_func (CameraFilesystem *fs, const char *folder, void *data,
ret = sonix_init(camera->port, camera->pl);
if ( ret != GP_OK) {
free(camera->pl);
+ camera->pl = NULL;
return ret;
}
sonix_delete_all_pics (camera->port);
@@ -480,6 +484,7 @@ delete_file_func (CameraFilesystem *fs, const char *folder,
ret = sonix_init(camera->port, camera->pl);
if ( ret != GP_OK) {
free(camera->pl);
+ camera->pl = NULL;
return ret;
}
if (camera->pl->fwversion[1] == 0x0a)
@@ -505,6 +510,7 @@ camera_capture (Camera *camera, CameraCaptureType type, CameraFilePath *path,
ret = sonix_init(camera->port, camera->pl);
if ( ret != GP_OK) {
free(camera->pl);
+ camera->pl = NULL;
return ret;
}
if (!(camera->pl->can_do_capture)) {
diff --git a/camlibs/sonix/sonix.c b/camlibs/sonix/sonix.c
index e0164761d..22b2d73f5 100644
--- a/camlibs/sonix/sonix.c
+++ b/camlibs/sonix/sonix.c
@@ -44,24 +44,21 @@
static int
SONIX_READ (GPPort *port, char *data)
{
- gp_port_usb_msg_interface_read(port, 0, 1, 0, data, 1);
- return GP_OK;
+ return gp_port_usb_msg_interface_read(port, 0, 1, 0, data, 1);
}
/* This reads a 4-byte response to a command */
static int
SONIX_READ4 (GPPort *port, char *data)
{
- gp_port_usb_msg_interface_read(port, 0, 4, 0, data, 4);
- return GP_OK;
+ return gp_port_usb_msg_interface_read(port, 0, 4, 0, data, 4);
}
/* A command to the camera is a 6-byte string, and this sends it. */
static int
SONIX_COMMAND (GPPort *port, char *command)
{
- gp_port_usb_msg_interface_write(port, 8, 2, 0, command ,6);
- return GP_OK;
+ return gp_port_usb_msg_interface_write(port, 8, 2, 0, command ,6);
}
@@ -88,7 +85,8 @@ int sonix_init (GPPort *port, CameraPrivateLibrary *priv)
i = 0;
while ((unsigned)status > 0) {
- SONIX_READ(port, &status);
+ if (SONIX_READ(port, &status) < GP_OK)
+ break;
i++;
if (i==1000) break;
}
@@ -97,8 +95,10 @@ int sonix_init (GPPort *port, CameraPrivateLibrary *priv)
SONIX_COMMAND ( port, c);
- while (status !=2)
- SONIX_READ(port, &status);
+ while (status !=2) {
+ if (SONIX_READ(port, &status) < GP_OK)
+ break;
+ }
/* FIXME(Marcus): was indented at above level, unclear if it is needed this way ... */
SONIX_READ(port, &status);
@@ -117,7 +117,8 @@ int sonix_init (GPPort *port, CameraPrivateLibrary *priv)
while (!reading[1]&&!reading[2]&&!reading[3]) {
c[0]=0x16;
- SONIX_COMMAND ( port, c );
+ if (SONIX_COMMAND ( port, c ) < GP_OK)
+ break;
/*
* For the Vivicam 3350b this always gives
* 96 0a 76 07. This is apparently the firmware version.
@@ -129,7 +130,8 @@ int sonix_init (GPPort *port, CameraPrivateLibrary *priv)
* Spy Camera 70137 it is 96 01 31 09. Since the cameras
* have different abilities, we ought to distinguish.
*/
- SONIX_READ4 (port, (char *)reading);
+ if (SONIX_READ4 (port, (char *)reading) < GP_OK)
+ break;
}
GP_DEBUG("%02x %02x %02x %02x\n", reading[0], reading[1],
reading[2], reading[3]);
diff --git a/examples/sample-afl.c b/examples/sample-afl.c
index c01414bbc..d3520c5f2 100644
--- a/examples/sample-afl.c
+++ b/examples/sample-afl.c
@@ -95,7 +95,7 @@ recursive_directory(Camera *camera, const char *folder, GPContext *context, int
printf ("Could not get file.\n");
return ret;
}
- gp_file_free (file);
+ gp_file_unref (file);
/* get preview */
gp_file_new (&file);
ret = gp_camera_file_get (camera, folder, newfile, GP_FILE_TYPE_PREVIEW, file, context);
@@ -104,7 +104,7 @@ recursive_directory(Camera *camera, const char *folder, GPContext *context, int
printf ("Could not get file preview.\n");
return ret;
}
- gp_file_free (file);
+ gp_file_unref (file);
/* get exif */
gp_file_new (&file);
ret = gp_camera_file_get (camera, folder, newfile, GP_FILE_TYPE_EXIF, file, context);
@@ -113,7 +113,7 @@ recursive_directory(Camera *camera, const char *folder, GPContext *context, int
printf ("Could not get file preview.\n");
return ret;
}
- gp_file_free (file);
+ gp_file_unref (file);
/* Trigger the ptp things */
gp_file_new (&file);
ret = gp_camera_file_get (camera, folder, newfile, GP_FILE_TYPE_METADATA, file, context);
@@ -122,7 +122,7 @@ recursive_directory(Camera *camera, const char *folder, GPContext *context, int
printf ("Could not get file metadata.\n");
return ret;
}
- gp_file_free (file);
+ gp_file_unref (file);
if (foundfile) *foundfile = 1;
gp_list_free (list);
return GP_OK;
diff --git a/libgphoto2/ahd_bayer.c b/libgphoto2/ahd_bayer.c
index efedfd5ff..5254d28dc 100644
--- a/libgphoto2/ahd_bayer.c
+++ b/libgphoto2/ahd_bayer.c
@@ -581,8 +581,10 @@ int gp_ahd_interpolate (unsigned char *image, int w, int h, BayerTile tile)
for (i=-1; i < 2;i++) {
for (k=0; k < 3;k++) {
j=i+x+w*k;
- homo_ch[x]+=homo_h[j];
- homo_cv[x]+=homo_v[j];
+ if ((j >= 0) && ( j < w*3)) {
+ homo_ch[x]+=homo_h[j];
+ homo_cv[x]+=homo_v[j];
+ }
}
}
for (color=0; color < 3; color++) {