diff options
author | Jim Meyering <jim@meyering.net> | 2012-10-23 16:10:21 +0200 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 2012-10-23 16:13:40 +0200 |
commit | 36a93b370040444d6d2240100404490064b6fa00 (patch) | |
tree | 32ff82b393ebbe6fb3d64de0c94ecdef89abe86b /libidu | |
parent | b7ac27d5fe9ef7751b79812dc0095a59bddbfd4d (diff) | |
download | idutils-36a93b370040444d6d2240100404490064b6fa00.tar.gz idutils-36a93b370040444d6d2240100404490064b6fa00.tar.bz2 idutils-36a93b370040444d6d2240100404490064b6fa00.zip |
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.
* NEWS (Bug fixes): Mention the bug fix.
Diffstat (limited to 'libidu')
-rw-r--r-- | libidu/fnprint.c | 6 | ||||
-rw-r--r-- | libidu/idfile.h | 15 |
2 files changed, 16 insertions, 5 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_ */ |