Re: [PATCH libdrm] xf86drm: fix valgrind warning in drmParsePciBusInfo

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 2017-01-12 at 18:16 -0800, Nicholas Miell wrote:
> From 714d07f600db39498c87d7816f4dd3a7e6d9bbca Mon Sep 17 00:00:00 2001
> From: Nicholas Miell <nmiell@xxxxxxxxx>
> Date: Thu, 12 Jan 2017 15:43:07 -0800
> Subject: [PATCH libdrm] xf86drm: fix valgrind warning in drmParsePciBusInfo
> 
> The current implementation reads (up to) 513 bytes, overwrites the 513th
> byte with '\0' and then passes the buffer off to strstr() and sscanf()
> without ever initializing the middle bytes. This causes valgrind
> warnings and potentially fails to parse PCI_SLOT_NAME if the uevent is
> unexpectedly large.

a simpler fix should also get rid of the valgrind warning:

-      ret = read(fd, data, sizeof(data));
-      data[sizeof(data)-1] = '\0';
+      ret = read(fd, data, sizeof(data) - 1);
       close(fd);
       if (ret < 0)
           return -errno
+      data[ret] = '\0';


I think that dynamic memory allocation is still a more robust approach.

regards,
Jan

> 
> Rewrite it using getline() to fix the valgrind errors and future-proof
> the function against uevent files larger than 513 bytes.
> 
> Signed-off-by: Nicholas Miell <nmiell@xxxxxxxxx>
> ---
>  xf86drm.c | 34 +++++++++++++++++-----------------
>  1 file changed, 17 insertions(+), 17 deletions(-)
> 
> diff --git a/xf86drm.c b/xf86drm.c
> index b8b2cfe..33261ac 100644
> --- a/xf86drm.c
> +++ b/xf86drm.c
> @@ -2919,31 +2919,31 @@ static int drmParsePciBusInfo(int maj, int min, drmPciBusInfoPtr info)
>  {
>  #ifdef __linux__
>      char path[PATH_MAX + 1];
> -    char data[512 + 1];
> -    char *str;
> +    FILE *uevent;
> +    char *line = NULL;
> +    size_t n = 0;
> +    bool found = false;
>      int domain, bus, dev, func;
> -    int fd, ret;
>  
>      snprintf(path, PATH_MAX, "/sys/dev/char/%d:%d/device/uevent", maj, min);
> -    fd = open(path, O_RDONLY);
> -    if (fd < 0)
> +    uevent = fopen(path, "r");
> +    if (uevent == NULL)
>          return -errno;
>  
> -    ret = read(fd, data, sizeof(data));
> -    data[sizeof(data)-1] = '\0';
> -    close(fd);
> -    if (ret < 0)
> -        return -errno;
> +    while (getline(&line, &n, uevent) != -1) {
> +        if (sscanf(line, "PCI_SLOT_NAME=%04x:%02x:%02x.%1u",
> +                   &domain, &bus, &dev, &func) == 4)
> +        {
> +	        found = true;
> +	        break;
> +        }
> +    }
> +    free(line);
>  
> -#define TAG "PCI_SLOT_NAME="
> -    str = strstr(data, TAG);
> -    if (str == NULL)
> -        return -EINVAL;
> +    fclose(uevent);
>  
> -    if (sscanf(str, TAG "%04x:%02x:%02x.%1u",
> -               &domain, &bus, &dev, &func) != 4)
> +    if (!found)
>          return -EINVAL;
> -#undef TAG
>  
>      info->domain = domain;
>      info->bus = bus;

-- 
Jan Vesely <jan.vesely@xxxxxxxxxxx>

Attachment: signature.asc
Description: This is a digitally signed message part

_______________________________________________
dri-devel mailing list
dri-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[Index of Archives]     [Linux DRI Users]     [Linux Intel Graphics]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux