* fix h_size validation
@ 2024-04-29 7:01 Christoph Hellwig
2024-04-29 7:01 ` [PATCH 1/3] xfs: fix log recovery buffer allocation for the legacy h_size fixup Christoph Hellwig
` (2 more replies)
0 siblings, 3 replies; 14+ messages in thread
From: Christoph Hellwig @ 2024-04-29 7:01 UTC (permalink / raw)
To: Chandan Babu R
Cc: Darrick J. Wong, Brian Foster, Dave Chinner, Sam Sun, linux-xfs
Hi all,
this series fixes the slab out of bounds founds by Sam's fuzzer,
and tightens up the h_size validation and log recovery buffer
allocation while at it.
Diffstat:
xfs_log_recover.c | 39 +++++++++++++++++++++++++--------------
1 file changed, 25 insertions(+), 14 deletions(-)
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/3] xfs: fix log recovery buffer allocation for the legacy h_size fixup
2024-04-29 7:01 fix h_size validation Christoph Hellwig
@ 2024-04-29 7:01 ` Christoph Hellwig
2024-04-29 12:18 ` Brian Foster
2024-04-29 15:53 ` Darrick J. Wong
2024-04-29 7:01 ` [PATCH 2/3] xfs: restrict the h_size fixup in xlog_do_recovery_pass Christoph Hellwig
2024-04-29 7:02 ` [PATCH 3/3] xfs: clean up buffer allocation " Christoph Hellwig
2 siblings, 2 replies; 14+ messages in thread
From: Christoph Hellwig @ 2024-04-29 7:01 UTC (permalink / raw)
To: Chandan Babu R
Cc: Darrick J. Wong, Brian Foster, Dave Chinner, Sam Sun, linux-xfs
Commit a70f9fe52daa ("xfs: detect and handle invalid iclog size set by
mkfs") added a fixup for incorrect h_size values used for the initial
umount record in old xfsprogs versions. But it is not using this fixed
up value to size the log recovery buffer, which can lead to an out of
bounds access when the incorrect h_size does not come from the old mkfs
tool, but a fuzzer.
Fix this by open coding xlog_logrec_hblks and taking the fixed h_size
into account for this calculation.
Fixes: a70f9fe52daa ("xfs: detect and handle invalid iclog size set by mkfs")
Reported-by: Sam Sun <samsun1006219@gmail.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
fs/xfs/xfs_log_recover.c | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index b445e8ce4a7d21..bb8957927c3c2e 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -2999,7 +2999,7 @@ xlog_do_recovery_pass(
int error = 0, h_size, h_len;
int error2 = 0;
int bblks, split_bblks;
- int hblks, split_hblks, wrapped_hblks;
+ int hblks = 1, split_hblks, wrapped_hblks;
int i;
struct hlist_head rhash[XLOG_RHASH_SIZE];
LIST_HEAD (buffer_list);
@@ -3055,14 +3055,22 @@ xlog_do_recovery_pass(
if (error)
goto bread_err1;
- hblks = xlog_logrec_hblks(log, rhead);
- if (hblks != 1) {
- kvfree(hbp);
- hbp = xlog_alloc_buffer(log, hblks);
+ /*
+ * This open codes xlog_logrec_hblks so that we can reuse the
+ * fixed up h_size value calculated above. Without that we'd
+ * still allocate the buffer based on the incorrect on-disk
+ * size.
+ */
+ if (h_size > XLOG_HEADER_CYCLE_SIZE &&
+ (rhead->h_version & cpu_to_be32(XLOG_VERSION_2))) {
+ hblks = DIV_ROUND_UP(h_size, XLOG_HEADER_CYCLE_SIZE);
+ if (hblks > 1) {
+ kvfree(hbp);
+ hbp = xlog_alloc_buffer(log, hblks);
+ }
}
} else {
ASSERT(log->l_sectBBsize == 1);
- hblks = 1;
hbp = xlog_alloc_buffer(log, 1);
h_size = XLOG_BIG_RECORD_BSIZE;
}
--
2.39.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 2/3] xfs: restrict the h_size fixup in xlog_do_recovery_pass
2024-04-29 7:01 fix h_size validation Christoph Hellwig
2024-04-29 7:01 ` [PATCH 1/3] xfs: fix log recovery buffer allocation for the legacy h_size fixup Christoph Hellwig
@ 2024-04-29 7:01 ` Christoph Hellwig
2024-04-29 12:18 ` Brian Foster
2024-04-29 15:55 ` Darrick J. Wong
2024-04-29 7:02 ` [PATCH 3/3] xfs: clean up buffer allocation " Christoph Hellwig
2 siblings, 2 replies; 14+ messages in thread
From: Christoph Hellwig @ 2024-04-29 7:01 UTC (permalink / raw)
To: Chandan Babu R
Cc: Darrick J. Wong, Brian Foster, Dave Chinner, Sam Sun, linux-xfs
The reflink and rmap features require a fixed xfsprogs, so don't allow
this fixup for them.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
fs/xfs/xfs_log_recover.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index bb8957927c3c2e..d73bec65f93b46 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -3040,10 +3040,14 @@ xlog_do_recovery_pass(
* Detect this condition here. Use lsunit for the buffer size as
* long as this looks like the mkfs case. Otherwise, return an
* error to avoid a buffer overrun.
+ *
+ * Reject the invalid size if the file system has new enough
+ * features that require a fixed mkfs.
*/
h_size = be32_to_cpu(rhead->h_size);
h_len = be32_to_cpu(rhead->h_len);
- if (h_len > h_size && h_len <= log->l_mp->m_logbsize &&
+ if (!xfs_has_reflink(log->l_mp) && xfs_has_reflink(log->l_mp) &&
+ h_len > h_size && h_len <= log->l_mp->m_logbsize &&
rhead->h_num_logops == cpu_to_be32(1)) {
xfs_warn(log->l_mp,
"invalid iclog size (%d bytes), using lsunit (%d bytes)",
--
2.39.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 3/3] xfs: clean up buffer allocation in xlog_do_recovery_pass
2024-04-29 7:01 fix h_size validation Christoph Hellwig
2024-04-29 7:01 ` [PATCH 1/3] xfs: fix log recovery buffer allocation for the legacy h_size fixup Christoph Hellwig
2024-04-29 7:01 ` [PATCH 2/3] xfs: restrict the h_size fixup in xlog_do_recovery_pass Christoph Hellwig
@ 2024-04-29 7:02 ` Christoph Hellwig
2024-04-29 12:18 ` Brian Foster
2024-04-29 15:56 ` Darrick J. Wong
2 siblings, 2 replies; 14+ messages in thread
From: Christoph Hellwig @ 2024-04-29 7:02 UTC (permalink / raw)
To: Chandan Babu R
Cc: Darrick J. Wong, Brian Foster, Dave Chinner, Sam Sun, linux-xfs
Merge the initial xlog_alloc_buffer calls, and pass the variable
designating the length that is initialized to 1 above instead of passing
the open coded 1 directly.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
fs/xfs/xfs_log_recover.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index d73bec65f93b46..d2e8b903945741 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -3010,6 +3010,10 @@ xlog_do_recovery_pass(
for (i = 0; i < XLOG_RHASH_SIZE; i++)
INIT_HLIST_HEAD(&rhash[i]);
+ hbp = xlog_alloc_buffer(log, hblks);
+ if (!hbp)
+ return -ENOMEM;
+
/*
* Read the header of the tail block and get the iclog buffer size from
* h_size. Use this to tell how many sectors make up the log header.
@@ -3020,10 +3024,6 @@ xlog_do_recovery_pass(
* iclog header and extract the header size from it. Get a
* new hbp that is the correct size.
*/
- hbp = xlog_alloc_buffer(log, 1);
- if (!hbp)
- return -ENOMEM;
-
error = xlog_bread(log, tail_blk, 1, hbp, &offset);
if (error)
goto bread_err1;
@@ -3071,16 +3071,15 @@ xlog_do_recovery_pass(
if (hblks > 1) {
kvfree(hbp);
hbp = xlog_alloc_buffer(log, hblks);
+ if (!hbp)
+ return -ENOMEM;
}
}
} else {
ASSERT(log->l_sectBBsize == 1);
- hbp = xlog_alloc_buffer(log, 1);
h_size = XLOG_BIG_RECORD_BSIZE;
}
- if (!hbp)
- return -ENOMEM;
dbp = xlog_alloc_buffer(log, BTOBB(h_size));
if (!dbp) {
kvfree(hbp);
--
2.39.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 1/3] xfs: fix log recovery buffer allocation for the legacy h_size fixup
2024-04-29 7:01 ` [PATCH 1/3] xfs: fix log recovery buffer allocation for the legacy h_size fixup Christoph Hellwig
@ 2024-04-29 12:18 ` Brian Foster
2024-04-29 17:13 ` Christoph Hellwig
2024-04-29 15:53 ` Darrick J. Wong
1 sibling, 1 reply; 14+ messages in thread
From: Brian Foster @ 2024-04-29 12:18 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Chandan Babu R, Darrick J. Wong, Dave Chinner, Sam Sun, linux-xfs
On Mon, Apr 29, 2024 at 09:01:58AM +0200, Christoph Hellwig wrote:
> Commit a70f9fe52daa ("xfs: detect and handle invalid iclog size set by
> mkfs") added a fixup for incorrect h_size values used for the initial
> umount record in old xfsprogs versions. But it is not using this fixed
> up value to size the log recovery buffer, which can lead to an out of
> bounds access when the incorrect h_size does not come from the old mkfs
> tool, but a fuzzer.
>
> Fix this by open coding xlog_logrec_hblks and taking the fixed h_size
> into account for this calculation.
>
> Fixes: a70f9fe52daa ("xfs: detect and handle invalid iclog size set by mkfs")
> Reported-by: Sam Sun <samsun1006219@gmail.com>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
The commit log/fixes tag are incorrect... xlog_logrec_hblks() didn't
exist at the time a70f9fe52daa was committed. I suspect this broke later
in commit 0c771b99d6c9 ("xfs: clean up calculation of LR header
blocks"), but please double check.
Otherwise the code changes look fine to me, so with the commit log fixed
up:
Reviewed-by: Brian Foster <bfoster@redhat.com>
> fs/xfs/xfs_log_recover.c | 20 ++++++++++++++------
> 1 file changed, 14 insertions(+), 6 deletions(-)
>
> diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
> index b445e8ce4a7d21..bb8957927c3c2e 100644
> --- a/fs/xfs/xfs_log_recover.c
> +++ b/fs/xfs/xfs_log_recover.c
> @@ -2999,7 +2999,7 @@ xlog_do_recovery_pass(
> int error = 0, h_size, h_len;
> int error2 = 0;
> int bblks, split_bblks;
> - int hblks, split_hblks, wrapped_hblks;
> + int hblks = 1, split_hblks, wrapped_hblks;
> int i;
> struct hlist_head rhash[XLOG_RHASH_SIZE];
> LIST_HEAD (buffer_list);
> @@ -3055,14 +3055,22 @@ xlog_do_recovery_pass(
> if (error)
> goto bread_err1;
>
> - hblks = xlog_logrec_hblks(log, rhead);
> - if (hblks != 1) {
> - kvfree(hbp);
> - hbp = xlog_alloc_buffer(log, hblks);
> + /*
> + * This open codes xlog_logrec_hblks so that we can reuse the
> + * fixed up h_size value calculated above. Without that we'd
> + * still allocate the buffer based on the incorrect on-disk
> + * size.
> + */
> + if (h_size > XLOG_HEADER_CYCLE_SIZE &&
> + (rhead->h_version & cpu_to_be32(XLOG_VERSION_2))) {
> + hblks = DIV_ROUND_UP(h_size, XLOG_HEADER_CYCLE_SIZE);
> + if (hblks > 1) {
> + kvfree(hbp);
> + hbp = xlog_alloc_buffer(log, hblks);
> + }
> }
> } else {
> ASSERT(log->l_sectBBsize == 1);
> - hblks = 1;
> hbp = xlog_alloc_buffer(log, 1);
> h_size = XLOG_BIG_RECORD_BSIZE;
> }
> --
> 2.39.2
>
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/3] xfs: restrict the h_size fixup in xlog_do_recovery_pass
2024-04-29 7:01 ` [PATCH 2/3] xfs: restrict the h_size fixup in xlog_do_recovery_pass Christoph Hellwig
@ 2024-04-29 12:18 ` Brian Foster
2024-04-29 17:15 ` Christoph Hellwig
2024-04-29 15:55 ` Darrick J. Wong
1 sibling, 1 reply; 14+ messages in thread
From: Brian Foster @ 2024-04-29 12:18 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Chandan Babu R, Darrick J. Wong, Dave Chinner, Sam Sun, linux-xfs
On Mon, Apr 29, 2024 at 09:01:59AM +0200, Christoph Hellwig wrote:
> The reflink and rmap features require a fixed xfsprogs, so don't allow
> this fixup for them.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
Seems reasonable..
> fs/xfs/xfs_log_recover.c | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
> index bb8957927c3c2e..d73bec65f93b46 100644
> --- a/fs/xfs/xfs_log_recover.c
> +++ b/fs/xfs/xfs_log_recover.c
> @@ -3040,10 +3040,14 @@ xlog_do_recovery_pass(
> * Detect this condition here. Use lsunit for the buffer size as
> * long as this looks like the mkfs case. Otherwise, return an
> * error to avoid a buffer overrun.
> + *
> + * Reject the invalid size if the file system has new enough
> + * features that require a fixed mkfs.
> */
> h_size = be32_to_cpu(rhead->h_size);
> h_len = be32_to_cpu(rhead->h_len);
> - if (h_len > h_size && h_len <= log->l_mp->m_logbsize &&
> + if (!xfs_has_reflink(log->l_mp) && xfs_has_reflink(log->l_mp) &&
> + h_len > h_size && h_len <= log->l_mp->m_logbsize &&
... but I'm going to assume this hasn't been tested. ;) Do you mean to
also check !rmapbt here?
Can you please also just double check that we still handle the original
mkfs problem correctly after these changes? I think that just means mkfs
from a sufficiently old xfsprogs using a larger log stripe unit, and
confirm the fs mounts (with a warning).
Brian
> rhead->h_num_logops == cpu_to_be32(1)) {
> xfs_warn(log->l_mp,
> "invalid iclog size (%d bytes), using lsunit (%d bytes)",
> --
> 2.39.2
>
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 3/3] xfs: clean up buffer allocation in xlog_do_recovery_pass
2024-04-29 7:02 ` [PATCH 3/3] xfs: clean up buffer allocation " Christoph Hellwig
@ 2024-04-29 12:18 ` Brian Foster
2024-04-29 15:56 ` Darrick J. Wong
1 sibling, 0 replies; 14+ messages in thread
From: Brian Foster @ 2024-04-29 12:18 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Chandan Babu R, Darrick J. Wong, Dave Chinner, Sam Sun, linux-xfs
On Mon, Apr 29, 2024 at 09:02:00AM +0200, Christoph Hellwig wrote:
> Merge the initial xlog_alloc_buffer calls, and pass the variable
> designating the length that is initialized to 1 above instead of passing
> the open coded 1 directly.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
Reviewed-by: Brian Foster <bfoster@redhat.com>
> fs/xfs/xfs_log_recover.c | 13 ++++++-------
> 1 file changed, 6 insertions(+), 7 deletions(-)
>
> diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
> index d73bec65f93b46..d2e8b903945741 100644
> --- a/fs/xfs/xfs_log_recover.c
> +++ b/fs/xfs/xfs_log_recover.c
> @@ -3010,6 +3010,10 @@ xlog_do_recovery_pass(
> for (i = 0; i < XLOG_RHASH_SIZE; i++)
> INIT_HLIST_HEAD(&rhash[i]);
>
> + hbp = xlog_alloc_buffer(log, hblks);
> + if (!hbp)
> + return -ENOMEM;
> +
> /*
> * Read the header of the tail block and get the iclog buffer size from
> * h_size. Use this to tell how many sectors make up the log header.
> @@ -3020,10 +3024,6 @@ xlog_do_recovery_pass(
> * iclog header and extract the header size from it. Get a
> * new hbp that is the correct size.
> */
> - hbp = xlog_alloc_buffer(log, 1);
> - if (!hbp)
> - return -ENOMEM;
> -
> error = xlog_bread(log, tail_blk, 1, hbp, &offset);
> if (error)
> goto bread_err1;
> @@ -3071,16 +3071,15 @@ xlog_do_recovery_pass(
> if (hblks > 1) {
> kvfree(hbp);
> hbp = xlog_alloc_buffer(log, hblks);
> + if (!hbp)
> + return -ENOMEM;
> }
> }
> } else {
> ASSERT(log->l_sectBBsize == 1);
> - hbp = xlog_alloc_buffer(log, 1);
> h_size = XLOG_BIG_RECORD_BSIZE;
> }
>
> - if (!hbp)
> - return -ENOMEM;
> dbp = xlog_alloc_buffer(log, BTOBB(h_size));
> if (!dbp) {
> kvfree(hbp);
> --
> 2.39.2
>
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/3] xfs: fix log recovery buffer allocation for the legacy h_size fixup
2024-04-29 7:01 ` [PATCH 1/3] xfs: fix log recovery buffer allocation for the legacy h_size fixup Christoph Hellwig
2024-04-29 12:18 ` Brian Foster
@ 2024-04-29 15:53 ` Darrick J. Wong
1 sibling, 0 replies; 14+ messages in thread
From: Darrick J. Wong @ 2024-04-29 15:53 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Chandan Babu R, Brian Foster, Dave Chinner, Sam Sun, linux-xfs
On Mon, Apr 29, 2024 at 09:01:58AM +0200, Christoph Hellwig wrote:
> Commit a70f9fe52daa ("xfs: detect and handle invalid iclog size set by
> mkfs") added a fixup for incorrect h_size values used for the initial
> umount record in old xfsprogs versions. But it is not using this fixed
> up value to size the log recovery buffer, which can lead to an out of
> bounds access when the incorrect h_size does not come from the old mkfs
> tool, but a fuzzer.
>
> Fix this by open coding xlog_logrec_hblks and taking the fixed h_size
> into account for this calculation.
>
> Fixes: a70f9fe52daa ("xfs: detect and handle invalid iclog size set by mkfs")
Modulo what bfoster said about the tagging,
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
--D
> Reported-by: Sam Sun <samsun1006219@gmail.com>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> fs/xfs/xfs_log_recover.c | 20 ++++++++++++++------
> 1 file changed, 14 insertions(+), 6 deletions(-)
>
> diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
> index b445e8ce4a7d21..bb8957927c3c2e 100644
> --- a/fs/xfs/xfs_log_recover.c
> +++ b/fs/xfs/xfs_log_recover.c
> @@ -2999,7 +2999,7 @@ xlog_do_recovery_pass(
> int error = 0, h_size, h_len;
> int error2 = 0;
> int bblks, split_bblks;
> - int hblks, split_hblks, wrapped_hblks;
> + int hblks = 1, split_hblks, wrapped_hblks;
> int i;
> struct hlist_head rhash[XLOG_RHASH_SIZE];
> LIST_HEAD (buffer_list);
> @@ -3055,14 +3055,22 @@ xlog_do_recovery_pass(
> if (error)
> goto bread_err1;
>
> - hblks = xlog_logrec_hblks(log, rhead);
> - if (hblks != 1) {
> - kvfree(hbp);
> - hbp = xlog_alloc_buffer(log, hblks);
> + /*
> + * This open codes xlog_logrec_hblks so that we can reuse the
> + * fixed up h_size value calculated above. Without that we'd
> + * still allocate the buffer based on the incorrect on-disk
> + * size.
> + */
> + if (h_size > XLOG_HEADER_CYCLE_SIZE &&
> + (rhead->h_version & cpu_to_be32(XLOG_VERSION_2))) {
> + hblks = DIV_ROUND_UP(h_size, XLOG_HEADER_CYCLE_SIZE);
> + if (hblks > 1) {
> + kvfree(hbp);
> + hbp = xlog_alloc_buffer(log, hblks);
> + }
> }
> } else {
> ASSERT(log->l_sectBBsize == 1);
> - hblks = 1;
> hbp = xlog_alloc_buffer(log, 1);
> h_size = XLOG_BIG_RECORD_BSIZE;
> }
> --
> 2.39.2
>
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/3] xfs: restrict the h_size fixup in xlog_do_recovery_pass
2024-04-29 7:01 ` [PATCH 2/3] xfs: restrict the h_size fixup in xlog_do_recovery_pass Christoph Hellwig
2024-04-29 12:18 ` Brian Foster
@ 2024-04-29 15:55 ` Darrick J. Wong
1 sibling, 0 replies; 14+ messages in thread
From: Darrick J. Wong @ 2024-04-29 15:55 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Chandan Babu R, Brian Foster, Dave Chinner, Sam Sun, linux-xfs
On Mon, Apr 29, 2024 at 09:01:59AM +0200, Christoph Hellwig wrote:
> The reflink and rmap features require a fixed xfsprogs, so don't allow
> this fixup for them.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> fs/xfs/xfs_log_recover.c | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
> index bb8957927c3c2e..d73bec65f93b46 100644
> --- a/fs/xfs/xfs_log_recover.c
> +++ b/fs/xfs/xfs_log_recover.c
> @@ -3040,10 +3040,14 @@ xlog_do_recovery_pass(
> * Detect this condition here. Use lsunit for the buffer size as
> * long as this looks like the mkfs case. Otherwise, return an
> * error to avoid a buffer overrun.
> + *
> + * Reject the invalid size if the file system has new enough
> + * features that require a fixed mkfs.
> */
> h_size = be32_to_cpu(rhead->h_size);
> h_len = be32_to_cpu(rhead->h_len);
> - if (h_len > h_size && h_len <= log->l_mp->m_logbsize &&
> + if (!xfs_has_reflink(log->l_mp) && xfs_has_reflink(log->l_mp) &&
> + h_len > h_size && h_len <= log->l_mp->m_logbsize &&
> rhead->h_num_logops == cpu_to_be32(1)) {
Same comment about do you want to test for rmap and reflink here?
I also wonder if this multiline predicate should turn into a static
inline helper. I nearly wrote you one, but then I realize that I don't
remember enough about the xfsprogs problem to know if the problem was
limited to mkfs, or if xfs_repair zeroing the log would also write out a
bad h_size?
--D
> xfs_warn(log->l_mp,
> "invalid iclog size (%d bytes), using lsunit (%d bytes)",
> --
> 2.39.2
>
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 3/3] xfs: clean up buffer allocation in xlog_do_recovery_pass
2024-04-29 7:02 ` [PATCH 3/3] xfs: clean up buffer allocation " Christoph Hellwig
2024-04-29 12:18 ` Brian Foster
@ 2024-04-29 15:56 ` Darrick J. Wong
1 sibling, 0 replies; 14+ messages in thread
From: Darrick J. Wong @ 2024-04-29 15:56 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Chandan Babu R, Brian Foster, Dave Chinner, Sam Sun, linux-xfs
On Mon, Apr 29, 2024 at 09:02:00AM +0200, Christoph Hellwig wrote:
> Merge the initial xlog_alloc_buffer calls, and pass the variable
> designating the length that is initialized to 1 above instead of passing
> the open coded 1 directly.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Nice cleanup,
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
--D
> ---
> fs/xfs/xfs_log_recover.c | 13 ++++++-------
> 1 file changed, 6 insertions(+), 7 deletions(-)
>
> diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
> index d73bec65f93b46..d2e8b903945741 100644
> --- a/fs/xfs/xfs_log_recover.c
> +++ b/fs/xfs/xfs_log_recover.c
> @@ -3010,6 +3010,10 @@ xlog_do_recovery_pass(
> for (i = 0; i < XLOG_RHASH_SIZE; i++)
> INIT_HLIST_HEAD(&rhash[i]);
>
> + hbp = xlog_alloc_buffer(log, hblks);
> + if (!hbp)
> + return -ENOMEM;
> +
> /*
> * Read the header of the tail block and get the iclog buffer size from
> * h_size. Use this to tell how many sectors make up the log header.
> @@ -3020,10 +3024,6 @@ xlog_do_recovery_pass(
> * iclog header and extract the header size from it. Get a
> * new hbp that is the correct size.
> */
> - hbp = xlog_alloc_buffer(log, 1);
> - if (!hbp)
> - return -ENOMEM;
> -
> error = xlog_bread(log, tail_blk, 1, hbp, &offset);
> if (error)
> goto bread_err1;
> @@ -3071,16 +3071,15 @@ xlog_do_recovery_pass(
> if (hblks > 1) {
> kvfree(hbp);
> hbp = xlog_alloc_buffer(log, hblks);
> + if (!hbp)
> + return -ENOMEM;
> }
> }
> } else {
> ASSERT(log->l_sectBBsize == 1);
> - hbp = xlog_alloc_buffer(log, 1);
> h_size = XLOG_BIG_RECORD_BSIZE;
> }
>
> - if (!hbp)
> - return -ENOMEM;
> dbp = xlog_alloc_buffer(log, BTOBB(h_size));
> if (!dbp) {
> kvfree(hbp);
> --
> 2.39.2
>
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/3] xfs: fix log recovery buffer allocation for the legacy h_size fixup
2024-04-29 12:18 ` Brian Foster
@ 2024-04-29 17:13 ` Christoph Hellwig
0 siblings, 0 replies; 14+ messages in thread
From: Christoph Hellwig @ 2024-04-29 17:13 UTC (permalink / raw)
To: Brian Foster
Cc: Christoph Hellwig, Chandan Babu R, Darrick J. Wong, Dave Chinner,
Sam Sun, linux-xfs
On Mon, Apr 29, 2024 at 08:18:23AM -0400, Brian Foster wrote:
> > Reported-by: Sam Sun <samsun1006219@gmail.com>
> > Signed-off-by: Christoph Hellwig <hch@lst.de>
> > ---
>
> The commit log/fixes tag are incorrect... xlog_logrec_hblks() didn't
> exist at the time a70f9fe52daa was committed. I suspect this broke later
> in commit 0c771b99d6c9 ("xfs: clean up calculation of LR header
> blocks"), but please double check.
Oh, indeed. My (git-)blame was a little too quick.
Looking at that later commit: can xfs_sb_version_haslogv2 and the
per-xlog_rec_header XLOG_VERSION_2 ever disagree? Do we need to check
for that?
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/3] xfs: restrict the h_size fixup in xlog_do_recovery_pass
2024-04-29 12:18 ` Brian Foster
@ 2024-04-29 17:15 ` Christoph Hellwig
2024-04-30 10:59 ` Brian Foster
0 siblings, 1 reply; 14+ messages in thread
From: Christoph Hellwig @ 2024-04-29 17:15 UTC (permalink / raw)
To: Brian Foster
Cc: Christoph Hellwig, Chandan Babu R, Darrick J. Wong, Dave Chinner,
Sam Sun, linux-xfs
On Mon, Apr 29, 2024 at 08:18:44AM -0400, Brian Foster wrote:
> > - if (h_len > h_size && h_len <= log->l_mp->m_logbsize &&
> > + if (!xfs_has_reflink(log->l_mp) && xfs_has_reflink(log->l_mp) &&
> > + h_len > h_size && h_len <= log->l_mp->m_logbsize &&
>
> ... but I'm going to assume this hasn't been tested. ;) Do you mean to
> also check !rmapbt here?
Heh. Well, it has been tested in that we don't do the fixup for the
reproducer fixed by the previous patch and in that xfstests still passes.
I guess nothing in there hits the old mkfs fixup, which isn't surprising.
> Can you please also just double check that we still handle the original
> mkfs problem correctly after these changes? I think that just means mkfs
> from a sufficiently old xfsprogs using a larger log stripe unit, and
> confirm the fs mounts (with a warning).
Yeah. Is there any way to commit a fs image to xfstests so that we
actually regularly test for it?
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/3] xfs: restrict the h_size fixup in xlog_do_recovery_pass
2024-04-29 17:15 ` Christoph Hellwig
@ 2024-04-30 10:59 ` Brian Foster
2024-05-10 12:34 ` Brian Foster
0 siblings, 1 reply; 14+ messages in thread
From: Brian Foster @ 2024-04-30 10:59 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Chandan Babu R, Darrick J. Wong, Dave Chinner, Sam Sun, linux-xfs
On Mon, Apr 29, 2024 at 07:15:52PM +0200, Christoph Hellwig wrote:
> On Mon, Apr 29, 2024 at 08:18:44AM -0400, Brian Foster wrote:
> > > - if (h_len > h_size && h_len <= log->l_mp->m_logbsize &&
> > > + if (!xfs_has_reflink(log->l_mp) && xfs_has_reflink(log->l_mp) &&
> > > + h_len > h_size && h_len <= log->l_mp->m_logbsize &&
> >
> > ... but I'm going to assume this hasn't been tested. ;) Do you mean to
> > also check !rmapbt here?
>
> Heh. Well, it has been tested in that we don't do the fixup for the
> reproducer fixed by the previous patch and in that xfstests still passes.
> I guess nothing in there hits the old mkfs fixup, which isn't surprising.
>
Yeah.. (sorry, just teasing about the testing.. ;).
> > Can you please also just double check that we still handle the original
> > mkfs problem correctly after these changes? I think that just means mkfs
> > from a sufficiently old xfsprogs using a larger log stripe unit, and
> > confirm the fs mounts (with a warning).
>
> Yeah. Is there any way to commit a fs image to xfstests so that we
> actually regularly test for it?
>
Not sure.. ideally we could fuzz the log record header somehow or
another to test for these various scenarios, since we clearly broke this
once already.
I don't quite recall if I looked into that at the time of the original
workaround. To Darrick's point, I wonder if there would be some use to
an expert logformat command or something that allowed for some bonkers
parameters (assuming something like that doesn't exist already).
I'm out on PTO for (at least) today, but I can take a closer look at
that once I'm back and caught up...
Brian
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/3] xfs: restrict the h_size fixup in xlog_do_recovery_pass
2024-04-30 10:59 ` Brian Foster
@ 2024-05-10 12:34 ` Brian Foster
0 siblings, 0 replies; 14+ messages in thread
From: Brian Foster @ 2024-05-10 12:34 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Chandan Babu R, Darrick J. Wong, Dave Chinner, Sam Sun, linux-xfs
On Tue, Apr 30, 2024 at 06:59:47AM -0400, Brian Foster wrote:
> On Mon, Apr 29, 2024 at 07:15:52PM +0200, Christoph Hellwig wrote:
> > On Mon, Apr 29, 2024 at 08:18:44AM -0400, Brian Foster wrote:
> > > > - if (h_len > h_size && h_len <= log->l_mp->m_logbsize &&
> > > > + if (!xfs_has_reflink(log->l_mp) && xfs_has_reflink(log->l_mp) &&
> > > > + h_len > h_size && h_len <= log->l_mp->m_logbsize &&
> > >
> > > ... but I'm going to assume this hasn't been tested. ;) Do you mean to
> > > also check !rmapbt here?
> >
> > Heh. Well, it has been tested in that we don't do the fixup for the
> > reproducer fixed by the previous patch and in that xfstests still passes.
> > I guess nothing in there hits the old mkfs fixup, which isn't surprising.
> >
>
> Yeah.. (sorry, just teasing about the testing.. ;).
>
> > > Can you please also just double check that we still handle the original
> > > mkfs problem correctly after these changes? I think that just means mkfs
> > > from a sufficiently old xfsprogs using a larger log stripe unit, and
> > > confirm the fs mounts (with a warning).
> >
> > Yeah. Is there any way to commit a fs image to xfstests so that we
> > actually regularly test for it?
> >
>
> Not sure.. ideally we could fuzz the log record header somehow or
> another to test for these various scenarios, since we clearly broke this
> once already.
>
> I don't quite recall if I looked into that at the time of the original
> workaround. To Darrick's point, I wonder if there would be some use to
> an expert logformat command or something that allowed for some bonkers
> parameters (assuming something like that doesn't exist already).
>
> I'm out on PTO for (at least) today, but I can take a closer look at
> that once I'm back and caught up...
>
I've had a chance to poke at this a bit and so far I don't think it's as
straightforward as I'd hoped. The logformat command already exists,
which makes it pretty easy to malformat a log record, but the recovery
code only runs into this path on a dirty log. I suspect the original
issue that prompted this logic was something like a crash-recovery test
leading to log record trimming (i.e. simulated torn log writes) and then
happening onto previously mkfs-formatted log records that way, but that
is a guess at this point.
I did play around a bit with fuzzing h_size for those sorts of tests
(i.e. xfs/141), but that ran into other issues. I went back to using
xfsprogs v4.3 or so and that eventually also produces an unmountable
filesystem with a similar error (even with the h_size fix patch). It
fails to locate the head/tail, which is obviously necessary in order to
process the log and perform record validation, so I'm wondering if
something else changed on the kernel side to further gate this scenario.
Of course it's also possible I'm looking at things wrong and this is
just orthogonal to the original problem.
But given all of that, I am a little skeptical on the value of retaining
this logic at all. Does whatever test case that recently uncovered the
h_size problem leave a mountable filesystem, or does it just work around
bad behavior to provide a more graceful failure condition?
Brian
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2024-05-10 12:34 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-04-29 7:01 fix h_size validation Christoph Hellwig
2024-04-29 7:01 ` [PATCH 1/3] xfs: fix log recovery buffer allocation for the legacy h_size fixup Christoph Hellwig
2024-04-29 12:18 ` Brian Foster
2024-04-29 17:13 ` Christoph Hellwig
2024-04-29 15:53 ` Darrick J. Wong
2024-04-29 7:01 ` [PATCH 2/3] xfs: restrict the h_size fixup in xlog_do_recovery_pass Christoph Hellwig
2024-04-29 12:18 ` Brian Foster
2024-04-29 17:15 ` Christoph Hellwig
2024-04-30 10:59 ` Brian Foster
2024-05-10 12:34 ` Brian Foster
2024-04-29 15:55 ` Darrick J. Wong
2024-04-29 7:02 ` [PATCH 3/3] xfs: clean up buffer allocation " Christoph Hellwig
2024-04-29 12:18 ` Brian Foster
2024-04-29 15:56 ` Darrick J. Wong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).