Dear Ludovic

On Mon, Feb 20, 2012 at 11:21 PM, Godfrey Chung
<[email protected]> wrote:
> Compared with acsccid-1.0.3 with ccid-1.4.5, I found that I didn't
> merge your changes for the ControlUSB function. Your function checked
> the return value from libusb_control_transfer(). The returned value
> may be very large and cause DEBUG_XXD to fail. I will do more tests
> tomorrow.

I used APG8201 for testing and reviewed the code from acsccid-1.0.3,
ccid-1.4.5 and pcsc-lite-1.8.2. The problem is not related to libusb
or kernel.

I found that the real problem is in DEBUG_XXD macro which calls
log_xxd from pcsc-lite. From my testing, I got error code "-84" from
usb_control_msg. Because acsccid is missing a check of error code in
ControlUSB, it passed the error code directly to DEBUG_XXD. Then,
pcscd is suddenly terminated with segmentation fault.

In pcsc-lite, log_xxd calls log_xxd_always. log_xxd_always accepts
negative number in len parameter and use the value for the array size
of DebugBuffer.

Suggested code change for acsccid-1.0.3 (src/ccid_usb.c):

Add a error code check after usb_control_msg.

int ControlUSB(int reader_index, int requesttype, int request, int value,
        unsigned char *bytes, unsigned int size)
{
        int ret;

        DEBUG_COMM2("request: 0x%02X", request);

        if (0 == (requesttype & 0x80))
                DEBUG_XXD("send: ", bytes, size);

        ret = usb_control_msg(usbDevice[reader_index].handle, requesttype,
                request, value, usbDevice[reader_index].interface, (char 
*)bytes, size,
                usbDevice[reader_index].ccid.readTimeout * 1000);

        if (ret < 0)
        {
                DEBUG_CRITICAL4("control failed (%s/%s): %s",
                        usbDevice[reader_index].dirname, 
usbDevice[reader_index].filename,
                        strerror(errno));

                return ret;
        }

        if (requesttype & 0x80)
                DEBUG_XXD("receive: ", bytes, ret);

        return ret;
} /* ControlUSB */

Suggested code change for ccid-1.4.5 (src/ccid_usb.c):

Use of STATUS_UNSUCCESSFUL as return code is not appropriate.
STATUS_UNSUCCESSFUL is a positive number.

int ControlUSB(int reader_index, int requesttype, int request, int value,
        unsigned char *bytes, unsigned int size)
{
        int ret;

        DEBUG_COMM2("request: 0x%02X", request);

        if (0 == (requesttype & 0x80))
                DEBUG_XXD("send: ", bytes, size);

        ret = libusb_control_transfer(usbDevice[reader_index].dev_handle,
                requesttype, request, value, usbDevice[reader_index].interface,
                bytes, size, usbDevice[reader_index].ccid.readTimeout);

        if (ret < 0)
        {
                DEBUG_CRITICAL5("control failed (%d/%d): %d %s",
                        usbDevice[reader_index].bus_number,
                        usbDevice[reader_index].device_address, ret, 
strerror(errno));

                return ret; // STATUS_UNSUCCESSFUL;
        }

        if (requesttype & 0x80)
                DEBUG_XXD("receive: ", bytes, ret);

        return ret;
} /* ControlUSB */

Regards

Godfrey
_______________________________________________
Muscle mailing list
[email protected]
http://lists.drizzle.com/mailman/listinfo/muscle

Reply via email to