48 lines
1.7 KiB
Diff
48 lines
1.7 KiB
Diff
From caab270a739d619cfa3b8d4c57789cb6b1ef94e8 Mon Sep 17 00:00:00 2001
|
|
From: Andrew Price <anprice@redhat.com>
|
|
Date: Thu, 11 May 2023 17:04:34 +0100
|
|
Subject: [PATCH] fsck.gfs2: Tighten offset check in check_eattr_entries()
|
|
|
|
The "offset >= bsize" check is insufficient as it doesn't detect invalid
|
|
ea_header offsets less than one ea_header from the end of the block.
|
|
This fixes an unlikely fsck.gfs2 buffer over-read that can occur.
|
|
|
|
For the bug to occur:
|
|
1. The last valid xattr header must not have GFS2_EAFLAG_LAST set
|
|
2. Its ea_rec_len must result in an offset of the next xattr within 15
|
|
bytes of the end of the block
|
|
|
|
A segfault can then occur if this region contains non-zero data that
|
|
results in the loop continuing with another bad offset and another bad
|
|
read, and so on.
|
|
|
|
Signed-off-by: Andrew Price <anprice@redhat.com>
|
|
---
|
|
gfs2/fsck/metawalk.c | 3 ++-
|
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
|
|
index 66316e4d864c..819a7e670f73 100644
|
|
--- a/gfs2/fsck/metawalk.c
|
|
+++ b/gfs2/fsck/metawalk.c
|
|
@@ -846,6 +846,7 @@ static int check_eattr_entries(struct fsck_cx *cx, struct lgfs2_inode *ip,
|
|
int i;
|
|
int error = 0, err;
|
|
uint32_t offset = (uint32_t)sizeof(struct gfs2_meta_header);
|
|
+ uint32_t offset_limit = ip->i_sbd->sd_bsize - sizeof(struct gfs2_ea_header);
|
|
|
|
if (!pass->check_eattr_entry)
|
|
return 0;
|
|
@@ -894,7 +895,7 @@ static int check_eattr_entries(struct fsck_cx *cx, struct lgfs2_inode *ip,
|
|
}
|
|
offset += be32_to_cpu(ea_hdr->ea_rec_len);
|
|
if (ea_hdr->ea_flags & GFS2_EAFLAG_LAST ||
|
|
- offset >= ip->i_sbd->sd_bsize || ea_hdr->ea_rec_len == 0){
|
|
+ offset > offset_limit || ea_hdr->ea_rec_len == 0) {
|
|
break;
|
|
}
|
|
ea_hdr_prev = ea_hdr;
|
|
--
|
|
2.35.3
|
|
|