Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 6 Sep 2023 04:19:42 GMT
From:      Zhenlei Huang <zlei@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 809450c4b531 - stable/13 - geom_linux_lvm: Check the offset of physical volume header
Message-ID:  <202309060419.3864Jg1T057449@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by zlei:

URL: https://cgit.FreeBSD.org/src/commit/?id=809450c4b53109b6ca8a87054452f2b3b8f711aa

commit 809450c4b53109b6ca8a87054452f2b3b8f711aa
Author:     Zhenlei Huang <zlei@FreeBSD.org>
AuthorDate: 2023-08-22 09:20:10 +0000
Commit:     Zhenlei Huang <zlei@FreeBSD.org>
CommitDate: 2023-09-06 04:17:49 +0000

    geom_linux_lvm: Check the offset of physical volume header
    
    The LVM label is stored on any of the first four sectors, and the
    PV (physical volume) header is stored within the same sector following
    the LVM label. The current implementation does not fully check the
    offset of PV header, when attaching a bad formatted LVM PV the kernel
    may crash due to out-of-bounds memory read.
    
    PR:             266562
    Reviewed by:    jhb
    MFC after:      2 weeks
    Differential Revision:  https://reviews.freebsd.org/D36773
    
    (cherry picked from commit c941b82e1c31a67a025c43cc7bd31f269fa62588)
---
 sys/geom/linux_lvm/g_linux_lvm.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/sys/geom/linux_lvm/g_linux_lvm.c b/sys/geom/linux_lvm/g_linux_lvm.c
index 2e4bbcaa045a..dddc3ae9184e 100644
--- a/sys/geom/linux_lvm/g_linux_lvm.c
+++ b/sys/geom/linux_lvm/g_linux_lvm.c
@@ -67,7 +67,8 @@ static int	g_llvm_read_label(struct g_consumer *, struct g_llvm_label *);
 static int	g_llvm_read_md(struct g_consumer *, struct g_llvm_metadata *,
 		    struct g_llvm_label *);
 
-static int	llvm_label_decode(const u_char *, struct g_llvm_label *, int);
+static int	llvm_label_decode(const u_char *, struct g_llvm_label *,
+		    int, u_int);
 static int	llvm_md_decode(const u_char *, struct g_llvm_metadata *,
 		    struct g_llvm_label *);
 static int	llvm_textconf_decode(u_char *, int,
@@ -637,7 +638,8 @@ g_llvm_read_label(struct g_consumer *cp, struct g_llvm_label *ll)
 
 	/* Search the four sectors for the LVM label. */
 	for (i = 0; i < 4; i++) {
-		error = llvm_label_decode(&buf[i * pp->sectorsize], ll, i);
+		error = llvm_label_decode(&buf[i * pp->sectorsize], ll, i,
+			    pp->sectorsize);
 		if (error == 0)
 			break;	/* found it */
 	}
@@ -703,7 +705,8 @@ g_llvm_read_md(struct g_consumer *cp, struct g_llvm_metadata *md,
 }
 
 static int
-llvm_label_decode(const u_char *data, struct g_llvm_label *ll, int sector)
+llvm_label_decode(const u_char *data, struct g_llvm_label *ll, int sector,
+    u_int sectorsize)
 {
 	uint64_t off;
 	char *uuid;
@@ -728,6 +731,13 @@ llvm_label_decode(const u_char *data, struct g_llvm_label *ll, int sector)
 		return (EINVAL);
 	}
 
+	/* XXX The minimal possible size of physical volume header is 88 */
+	if (ll->ll_offset < 32 || ll->ll_offset > sectorsize - 88) {
+		G_LLVM_DEBUG(0, "Invalid physical volume header offset %u",
+		    ll->ll_offset);
+		return (EINVAL);
+	}
+
 	off = ll->ll_offset;
 	/*
 	 * convert the binary uuid to string format, the format is



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202309060419.3864Jg1T057449>