Bug#985974: grub-common: grub-probe fails to parse lvm metadata with lvm type "cache-pool+METADATA_FORMAT"

Keyu Tao taoky99 at outlook.com
Sun Mar 28 10:18:32 BST 2021


Hi Debian GRUB maintainers,

I have written a patch today trying to fix this bug. Idea is that when 
grub_lvm_detect() meets unknown lvm segment type, manually iterate all 
characters afterwards until we are sure this segment finishes parsed.

--- lvm.c    2021-03-28 09:07:30.000000000 +0000
+++ /root/grub2-2.02+dfsg1/grub-core/disk/lvm.c    2021-03-28 
09:01:21.988239003 +0000
@@ -778,6 +778,28 @@
                if (p2)
              *p2 ='"';
  #endif
+              /* currently p pointer is in a string */
+              int in_string = ~0;
+              int brackets = 0;
+              while (++p)
+            {
+              if (*p == '"')
+                in_string = ~in_string;
+              if (*p == '{' && in_string == 0)
+                brackets += 1;
+              if (*p == '}' && in_string == 0)
+                {
+                  if (brackets == 0)
+                {
+                  p--;
+                  break;
+                }
+                  else
+                {
+                  brackets -= 1;
+                }
+                }
+            }
                /* Found a non-supported type, give up and move on. */
                skip_lv = 1;
                break;

I modified on the grub2 buster package, and grub-probe can work probably 
now, although this patch probably needs to be rewritten to follow GNU's 
code style.


On Sat, 27 Mar 2021 16:08:33 +0800 Keyu Tao <taoky99 at outlook.com> wrote:

 > Package: grub-common
 > Version: 2.02+dfsg1-20+deb10u4
 > Severity: important
 >
 > In lvm.c (grub-core/disk/lvm.c) of grub2, grub_lvm_detect() will 
"skip" unknown LVM type.
 > However, the lv segment type "cache-pool+METADATA_FORMAT" has a 
policy_settings like this:
 >
 > ```
 > mcache {
 > id = "BJvm0E-9uCj-Ji6a-N37P-nEuL-evA4-ZDUxdt"
 > status = ["READ", "WRITE"]
 > flags = []
 > creation_time = 1594104910 # 2020-07-07 14:55:10 +0800
 > creation_host = "mirrors4"
 > segment_count = 1
 > segment1 {
 > start_extent = 0
 > extent_count = 393216 # 1.5 Terabytes
 > type = "cache-pool+METADATA_FORMAT"
 > data = "mcache_cdata"
 > metadata = "mcache_cmeta"
 > chunk_size = 2048
 > metadata_format = 2
 > cache_mode = "writethrough"
 > policy = "smq"
 > policy_settings {
 > migration_threshold=16384
 > }
 > }
 > }
 > ```
 >
 > The unexpected "}" of policy_settings will mislead grub_strchr (p, '}')
 > to "skip" the variable p to "}", and thus grub considers parsing done,
 > and ignores all lvm metadata after this segment.
 >
 > It can bring the system unbootable. In our example, rootfs is a
 > mirror-type lv, and the "mirrors" in its segment references 2 lvs:
 >
 > ```
 > root {
 > id = "QqUaB2-R6JG-ZCFG-6LO9-KfKp-FsQx-6jeFp2"
 > status = ["READ", "WRITE", "VISIBLE"]
 > flags = []
 > creation_time = 1586435631 # 2020-04-09 20:33:51 +0800
 > creation_host = "mirrors4"
 > segment_count = 1
 > segment1 {
 > start_extent = 0
 > extent_count = 8192 # 32 Gigabytes
 > type = "mirror"
 > mirror_count = 2
 > mirror_log = "root_mlog"
 > region_size = 4096
 > mirrors = [
 > "root_mimage_0", 0,
 > "root_mimage_1", 0
 > ]
 > }
 > }



More information about the Pkg-grub-devel mailing list