[libvirt] [PATCH] absolutePathFromBaseFile: don't leak when first arg contains no "/"

Daniel Veillard veillard at redhat.com
Fri Feb 5 10:28:38 UTC 2010


On Fri, Feb 05, 2010 at 10:59:23AM +0100, Jim Meyering wrote:
> Daniel P. Berrange wrote:
> > Any code which uses a combination of VIR_ALLOC + strcat/strcpy/strpcpy/etc
> > really ought to be re-written to use virAsprintf(). The nested stpcpy is
> > a nice trick, but its not really helping clarity like asprintf would.
> 
> Good point.
> In spite of having to use "%.*s" in the format,
> using virAsprintf is both more readable and more concise.
> Note that there is no need to test the return value of virAsprintf here.
> Here's the incremental patch, followed by the amended one:
> 
> Note also that I've done it this way:
> 
>     virAsprintf(&res, "%.*s/%s", base_file, d_len, path);
> 
> but I could also have omitted the "/" from the format,
> since there's guaranteed to be one at base_file[d_len],
> but that is not obvious, which makes this much less readable:
> 
>     virAsprintf(&res, "%.*s%s", base_file, d_len+1, path);
> 
> Likewise, I could have avoided one of those two stpcpy calls.
>
> diff --git a/bootstrap b/bootstrap
> index 5cc43c5..113cc0f 100755
> --- a/bootstrap
> +++ b/bootstrap
> @@ -94,7 +94,6 @@ send
>  setsockopt
>  socket
>  stpcpy
> -stpncpy
>  strchrnul
>  strndup
>  strerror
> diff --git a/src/util/storage_file.c b/src/util/storage_file.c
> index 8c53fba..2c79fa9 100644
> --- a/src/util/storage_file.c
> +++ b/src/util/storage_file.c
> @@ -255,10 +255,7 @@ absolutePathFromBaseFile(const char *base_file, const char *path)
>      if (*path == '/' || d_len == 0)
>          return strdup(path);
> 
> -    if (VIR_ALLOC_N(res, d_len + 1 + strlen(path) + 1) < 0)
> -        return NULL;
> -
> -    stpcpy(stpcpy(stpncpy(res, base_file, d_len), "/"), path);
> +    virAsprintf(&res, "%.*s/%s", base_file, d_len, path);
>      return res;
>  }
> 
> 
> >From 8653369953741ceb0451db998e8c766220dd9ac4 Mon Sep 17 00:00:00 2001
> From: Jim Meyering <meyering at redhat.com>
> Date: Thu, 4 Feb 2010 16:55:57 +0100
> Subject: [PATCH] absolutePathFromBaseFile: don't leak when first arg contains no "/"
> 
> * src/util/storage_file.c: Include "dirname.h".
> (absolutePathFromBaseFile): Rewrite not to leak, and to require
> fewer allocations.
> * bootstrap (modules): Add dirname-lgpl.
> * .gnulib: Update submodule to the latest.
> ---
>  .gnulib                 |    2 +-
>  bootstrap               |    1 +
>  src/util/storage_file.c |   26 ++++++++------------------
>  3 files changed, 10 insertions(+), 19 deletions(-)
> 
> diff --git a/.gnulib b/.gnulib
> index 146d914..9d0ad65 160000
> --- a/.gnulib
> +++ b/.gnulib
> @@ -1 +1 @@
> -Subproject commit 146d9145073e62a2096a2d6b33f75e93908fedf3
> +Subproject commit 9d0ad652de159d08e5f679842f8a2a5658196361
> diff --git a/bootstrap b/bootstrap
> index cc3c6ef..113cc0f 100755
> --- a/bootstrap
> +++ b/bootstrap
> @@ -71,6 +71,7 @@ c-ctype
>  canonicalize-lgpl
>  close
>  connect
> +dirname-lgpl
>  getaddrinfo
>  gethostname
>  getpass
> diff --git a/src/util/storage_file.c b/src/util/storage_file.c
> index 44057d2..2c79fa9 100644
> --- a/src/util/storage_file.c
> +++ b/src/util/storage_file.c
> @@ -1,7 +1,7 @@
>  /*
>   * storage_file.c: file utility functions for FS storage backend
>   *
> - * Copyright (C) 2007-2009 Red Hat, Inc.
> + * Copyright (C) 2007-2010 Red Hat, Inc.
>   * Copyright (C) 2007-2008 Daniel P. Berrange
>   *
>   * This library is free software; you can redistribute it and/or
> @@ -26,6 +26,7 @@
> 
>  #include <unistd.h>
>  #include <fcntl.h>
> +#include "dirname.h"
>  #include "memory.h"
>  #include "virterror_internal.h"
> 
> @@ -246,26 +247,15 @@ vmdk4GetBackingStore(virConnectPtr conn,
>  static char *
>  absolutePathFromBaseFile(const char *base_file, const char *path)
>  {
> -    size_t base_size, path_size;
> -    char *res, *p;
> +    char *res;
> +    size_t d_len = dir_len (base_file);
> 
> -    if (*path == '/')
> +    /* If path is already absolute, or if dirname(base_file) is ".",
> +       just return a copy of path.  */
> +    if (*path == '/' || d_len == 0)
>          return strdup(path);
> 
> -    base_size = strlen(base_file) + 1;
> -    path_size = strlen(path) + 1;
> -    if (VIR_ALLOC_N(res, base_size - 1 + path_size) < 0)
> -        return NULL;
> -    memcpy(res, base_file, base_size);
> -    p = strrchr(res, '/');
> -    if (p != NULL)
> -        p++;
> -    else
> -        p = res;
> -    memcpy(p, path, path_size);
> -    if (VIR_REALLOC_N(res, (p + path_size) - res) < 0) {
> -        /* Ignore failure */
> -    }
> +    virAsprintf(&res, "%.*s/%s", base_file, d_len, path);
>      return res;
>  }
> 

  ACK,

Daniel

-- 
Daniel Veillard      | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
daniel at veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/




More information about the libvir-list mailing list