[tor-commits] [tor/master] Move various mem* functions to lib/string

nickm at torproject.org nickm at torproject.org
Wed Jun 27 21:22:39 UTC 2018


commit e165c9c304800718daa589469349282110e00909
Author: Nick Mathewson <nickm at torproject.org>
Date:   Wed Jun 27 15:36:42 2018 -0400

    Move various mem* functions to lib/string
---
 src/common/compat.c          |  46 ------------------
 src/common/compat.h          |  10 ----
 src/common/util.c            |  55 ----------------------
 src/common/util.h            |   4 --
 src/lib/string/.may_include  |   1 +
 src/lib/string/util_string.c | 108 +++++++++++++++++++++++++++++++++++++++++++
 src/lib/string/util_string.h |   8 ++++
 7 files changed, 117 insertions(+), 115 deletions(-)

diff --git a/src/common/compat.c b/src/common/compat.c
index 367ea26c2..cdc53175d 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -131,52 +131,6 @@ SecureZeroMemory(PVOID ptr, SIZE_T cnt)
 #include "lib/net/address.h"
 #include "lib/sandbox/sandbox.h"
 
-/** Given <b>hlen</b> bytes at <b>haystack</b> and <b>nlen</b> bytes at
- * <b>needle</b>, return a pointer to the first occurrence of the needle
- * within the haystack, or NULL if there is no such occurrence.
- *
- * This function is <em>not</em> timing-safe.
- *
- * Requires that <b>nlen</b> be greater than zero.
- */
-const void *
-tor_memmem(const void *_haystack, size_t hlen,
-           const void *_needle, size_t nlen)
-{
-#if defined(HAVE_MEMMEM) && (!defined(__GNUC__) || __GNUC__ >= 2)
-  tor_assert(nlen);
-  return memmem(_haystack, hlen, _needle, nlen);
-#else
-  /* This isn't as fast as the GLIBC implementation, but it doesn't need to
-   * be. */
-  const char *p, *last_possible_start;
-  const char *haystack = (const char*)_haystack;
-  const char *needle = (const char*)_needle;
-  char first;
-  tor_assert(nlen);
-
-  if (nlen > hlen)
-    return NULL;
-
-  p = haystack;
-  /* Last position at which the needle could start. */
-  last_possible_start = haystack + hlen - nlen;
-  first = *(const char*)needle;
-  while ((p = memchr(p, first, last_possible_start + 1 - p))) {
-    if (fast_memeq(p, needle, nlen))
-      return p;
-    if (++p > last_possible_start) {
-      /* This comparison shouldn't be necessary, since if p was previously
-       * equal to last_possible_start, the next memchr call would be
-       * "memchr(p, first, 0)", which will return NULL. But it clarifies the
-       * logic. */
-      return NULL;
-    }
-  }
-  return NULL;
-#endif /* defined(HAVE_MEMMEM) && (!defined(__GNUC__) || __GNUC__ >= 2) */
-}
-
 /** Represents a lockfile on which we hold the lock. */
 struct tor_lockfile_t {
   /** Name of the file */
diff --git a/src/common/compat.h b/src/common/compat.h
index 766f62557..399badb6a 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -63,16 +63,6 @@
 #include <stdio.h>
 #include <errno.h>
 
-const void *tor_memmem(const void *haystack, size_t hlen, const void *needle,
-                       size_t nlen) ATTR_NONNULL((1,3));
-static const void *tor_memstr(const void *haystack, size_t hlen,
-                           const char *needle) ATTR_NONNULL((1,3));
-static inline const void *
-tor_memstr(const void *haystack, size_t hlen, const char *needle)
-{
-  return tor_memmem(haystack, hlen, needle, strlen(needle));
-}
-
 /* ===== Time compatibility */
 
 struct tm *tor_localtime_r(const time_t *timep, struct tm *result);
diff --git a/src/common/util.c b/src/common/util.c
index 09d3b2679..64efbc81e 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -240,54 +240,6 @@ hex_str(const char *from, size_t fromlen)
   return buf;
 }
 
-/** Compare the value of the string <b>prefix</b> with the start of the
- * <b>memlen</b>-byte memory chunk at <b>mem</b>.  Return as for strcmp.
- *
- * [As fast_memcmp(mem, prefix, strlen(prefix)) but returns -1 if memlen is
- * less than strlen(prefix).]
- */
-int
-fast_memcmpstart(const void *mem, size_t memlen,
-                const char *prefix)
-{
-  size_t plen = strlen(prefix);
-  if (memlen < plen)
-    return -1;
-  return fast_memcmp(mem, prefix, plen);
-}
-
-/** Return true iff the 'len' bytes at 'mem' are all zero. */
-int
-tor_mem_is_zero(const char *mem, size_t len)
-{
-  static const char ZERO[] = {
-    0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
-  };
-  while (len >= sizeof(ZERO)) {
-    /* It's safe to use fast_memcmp here, since the very worst thing an
-     * attacker could learn is how many initial bytes of a secret were zero */
-    if (fast_memcmp(mem, ZERO, sizeof(ZERO)))
-      return 0;
-    len -= sizeof(ZERO);
-    mem += sizeof(ZERO);
-  }
-  /* Deal with leftover bytes. */
-  if (len)
-    return fast_memeq(mem, ZERO, len);
-
-  return 1;
-}
-
-/** Return true iff the DIGEST_LEN bytes in digest are all zero. */
-int
-tor_digest_is_zero(const char *digest)
-{
-  static const uint8_t ZERO_DIGEST[] = {
-    0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
-  };
-  return tor_memeq(digest, ZERO_DIGEST, DIGEST_LEN);
-}
-
 /** Return true if <b>string</b> is a valid 'key=[value]' string.
  *  "value" is optional, to indicate the empty string. Log at logging
  *  <b>severity</b> if something ugly happens. */
@@ -436,13 +388,6 @@ string_is_valid_nonrfc_hostname(const char *string)
   return result;
 }
 
-/** Return true iff the DIGEST256_LEN bytes in digest are all zero. */
-int
-tor_digest256_is_zero(const char *digest)
-{
-  return tor_mem_is_zero(digest, DIGEST256_LEN);
-}
-
 /** Return a newly allocated string equal to <b>string</b>, except that every
  * character in <b>chars_to_escape</b> is preceded by a backslash. */
 char *
diff --git a/src/common/util.h b/src/common/util.h
index 2b16fc457..f16a1fa98 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -78,10 +78,6 @@ int string_is_valid_nonrfc_hostname(const char *string);
 int string_is_valid_ipv4_address(const char *string);
 int string_is_valid_ipv6_address(const char *string);
 
-int tor_mem_is_zero(const char *mem, size_t len);
-int tor_digest_is_zero(const char *digest);
-int tor_digest256_is_zero(const char *digest);
-
 char *tor_escape_str_for_pt_args(const char *string,
                                  const char *chars_to_escape);
 
diff --git a/src/lib/string/.may_include b/src/lib/string/.may_include
index c5d771861..ec5c76983 100644
--- a/src/lib/string/.may_include
+++ b/src/lib/string/.may_include
@@ -1,5 +1,6 @@
 orconfig.h
 lib/cc/*.h
+lib/defs/*.h
 lib/err/*.h
 lib/malloc/*.h
 lib/ctime/*.h
diff --git a/src/lib/string/util_string.c b/src/lib/string/util_string.c
index aba37fcc0..e8ed3d4f5 100644
--- a/src/lib/string/util_string.c
+++ b/src/lib/string/util_string.c
@@ -7,10 +7,102 @@
 #include "lib/string/compat_ctype.h"
 #include "lib/err/torerr.h"
 #include "lib/ctime/di_ops.h"
+#include "lib/defs/digest_sizes.h"
 
 #include <string.h>
 #include <stdlib.h>
 
+/** Given <b>hlen</b> bytes at <b>haystack</b> and <b>nlen</b> bytes at
+ * <b>needle</b>, return a pointer to the first occurrence of the needle
+ * within the haystack, or NULL if there is no such occurrence.
+ *
+ * This function is <em>not</em> timing-safe.
+ *
+ * Requires that <b>nlen</b> be greater than zero.
+ */
+const void *
+tor_memmem(const void *_haystack, size_t hlen,
+           const void *_needle, size_t nlen)
+{
+#if defined(HAVE_MEMMEM) && (!defined(__GNUC__) || __GNUC__ >= 2)
+  raw_assert(nlen);
+  return memmem(_haystack, hlen, _needle, nlen);
+#else
+  /* This isn't as fast as the GLIBC implementation, but it doesn't need to
+   * be. */
+  const char *p, *last_possible_start;
+  const char *haystack = (const char*)_haystack;
+  const char *needle = (const char*)_needle;
+  char first;
+  raw_assert(nlen);
+
+  if (nlen > hlen)
+    return NULL;
+
+  p = haystack;
+  /* Last position at which the needle could start. */
+  last_possible_start = haystack + hlen - nlen;
+  first = *(const char*)needle;
+  while ((p = memchr(p, first, last_possible_start + 1 - p))) {
+    if (fast_memeq(p, needle, nlen))
+      return p;
+    if (++p > last_possible_start) {
+      /* This comparison shouldn't be necessary, since if p was previously
+       * equal to last_possible_start, the next memchr call would be
+       * "memchr(p, first, 0)", which will return NULL. But it clarifies the
+       * logic. */
+      return NULL;
+    }
+  }
+  return NULL;
+#endif /* defined(HAVE_MEMMEM) && (!defined(__GNUC__) || __GNUC__ >= 2) */
+}
+
+const void *
+tor_memstr(const void *haystack, size_t hlen, const char *needle)
+{
+  return tor_memmem(haystack, hlen, needle, strlen(needle));
+}
+
+/** Return true iff the 'len' bytes at 'mem' are all zero. */
+int
+tor_mem_is_zero(const char *mem, size_t len)
+{
+  static const char ZERO[] = {
+    0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
+  };
+  while (len >= sizeof(ZERO)) {
+    /* It's safe to use fast_memcmp here, since the very worst thing an
+     * attacker could learn is how many initial bytes of a secret were zero */
+    if (fast_memcmp(mem, ZERO, sizeof(ZERO)))
+      return 0;
+    len -= sizeof(ZERO);
+    mem += sizeof(ZERO);
+  }
+  /* Deal with leftover bytes. */
+  if (len)
+    return fast_memeq(mem, ZERO, len);
+
+  return 1;
+}
+
+/** Return true iff the DIGEST_LEN bytes in digest are all zero. */
+int
+tor_digest_is_zero(const char *digest)
+{
+  static const uint8_t ZERO_DIGEST[] = {
+    0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
+  };
+  return tor_memeq(digest, ZERO_DIGEST, DIGEST_LEN);
+}
+
+/** Return true iff the DIGEST256_LEN bytes in digest are all zero. */
+int
+tor_digest256_is_zero(const char *digest)
+{
+  return tor_mem_is_zero(digest, DIGEST256_LEN);
+}
+
 /** Remove from the string <b>s</b> every character which appears in
  * <b>strip</b>. */
 void
@@ -140,6 +232,22 @@ strcasecmpstart(const char *s1, const char *s2)
   return strncasecmp(s1, s2, n);
 }
 
+/** Compare the value of the string <b>prefix</b> with the start of the
+ * <b>memlen</b>-byte memory chunk at <b>mem</b>.  Return as for strcmp.
+ *
+ * [As fast_memcmp(mem, prefix, strlen(prefix)) but returns -1 if memlen is
+ * less than strlen(prefix).]
+ */
+int
+fast_memcmpstart(const void *mem, size_t memlen,
+                const char *prefix)
+{
+  size_t plen = strlen(prefix);
+  if (memlen < plen)
+    return -1;
+  return fast_memcmp(mem, prefix, plen);
+}
+
 /** Compares the last strlen(s2) characters of s1 with s2.  Returns as for
  * strcmp.
  */
diff --git a/src/lib/string/util_string.h b/src/lib/string/util_string.h
index f194c3637..bdc2e77ce 100644
--- a/src/lib/string/util_string.h
+++ b/src/lib/string/util_string.h
@@ -11,6 +11,14 @@
 
 #include <stddef.h>
 
+const void *tor_memmem(const void *haystack, size_t hlen, const void *needle,
+                       size_t nlen) ATTR_NONNULL((1,3));
+const void *tor_memstr(const void *haystack, size_t hlen,
+                       const char *needle) ATTR_NONNULL((1,3));
+int tor_mem_is_zero(const char *mem, size_t len);
+int tor_digest_is_zero(const char *digest);
+int tor_digest256_is_zero(const char *digest);
+
 /** Allowable characters in a hexadecimal string. */
 #define HEX_CHARACTERS "0123456789ABCDEFabcdef"
 void tor_strlower(char *s) ATTR_NONNULL((1));





More information about the tor-commits mailing list