The branch, master has been updated
via 388d0297c5540f021d1e9dfa75925e4f8fae03be (commit)
via f3f81007ff33dd6a856ea5f289187f10235635a0 (commit)
via dff4fdb0a64ea5b3cb03d9ff66374cbf05e5e0dc (commit)
from e3d9bcdd6771a2464cd832b96e3da26a3ad804ac (commit)
- Log -----------------------------------------------------------------
commit 388d0297c5540f021d1e9dfa75925e4f8fae03be
Author: Thomas Jarosch <thomas.jarosch@xxxxxxxxxxxxx>
Date: Mon Jul 27 22:31:55 2009 +0200
Updated ChangeLog and AUTHORS
commit f3f81007ff33dd6a856ea5f289187f10235635a0
Author: Thomas Jarosch <thomas.jarosch@xxxxxxxxxxxxx>
Date: Mon Jul 27 22:25:03 2009 +0200
Renamed new usb_close_intl() to ftdi_usb_close_internal(). Made function
static and added doxygen documentation
commit dff4fdb0a64ea5b3cb03d9ff66374cbf05e5e0dc
Author: Nathan Fraser <ndf@xxxxxxxxxxxxxxx>
Date: Mon Jul 27 21:19:11 2009 +1000
Fix for double-free and segfault after close
In some circumstances it is possible to send an invalid usb_dev
pointer through to libusb after some errors or after an explicit
close request. Result will be segfault or subtle corruption.
This patch replaces all calls to usb_close with an internal wrapper
that sets the usb handle to NULL after the usb_close, and refuses
to call close on a NULL handle. Comments and/or discussion very welcome!
-----------------------------------------------------------------------
Summary of changes:
AUTHORS | 2 ++
ChangeLog | 6 ++++++
src/ftdi.c | 58 ++++++++++++++++++++++++++++++++++++++++++----------------
3 files changed, 50 insertions(+), 16 deletions(-)
diff --git a/AUTHORS b/AUTHORS
index f325f05..749b185 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -9,6 +9,7 @@ see Changelog for full details:
Alex Harford <harford@xxxxxxxxx>
Andrew John Rogers <andrew@xxxxxxxxxxxxxxxx>
Arnim Läuger <arnim.laeuger@xxxxxxx>
+ Aurelien Jarno <aurelien@xxxxxxxxxxx>
Daniel Kirkham <d.kirkham@xxxxxxxxxxx>
David Challis <dchallis@xxxxxxxxxxxxx>
Emil <emil@xxxxxxxxxxx>
@@ -26,6 +27,7 @@ see Changelog for full details:
Matthijs ten Berge <m.h.tenberge@xxxxxxxxxxxxxxxxxx>
Max <max@xxxxxxxxxxxx>
Mike Frysinger <vapier.adi@xxxxxxxxx>
+ Nathan Fraser <ndf@xxxxxxxxxxxxxxx>
Peter Holik <peter@xxxxxxxx>
Rogier Wolff <R.E.Wolff@xxxxxxxxxxxxxxxxxxxx>
Steven Turner <steven.turner@xxxxxxxxxxxx>
diff --git a/ChangeLog b/ChangeLog
index 8e28a76..802e53e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+New in 0.17 - 2009-XX-XX
+------------------------
+* Protect against double close of usb device (Nathan Fraser)
+* Fix out-of-tree-build in python wrapper (Aurelien Jarno)
+* Autoconf and doxygen cleanup (Jim Paris)
+
New in 0.16 - 2009-05-08
------------------------
* C++ wrapper: Reopen the device after calling get_strings() in
Context::open() (Marek Vavruša and Intra2net)
diff --git a/src/ftdi.c b/src/ftdi.c
index f89e352..8b589eb 100644
--- a/src/ftdi.c
+++ b/src/ftdi.c
@@ -50,6 +50,27 @@
return code; \
} while(0);
+/**
+ Internal function to close usb device pointer.
+ Sets ftdi->usb_dev to NULL.
+ \internal
+
+ \param ftdi pointer to ftdi_context
+
+ \retval zero if all is fine, otherwise error code from usb_close()
+*/
+static int ftdi_usb_close_internal (struct ftdi_context *ftdi)
+{
+ int ret = 0;
+
+ if (ftdi->usb_dev)
+ {
+ ret = usb_close (ftdi->usb_dev);
+ ftdi->usb_dev = NULL;
+ }
+
+ return ret;
+}
/**
Initializes a ftdi_context.
@@ -176,6 +197,8 @@ int ftdi_set_interface(struct ftdi_context *ftdi, enum
ftdi_interface interface)
*/
void ftdi_deinit(struct ftdi_context *ftdi)
{
+ ftdi_usb_close_internal (ftdi);
+
if (ftdi->async_usb_buffer != NULL)
{
free(ftdi->async_usb_buffer);
@@ -332,7 +355,7 @@ int ftdi_usb_get_strings(struct ftdi_context * ftdi, struct
usb_device * dev,
{
if (usb_get_string_simple(ftdi->usb_dev,
dev->descriptor.iManufacturer, manufacturer, mnf_len) <= 0)
{
- usb_close (ftdi->usb_dev);
+ ftdi_usb_close_internal (ftdi);
ftdi_error_return(-7, usb_strerror());
}
}
@@ -341,7 +364,7 @@ int ftdi_usb_get_strings(struct ftdi_context * ftdi, struct
usb_device * dev,
{
if (usb_get_string_simple(ftdi->usb_dev, dev->descriptor.iProduct,
description, desc_len) <= 0)
{
- usb_close (ftdi->usb_dev);
+ ftdi_usb_close_internal (ftdi);
ftdi_error_return(-8, usb_strerror());
}
}
@@ -350,12 +373,12 @@ int ftdi_usb_get_strings(struct ftdi_context * ftdi,
struct usb_device * dev,
{
if (usb_get_string_simple(ftdi->usb_dev,
dev->descriptor.iSerialNumber, serial, serial_len) <= 0)
{
- usb_close (ftdi->usb_dev);
+ ftdi_usb_close_internal (ftdi);
ftdi_error_return(-9, usb_strerror());
}
}
- if (usb_close (ftdi->usb_dev) != 0)
+ if (ftdi_usb_close_internal (ftdi) != 0)
ftdi_error_return(-10, usb_strerror());
return 0;
@@ -399,7 +422,7 @@ int ftdi_usb_open_dev(struct ftdi_context *ftdi, struct
usb_device *dev)
usb_set_configuration(ftdi->usb_dev,
dev->config[0].bConfigurationValue) &&
errno != EBUSY)
{
- usb_close (ftdi->usb_dev);
+ ftdi_usb_close_internal (ftdi);
if (detach_errno == EPERM)
{
ftdi_error_return(-8, "inappropriate permissions on device!");
@@ -412,7 +435,7 @@ int ftdi_usb_open_dev(struct ftdi_context *ftdi, struct
usb_device *dev)
if (usb_claim_interface(ftdi->usb_dev, ftdi->interface) != 0)
{
- usb_close (ftdi->usb_dev);
+ ftdi_usb_close_internal (ftdi);
if (detach_errno == EPERM)
{
ftdi_error_return(-8, "inappropriate permissions on device!");
@@ -425,13 +448,13 @@ int ftdi_usb_open_dev(struct ftdi_context *ftdi, struct
usb_device *dev)
if (ftdi_usb_reset (ftdi) != 0)
{
- usb_close (ftdi->usb_dev);
+ ftdi_usb_close_internal (ftdi);
ftdi_error_return(-6, "ftdi_usb_reset failed");
}
if (ftdi_set_baudrate (ftdi, 9600) != 0)
{
- usb_close (ftdi->usb_dev);
+ ftdi_usb_close_internal (ftdi);
ftdi_error_return(-7, "set baudrate failed");
}
@@ -531,12 +554,12 @@ int ftdi_usb_open_desc(struct ftdi_context *ftdi, int
vendor, int product,
{
if (usb_get_string_simple(ftdi->usb_dev,
dev->descriptor.iProduct, string, sizeof(string)) <= 0)
{
- usb_close (ftdi->usb_dev);
+ ftdi_usb_close_internal (ftdi);
ftdi_error_return(-8, "unable to fetch product
description");
}
if (strncmp(string, description, sizeof(string)) != 0)
{
- if (usb_close (ftdi->usb_dev) != 0)
+ if (ftdi_usb_close_internal (ftdi) != 0)
ftdi_error_return(-10, "unable to close device");
continue;
}
@@ -545,18 +568,18 @@ int ftdi_usb_open_desc(struct ftdi_context *ftdi, int
vendor, int product,
{
if (usb_get_string_simple(ftdi->usb_dev,
dev->descriptor.iSerialNumber, string, sizeof(string)) <= 0)
{
- usb_close (ftdi->usb_dev);
+ ftdi_usb_close_internal (ftdi);
ftdi_error_return(-9, "unable to fetch serial number");
}
if (strncmp(string, serial, sizeof(string)) != 0)
{
- if (usb_close (ftdi->usb_dev) != 0)
+ if (ftdi_usb_close_internal (ftdi) != 0)
ftdi_error_return(-10, "unable to close device");
continue;
}
}
- if (usb_close (ftdi->usb_dev) != 0)
+ if (ftdi_usb_close_internal (ftdi) != 0)
ftdi_error_return(-10, "unable to close device");
return ftdi_usb_open_dev(ftdi, dev);
@@ -654,6 +677,8 @@ int ftdi_usb_purge_buffers(struct ftdi_context *ftdi)
return 0;
}
+
+
/**
Closes the ftdi device. Call ftdi_deinit() if you're cleaning up.
@@ -672,10 +697,11 @@ int ftdi_usb_close(struct ftdi_context *ftdi)
ftdi_async_complete(ftdi,1);
#endif
- if (usb_release_interface(ftdi->usb_dev, ftdi->interface) != 0)
- rtn = -1;
+ if (ftdi->usb_dev != NULL)
+ if (usb_release_interface(ftdi->usb_dev, ftdi->interface) != 0)
+ rtn = -1;
- if (usb_close (ftdi->usb_dev) != 0)
+ if (ftdi_usb_close_internal (ftdi) != 0)
rtn = -2;
return rtn;
hooks/post-receive
--
A library to talk to FTDI chips
--
libftdi-git - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi-git+unsubscribe@xxxxxxxxxxxxxxxxxxxxxxx
|