diff options
author | Jasem Mutlaq <mutlaqja@ikarustech.com> | 2020-01-28 10:46:35 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-28 10:46:35 +0300 |
commit | 049f96cc01061be855da09a89f5b87c906deb25f (patch) | |
tree | f7e1849676c83e61c3ceb25888346c8c27f7c03e | |
parent | 91abbb84263b507ae4e4dc7b46fbe68c8f8c70dd (diff) | |
parent | cd19a02e300b27db24194ccb82b787545260c4b6 (diff) | |
download | libgphoto2-049f96cc01061be855da09a89f5b87c906deb25f.tar.gz |
Merge branch 'master' into master
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | NEWS | 10 | ||||
-rw-r--r-- | SECURITY.md | 68 | ||||
-rw-r--r-- | camlibs/clicksmart310/clicksmart.c | 25 | ||||
-rw-r--r-- | camlibs/clicksmart310/clicksmart.h | 2 | ||||
-rw-r--r-- | camlibs/clicksmart310/library.c | 6 | ||||
-rw-r--r-- | camlibs/kodak/dc240/library.c | 21 | ||||
-rw-r--r-- | camlibs/ptp2/config.c | 3 | ||||
-rw-r--r-- | camlibs/ptp2/music-players.h | 3 | ||||
-rw-r--r-- | camlibs/smal/ultrapocket.c | 2 | ||||
-rw-r--r-- | camlibs/sonix/library.c | 6 | ||||
-rw-r--r-- | camlibs/sonix/sonix.c | 24 | ||||
-rw-r--r-- | examples/sample-afl.c | 8 | ||||
-rw-r--r-- | libgphoto2/ahd_bayer.c | 6 |
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 @@ -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++) { |