Don't truncate silently in snprintf(). - susmb - mounting of SMB/CIFS shares via FUSE
 (HTM) git clone git://git.codemadness.org/susmb
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 64313aed26f8c03e48d817d01affe47eb2df5a1e
 (DIR) parent fdd9015111ff8fcb39d85d25250d14b1d532e44f
 (HTM) Author: Geoff Johnstone <qwerty@acm.org>
       Date:   Sat, 13 Mar 2010 13:29:26 +0000
       
       Don't truncate silently in snprintf().
       
       Diffstat:
         M conffile.c                          |       9 ++++++---
         M usmb.c                              |      25 ++++++++++++++++++++++---
         M utils.c                             |      31 ++++++++++++++++++++++++++++++-
         M utils.h                             |       7 +++++++
       
       4 files changed, 65 insertions(+), 7 deletions(-)
       ---
 (DIR) diff --git a/conffile.c b/conffile.c
       @@ -111,8 +111,11 @@ static bool do_xpath_text (xmlXPathContextPtr ctx,
                                   const char *child, char **out)
        {
          char xpath[2048];
       -  snprintf (xpath, sizeof (xpath),
       -            "/usmbconfig/%s[@id='%s']/%s/text()", parent, id, child);
       +
       +  if (!bsnprintf (xpath, sizeof (xpath),
       +                  "/usmbconfig/%s[@id='%s']/%s/text()", parent, id, child))
       +    return false;
       +
          return xml_xpath_text (ctx, xpath, (void *)out);
        }
        
       @@ -146,7 +149,7 @@ bool conffile_get_mount (const char *filename, const char *key,
            if (!do_xpath_text (ctx, "mount", key, "mountpoint", mountpoint)) break;
            (void)do_xpath_text (ctx, "mount", key, "options", options);
        
       -    snprintf (xp, sizeof (xp), "/usmbconfig/mount[@id='%s']", key);
       +    if (!snprintf (xp, sizeof (xp), "/usmbconfig/mount[@id='%s']", key)) break;
            if (!xml_xpath_attr_value (ctx, xp, "credentials", &creds)) break;
        
            (void)do_xpath_text (ctx, "credentials", creds, "domain", domain);
 (DIR) diff --git a/usmb.c b/usmb.c
       @@ -21,6 +21,7 @@
        #include "samba3x-compat.h"
        #include <fuse.h>
        #include <assert.h>
       +#include <limits.h>
        #include <errno.h>
        #include <stdarg.h>
        #include <stdbool.h>
       @@ -190,7 +191,13 @@ static bool create_share_name (const char *server_, const char *sharename)
            return false;
          }
        
       -  snprintf (share, len, "smb://%s/%s", server_, sharename);
       +  if (!bsnprintf (share, len, "smb://%s/%s", server_, sharename))
       +  {
       +    fputs ("Share server and/or name are too long.\n", stderr);
       +    free (share);
       +    return false;
       +  }
       +
          DEBUG (fprintf (stderr, "Share URL: %s\n", share));
          return true;
        }
       @@ -276,8 +283,20 @@ int main (int argc, char **argv)
          }
        
          {
       -    static char conf[256];
       -    snprintf (conf, sizeof (conf), "%s/.usmb.conf", getenv ("HOME"));
       +    static char conf[PATH_MAX];
       +    const char * const HOME = getenv ("HOME");
       +    if (NULL == HOME)
       +    {
       +      fputs ("Please set the HOME environment variable.\n", stderr);
       +      return EXIT_FAILURE;
       +    }
       +
       +    if (!bsnprintf (conf, sizeof (conf), "%s/.usmb.conf", HOME))
       +    {
       +      fputs ("Configuration file path is too long.\n", stderr);
       +      return EXIT_FAILURE;
       +    }
       +
            conffile = conf;
          }
        
 (DIR) diff --git a/utils.c b/utils.c
       @@ -1,5 +1,5 @@
        /* usmb - mount SMB shares via FUSE and Samba
       - * Copyright (C) 2006-2009 Geoff Johnstone
       + * Copyright (C) 2006-2010 Geoff Johnstone
         *
         * This program is free software; you can redistribute it and/or modify
         * it under the terms of the GNU General Public License version 3 as
       @@ -140,3 +140,32 @@ void xfree_errno (const void *ptr)
          errno = err;
        }
        
       +
       +bool bsnprintf (char *str, size_t size, const char *format, ...)
       +{
       +  va_list ap;
       +  bool ret;
       +
       +  assert (str);
       +  assert (format);
       +
       +  va_start (ap, format);
       +  ret = bvsnprintf (str, size, format, ap);
       +  va_end (ap);
       +
       +  return ret;
       +}
       +
       +
       +bool bvsnprintf (char *str, size_t size, const char *format, va_list ap)
       +{
       +  int ret;
       +
       +  assert (str);
       +  assert (format);
       +
       +  ret = vsnprintf (str, size, format, ap);
       +
       +  return ((ret >= 0) && ((size_t)ret < size));
       +}
       +
 (DIR) diff --git a/utils.h b/utils.h
       @@ -17,6 +17,10 @@
        #ifndef UTILS_H
          #define UTILS_H
        
       +  #include <stdarg.h>
       +  #include <stdbool.h>
       +  #include <stddef.h>
       +
          #ifdef DEBUG
            #undef DEBUG
            #define DEBUG(x) (x)
       @@ -31,5 +35,8 @@
          void clear_and_free (char *ptr);
          void free_errno (const void *ptr);
          void xfree_errno (const void *ptr);
       +  bool bsnprintf (char *str, size_t size, const char *format, ...)
       +    __attribute__ ((format (printf, 3, 4)));
       +  bool bvsnprintf (char *str, size_t size, const char *format, va_list ap);
        
        #endif