bug-idutils
[Top][All Lists]
Advanced

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

[bug-idutils] [PATCH] lid: avoid reading beyond end of buffer for a long


From: Jim Meyering
Subject: [bug-idutils] [PATCH] lid: avoid reading beyond end of buffer for a long name
Date: Tue, 23 Oct 2012 16:11:40 +0200

FYI,

>From 30b13233f7a4d01d3a1826244661a6588e8c3f98 Mon Sep 17 00:00:00 2001
From: Jim Meyering <address@hidden>
Date: Tue, 23 Oct 2012 16:10:21 +0200
Subject: [PATCH] lid: avoid reading beyond end of buffer for a long name

* libidu/idfile.h (stzncpy): Define, from coreutils.
* src/lid.c (query_ambiguous_prefix): Avoid buffer overrun.
Using strncpy to copy a too-long name would result in a "name"
that is not NUL-terminated, yet that name would be treated as
a NUL-terminated string immediately afterwards, via report_func,
which attempts to print it.
* libidu/fnprint.c (root_name): Use stzncpy in place of strncpy.
---
 libidu/fnprint.c |  6 +-----
 libidu/idfile.h  | 15 +++++++++++++++
 src/lid.c        |  4 ++--
 3 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/libidu/fnprint.c b/libidu/fnprint.c
index b8d97ce..4129441 100644
--- a/libidu/fnprint.c
+++ b/libidu/fnprint.c
@@ -46,11 +46,7 @@ root_name (char const *file_name)
   char const *dot = strrchr (file_name, '.');

   if (dot)
-    {
-      int length = dot - file_name;
-      strncpy (file_name_buffer, file_name, length);
-      file_name_buffer[length] = '\0';
-    }
+    stzncpy (file_name_buffer, file_name, dot - file_name);
   else
     strcpy (file_name_buffer, file_name);
   return file_name_buffer;
diff --git a/libidu/idfile.h b/libidu/idfile.h
index 739819d..3775d7a 100644
--- a/libidu/idfile.h
+++ b/libidu/idfile.h
@@ -225,4 +225,19 @@ extern off_t largest_member_file;

 #define DEFAULT_ID_FILE_NAME "ID"

+/* Like stpncpy, but do ensure that the result is NUL-terminated,
+   and do not NUL-pad out to LEN.  I.e., when strnlen (src, len) == len,
+   this function writes a NUL byte into dest[len].  Thus, the length
+   of the destination buffer must be at least LEN + 1.
+   The DEST and SRC buffers must not overlap.  */
+static inline char *
+stzncpy (char *restrict dest, char const *restrict src, size_t len)
+{
+  char const *src_end = src + len;
+  while (src < src_end && *src)
+    *dest++ = *src++;
+  *dest = 0;
+  return dest;
+}
+
 #endif /* not _idfile_h_ */
diff --git a/src/lid.c b/src/lid.c
index cd307c0..8a31268 100644
--- a/src/lid.c
+++ b/src/lid.c
@@ -1042,7 +1042,7 @@ query_ambiguous_prefix (unsigned int limit, report_func_t 
report_func)
        {
          if (consecutive && key_style != ks_token)
            {
-             strncpy (&name[1], old, limit);
+             stzncpy (&name[1], old, limit - 2);
              (*report_func) (name, bits_to_flinkv (bits_vec));
            }
          consecutive = 0;
@@ -1064,7 +1064,7 @@ query_ambiguous_prefix (unsigned int limit, report_func_t 
report_func)
     }
   if (consecutive && key_style != ks_token)
     {
-      strncpy (&name[1], new, limit);
+      stzncpy (&name[1], new, limit - 2);
       (*report_func) (name, bits_to_flinkv (bits_vec));
     }
   return count;
--
1.8.0



reply via email to

[Prev in Thread] Current Thread [Next in Thread]