mirror of
https://github.com/armbian/build
synced 2025-09-24 19:47:06 +07:00
uboot-2024.01: fix boot from btrfs fs
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Alex Shumsky <alexthreed@gmail.com>
|
||||
Date: Mon, 14 Jun 2024 19:01:48 +0000
|
||||
Subject: fs/btrfs: fix out of bounds write
|
||||
|
||||
Signed-off-by: Alex Shumsky <alexthreed@gmail.com>
|
||||
---
|
||||
fs/btrfs/inode.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
|
||||
index 4691612eda..b51f578b49 100644
|
||||
--- a/fs/btrfs/inode.c
|
||||
+++ b/fs/btrfs/inode.c
|
||||
@@ -638,11 +638,11 @@ static int read_and_truncate_page(struct btrfs_path *path,
|
||||
return -ENOMEM;
|
||||
|
||||
extent_type = btrfs_file_extent_type(leaf, fi);
|
||||
if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
|
||||
ret = btrfs_read_extent_inline(path, fi, buf);
|
||||
- memcpy(dest, buf + page_off, min(page_len, ret));
|
||||
+ memcpy(dest, buf + page_off, min(min(page_len, ret), len));
|
||||
free(buf);
|
||||
return len;
|
||||
}
|
||||
|
||||
ret = btrfs_read_extent_reg(path, fi,
|
||||
@@ -650,11 +650,11 @@ static int read_and_truncate_page(struct btrfs_path *path,
|
||||
fs_info->sectorsize, buf);
|
||||
if (ret < 0) {
|
||||
free(buf);
|
||||
return ret;
|
||||
}
|
||||
- memcpy(dest, buf + page_off, page_len);
|
||||
+ memcpy(dest, buf + page_off, min(page_len, len));
|
||||
free(buf);
|
||||
return len;
|
||||
}
|
||||
|
||||
int btrfs_file_read(struct btrfs_root *root, u64 ino, u64 file_offset, u64 len,
|
||||
--
|
||||
Created with Armbian build tools https://github.com/armbian/build
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
From 6d6ea52b629c384fb8605678b9003d2a077f9148 Mon Sep 17 00:00:00 2001
|
||||
From: Sam Edwards <cfsworks@gmail.com>
|
||||
Date: Sat, 11 Nov 2023 08:19:04 -0700
|
||||
Subject: [PATCH] fs: btrfs: fix reading when length specified
|
||||
|
||||
The btrfs read function limits the read length to ensure that it
|
||||
and the read offset do not together exceed the size of the file.
|
||||
However, this size was only being queried if the read length was
|
||||
passed a value of zero (meaning "whole file"), and the size is
|
||||
defaulted to 0 otherwise. This means the clamp will just zero out
|
||||
the length if one is specified, preventing reading of the file.
|
||||
|
||||
Fix this by checking the file size unconditionally, and unifying
|
||||
the default length and clamping logic as a single range check instead.
|
||||
|
||||
This bug was discovered when trying to boot Linux with initrd= via
|
||||
'bootefi' from a btrfs partition. The EFI stub entered an infinite
|
||||
loop of zero-length reads while trying to read the initrd, and the
|
||||
boot process stalled indefinitely.
|
||||
|
||||
Signed-off-by: Sam Edwards <CFSworks@gmail.com>
|
||||
Reviewed-by: Qu Wenruo <wqu@suse.com>
|
||||
---
|
||||
fs/btrfs/btrfs.c | 15 ++++++---------
|
||||
1 file changed, 6 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/fs/btrfs/btrfs.c b/fs/btrfs/btrfs.c
|
||||
index 4cdbbbe3d066..1149a3b20077 100644
|
||||
--- a/fs/btrfs/btrfs.c
|
||||
+++ b/fs/btrfs/btrfs.c
|
||||
@@ -228,7 +228,7 @@ int btrfs_read(const char *file, void *buf, loff_t offset, loff_t len,
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = current_fs_info;
|
||||
struct btrfs_root *root;
|
||||
- loff_t real_size = 0;
|
||||
+ loff_t real_size;
|
||||
u64 ino;
|
||||
u8 type;
|
||||
int ret;
|
||||
@@ -246,16 +246,13 @@ int btrfs_read(const char *file, void *buf, loff_t offset, loff_t len,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- if (!len) {
|
||||
- ret = btrfs_size(file, &real_size);
|
||||
- if (ret < 0) {
|
||||
- error("Failed to get inode size: %s", file);
|
||||
- return ret;
|
||||
- }
|
||||
- len = real_size;
|
||||
+ ret = btrfs_size(file, &real_size);
|
||||
+ if (ret < 0) {
|
||||
+ error("Failed to get inode size: %s", file);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
- if (len > real_size - offset)
|
||||
+ if (!len || len > real_size - offset)
|
||||
len = real_size - offset;
|
||||
|
||||
ret = btrfs_file_read(root, ino, offset, len, buf);
|
||||
Reference in New Issue
Block a user