]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Avoid undefined behaviour when parsing HS protocol versions
authorRobert Ransom <rransom.8774@gmail.com>
Thu, 13 Sep 2012 11:39:39 +0000 (07:39 -0400)
committerRobert Ransom <rransom.8774@gmail.com>
Thu, 13 Sep 2012 11:48:21 +0000 (07:48 -0400)
Fixes bug 6827; bugfix on c58675ca728f12b42f65e5b8964ae695c2e0ec2d
(when the v2 HS desc parser was implemented).

Found by asn.

changes/bug6827 [new file with mode: 0644]
src/or/or.h
src/or/routerparse.c

diff --git a/changes/bug6827 b/changes/bug6827
new file mode 100644 (file)
index 0000000..799c459
--- /dev/null
@@ -0,0 +1,8 @@
+  o Minor bugfixes:
+
+    - Avoid undefined behaviour when parsing the list of supported
+      rendezvous/introduction protocols in a hidden service
+      descriptor.  Previously, Tor would have confused (as-yet-unused)
+      protocol version numbers greater than 32 with lower ones on many
+      platforms.  Bugfix on 0.2.0.10-alpha; found by George Kadianakis.
+
index 9074083a0430306a7fe7dcac3f44b0d65f70ef2a..51c23d305d1d0bffb0cc227fccc715d26431ec91 100644 (file)
@@ -4279,14 +4279,17 @@ typedef struct rend_intro_point_t {
   time_t time_expiring;
 } rend_intro_point_t;
 
+#define REND_PROTOCOL_VERSION_BITMASK_WIDTH 16
+
 /** Information used to connect to a hidden service.  Used on both the
  * service side and the client side. */
 typedef struct rend_service_descriptor_t {
   crypto_pk_t *pk; /**< This service's public key. */
   int version; /**< Version of the descriptor format: 0 or 2. */
   time_t timestamp; /**< Time when the descriptor was generated. */
-  uint16_t protocols; /**< Bitmask: which rendezvous protocols are supported?
-                       * (We allow bits '0', '1', and '2' to be set.) */
+  /** Bitmask: which rendezvous protocols are supported?
+   * (We allow bits '0', '1', and '2' to be set.) */
+  int protocols : REND_PROTOCOL_VERSION_BITMASK_WIDTH;
   /** List of the service's introduction points.  Elements are removed if
    * introduction attempts fail. */
   smartlist_t *intro_nodes;
index 60a2eae75f63a699142c7fceafdda4655da0d56c..2bf072b3cf6f9e94ff03d4e18ac638d9670239f5 100644 (file)
@@ -4823,6 +4823,9 @@ rend_parse_v2_service_descriptor(rend_service_descriptor_t **parsed_out,
                                    10, 0, INT_MAX, &num_ok, NULL);
     if (!num_ok) /* It's a string; let's ignore it. */
       continue;
+    if (version >= REND_PROTOCOL_VERSION_BITMASK_WIDTH)
+      /* Avoid undefined left-shift behaviour. */
+      continue;
     result->protocols |= 1 << version;
   }
   SMARTLIST_FOREACH(versions, char *, cp, tor_free(cp));