libftdi Archives

Subject: Re: ftdi_eeprom_get_strings() failure when the device has no serial number

From: Harald Bergmann <harald.bergmann@xxxxxxxxxxxxx>
To: libftdi@xxxxxxxxxxxxxxxxxxxxxxx
Date: Thu, 18 Jul 2024 14:33:29 +0200
Hello David,

using a pointer parameter, without testing it for NULL before is a general coding error.
Multiple tests on every sub procedure call level can be dropped only, if the „not NULL“ property can be taken as sure thru all call branch possibilities.
Such is proven by static code analysis tools.
Hence, if the strncpy function use is as you told, you revealed a driver bug.
Modifying libftdi is the only way to fix it.

Best regards,
Harald Bergmann

Am 17.07.2024 um 03:42 schrieb David Walton <dwaltoneng@xxxxxxxxx>:

I have installed the latest version of libftdi in a RPi: "libftdi 1.5 (major: 1, minor: 5, micro: 0, snapshot ver: v1.5-42-gde9f01e)"

ftdi_eeprom_get_strings() fails with a segmentation fault if the connected device does not have a serial number. ftdi_eeprom_get_strings() calls strncpy(serial, eeprom->serial, serial_len);, however if the device has no serial number, then eeprom->serial == NULL

Am I taking the wrong approach, is there a way around this without modifying libftdi?. The code I am running is as follows:

/* Based on simple.c

   Simple libftdi usage example

   This program is distributed under the GPL, version 2
*/

#include <stdio.h>
#include <stdlib.h>
#include <ftdi.h>

int main(void)
{
    int ret;
    struct ftdi_context *ftdi;
    struct ftdi_version_info version;
    if ((ftdi = ftdi_new()) == 0)
    {
        fprintf(stderr, "ftdi_new failed\n");
        return EXIT_FAILURE;
    }

    version = ftdi_get_library_version();
    printf("Initialized libftdi %s (major: %d, minor: %d, micro: %d, snapshot ver: %s)\n",
           version.version_str, version.major, version.minor, version.micro,
           version.snapshot_str);

    if ((ret = ftdi_usb_open_desc(ftdi, 0x0403, 0x6010, "Lattice FTUSB Interface Cable", NULL)) < 0)
    {
        fprintf(stderr, "unable to open ftdi device: %d (%s)\n", ret, ftdi_get_error_string(ftdi));
        ftdi_free(ftdi);
        return EXIT_FAILURE;
    }

    if ((ret = ftdi_read_eeprom(ftdi)) < 0)
    {
        fprintf(stderr, "unable to open ftdi eeprom: %d (%s)\n", ret, ftdi_get_error_string(ftdi));
        ftdi_free(ftdi);
        return EXIT_FAILURE;
    }

    int value;
    if ((ret = ftdi_get_eeprom_value(ftdi, CHIP_SIZE, &value)) < 0)
    {
        fprintf(stderr, "unable to get ftdi eeprom size: %d (%s)\n", ret, ftdi_get_error_string(ftdi));
        ftdi_free(ftdi);
        return EXIT_FAILURE;
    }

    if (value < 0)
    {
        fprintf(stderr, "No EEPROM found or EEPROM empty\n");
        return EXIT_FAILURE;
    }

    if ((ret = ftdi_eeprom_decode(ftdi, 0)) < 0)
    {
        fprintf(stderr, "unable to decode ftdi eeprom: %d (%s)\n", ret, ftdi_get_error_string(ftdi));
        ftdi_free(ftdi);
        return EXIT_FAILURE;
    }

    char manufacturer[512] = "\0";
    char product[512] = "\0";
    char serial[512] = "\0";
    struct ftdi_eeprom *eeprom = ftdi->eeprom;
    if ((ret = ftdi_eeprom_get_strings(ftdi, manufacturer, sizeof(manufacturer), product, sizeof(product), serial, sizeof(serial))) < 0)
    {
        fprintf(stderr, "unable to get ftdi device info: %d (%s)\n", ret, ftdi_get_error_string(ftdi));
        ftdi_free(ftdi);
        return EXIT_FAILURE;
    }
    printf("manufacturer = %s, product = %s, serial = %s\n", manufacturer, product, serial);

    if (ftdi->type != TYPE_2232H)
    {
        fprintf(stderr, "Expected a FT2232H\n");
    }

    if ((ret = ftdi_usb_close(ftdi)) < 0)
    {
        fprintf(stderr, "unable to close ftdi device: %d (%s)\n", ret, ftdi_get_error_string(ftdi));
        ftdi_free(ftdi);
        return EXIT_FAILURE;
    }

    ftdi_free(ftdi);

    return EXIT_SUCCESS;
}



libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+unsubscribe@xxxxxxxxxxxxxxxxxxxxxxx





libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+unsubscribe@xxxxxxxxxxxxxxxxxxxxxxx


Current Thread