strncmp is commonly used when parsing early_param options where a
fixed string is matched without the trailing zero.

A few errors exist where string comparisons use strncmp and the
length of the comparison to perform is incorrectly specified.

ie:
        strncmp(ptr, "string", 5)
where 5 should likely have been 6

There are a few of these in the kernel tree like:

drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c:2307:
        if (!strncmp(opt, "eee_timer:", 6)) {
sound/firewire/bebob/bebob.c:180:
        return strncmp(name, "FW Audiophile Bootloader", 15) != 0;

Perhaps it would be useful to introduce a function that does a
strcmp limited to the length of the 2nd string argument.

The second argument for strzcmp requires a char [], not a const char *
using a macro and BUILD_BUG_ON.

Signed-off-by: Joe Perches <j...@perches.com>
---
 include/linux/string.h |  7 +++++++
 lib/string.c           | 18 ++++++++++++++++++
 2 files changed, 25 insertions(+)

diff --git a/include/linux/string.h b/include/linux/string.h
index 26b6f6a66f83..536d00164b26 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -5,6 +5,7 @@
 #include <linux/compiler.h>    /* for inline */
 #include <linux/types.h>       /* for size_t */
 #include <linux/stddef.h>      /* for NULL */
+#include <linux/bug.h>
 #include <stdarg.h>
 #include <uapi/linux/string.h>
 
@@ -44,6 +45,12 @@ extern int strcmp(const char *,const char *);
 #ifndef __HAVE_ARCH_STRNCMP
 extern int strncmp(const char *,const char *,__kernel_size_t);
 #endif
+int _strzcmp(const char *, const char *);
+#define strzcmp(s1, s2)                                                        
\
+({                                                                     \
+       BUILD_BUG_ON(!__same_type(s2, char []));                        \
+       _strzcmp(s1, s2);                                               \
+})
 #ifndef __HAVE_ARCH_STRCASECMP
 extern int strcasecmp(const char *s1, const char *s2);
 #endif
diff --git a/lib/string.c b/lib/string.c
index ed83562a53ae..ca9e4eb26b85 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -360,6 +360,24 @@ int strncmp(const char *cs, const char *ct, size_t count)
 EXPORT_SYMBOL(strncmp);
 #endif
 
+/**
+ * _strzcmp - Compare two strings limited to the length of the 2nd string
+ * @cs: 1st string
+ * @ct: 2nd string
+ */
+int _strzcmp(const char *cs, const char *ct)
+{
+       while (*cs == *ct && *cs != 0) {
+               cs++;
+               ct++;
+       }
+       if (*ct == 0)
+               return 0;
+
+       return *(unsigned char *)cs < *(unsigned char *)ct ? -1: 1;
+}
+EXPORT_SYMBOL(_strzcmp);
+
 #ifndef __HAVE_ARCH_STRCHR
 /**
  * strchr - Find the first occurrence of a character in a string
-- 
2.10.0.rc2.1.g053435c

Reply via email to