214838
From a71071230eb0726a9c9211048dc27b12613058a2 Mon Sep 17 00:00:00 2001
214838
From: "Richard W.M. Jones" <rjones@redhat.com>
214838
Date: Thu, 8 Jul 2021 19:00:45 +0100
214838
Subject: [PATCH 16/16] lib/node.c: Limit recursion in ri-records
214838
 (CVE-2021-3622)
214838
214838
Windows Registry hive "ri"-records are arbitrarily nested B-tree-like
214838
structures:
214838
214838
  +-------------+
214838
  | ri          |
214838
  |-------------|
214838
  | nr_offsets  |
214838
  |   offset[0] ------>  points to another lf/lh/li/ri block
214838
  |   offset[1] ------>
214838
  |   offset[2] ------>
214838
  +-------------+
214838
214838
It is possible to construct a hive with a very deeply nested tree of
214838
ri-records, causing the internal _get_children function to recurse to
214838
any depth which can cause programs linked to hivex to crash with a
214838
stack overflow.
214838
214838
Since it is not thought that deeply nested ri-records occur in real
214838
hives, limit recursion depth.  If you hit this limit you will see the
214838
following error and the operation will return an error instead of
214838
crashing:
214838
214838
  \> ls
214838
  hivex: _get_children: returning EINVAL because: ri-record nested to depth >= 32
214838
  ls: Invalid argument
214838
214838
Thanks to Jeremy Galindo for finding and reporting this bug.
214838
214838
Reported-by: Jeremy Galindo, Sr Security Engineer, Datto.com
214838
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
214838
Fixes: CVE-2021-3622
214838
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1975489
214838
(cherry picked from commit 781a12c4a49dd81365c9c567c5aa5e19e894ba0e)
214838
(cherry picked from commit 771728218dac2fbf6997a7e53225e75a4c6b7255)
214838
---
214838
 lib/node.c | 18 ++++++++++++++----
214838
 1 file changed, 14 insertions(+), 4 deletions(-)
214838
214838
diff --git a/lib/node.c b/lib/node.c
214838
index a90c964..c13b894 100644
214838
--- a/lib/node.c
214838
+++ b/lib/node.c
214838
@@ -203,7 +203,7 @@ hivex_node_classname (hive_h *h, hive_node_h node)
214838
 
214838
 static int _get_children (hive_h *h, hive_node_h blkoff,
214838
                           offset_list *children, offset_list *blocks,
214838
-                          int flags);
214838
+                          int flags, unsigned depth);
214838
 static int check_child_is_nk_block (hive_h *h, hive_node_h child, int flags);
214838
 
214838
 /* Iterate over children (ie. subkeys of a node), returning child
214838
@@ -335,7 +335,7 @@ _hivex_get_children (hive_h *h, hive_node_h node,
214838
     goto error;
214838
   }
214838
 
214838
-  if (_get_children (h, subkey_lf, &children, &blocks, flags) == -1)
214838
+  if (_get_children (h, subkey_lf, &children, &blocks, flags, 0) == -1)
214838
     goto error;
214838
 
214838
   /* Check the number of children we ended up reading matches
214838
@@ -383,7 +383,7 @@ _hivex_get_children (hive_h *h, hive_node_h node,
214838
 static int
214838
 _get_children (hive_h *h, hive_node_h blkoff,
214838
                offset_list *children, offset_list *blocks,
214838
-               int flags)
214838
+               int flags, unsigned depth)
214838
 {
214838
   /* Add this intermediate block. */
214838
   if (_hivex_add_to_offset_list (blocks, blkoff) == -1)
214838
@@ -486,7 +486,17 @@ _get_children (hive_h *h, hive_node_h blkoff,
214838
         }
214838
       }
214838
 
214838
-      if (_get_children (h, offset, children, blocks, flags) == -1)
214838
+      /* Although in theory hive ri records might be nested to any
214838
+       * depth, in practice this is unlikely.  Recursing here caused
214838
+       * CVE-2021-3622.  Thus limit the depth we will recurse to
214838
+       * something small.
214838
+       */
214838
+      if (depth >= 32) {
214838
+        SET_ERRNO (EINVAL, "ri-record nested to depth >= %u", depth);
214838
+        return -1;
214838
+      }
214838
+
214838
+      if (_get_children (h, offset, children, blocks, flags, depth+1) == -1)
214838
         return -1;
214838
     }
214838
   }
214838
-- 
214838
1.8.3.1
214838