Btrfs: check range early in map_private_extent_buffer
Check range early to avoid further check/compute in case of range error.
--- fs/btrfs/extent_io.c | 16 ++++++++-------- 1 files changed, 8 insertions(+), 8 deletions(-)
fs/btrfs/extent_io.c +8 -8
@@ -4643,6 +4643,14 @@ int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start,unsigned long end_i = (start_offset + start + min_len -1 ) >>PAGE_CACHE_SHIFT ; +if (start + min_len > eb->len) { +printk (KERN_ERR "btrfs bad mapping eb start %llu len %lu, " +"wanted %lu %lu\n" , (unsigned long long )eb->start, + eb->len, start, min_len); +WARN_ON (1 ); +return -EINVAL ; + } +if (i != end_i)return -EINVAL ;
@@ -4654,14 +4662,6 @@ int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start, *map_start = ((u64 )i <<PAGE_CACHE_SHIFT ) - start_offset; } -if (start + min_len > eb->len) { -printk (KERN_ERR "btrfs bad mapping eb start %llu len %lu, " -"wanted %lu %lu\n" , (unsigned long long )eb->start, - eb->len, start, min_len); -WARN_ON (1 ); -return -EINVAL ; - } - p =extent_buffer_page (eb, i); kaddr =page_address (p); *map = kaddr + offset;
Signature · 1 line
1.7.1
Quoted 16 lines · Wang Sheng-Hui
Check range early to avoid further check/compute in case of range error.
Signed-off-by Wang Sheng-Hui <[email protected]>--- fs/btrfs/extent_io.c | 16 ++++++++-------- 1 files changed, 8 insertions(+), 8 deletions(-)fs/btrfs/extent_io.c +0
-0@@ -4643,6 +4643,14 @@ int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start,unsigned long end_i = (start_offset + start + min_len -1 ) >>PAGE_CACHE_SHIFT ;
fs/btrfs/extent_io.c int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start, · line 4655
Quoted 10 lines
fs/btrfs/extent_io.c +8
-0+if (start + min_len > eb->len) { +printk (KERN_ERR "btrfs bad mapping eb start %llu len %lu, " +"wanted %lu %lu\n" , (unsigned long long )eb->start, + eb->len, start, min_len); +WARN_ON (1 ); +return -EINVAL ; + } +if (i != end_i)return -EINVAL ;
4665 unsigned long i = (start_offset + start) >> PAGE_CACHE_SHIFT;
4666 unsigned long end_i = (start_offset + start + min_len - 1) >>
4667 PAGE_CACHE_SHIFT;
so the check above effectively verifies that
min_len - 1 < PAGE_CACHE_SIZE
AND
is within the same page
The other check
if (start + min_len > eb->len) {looks if the requested data do not lie out of the bounds of the extent buffer, where min_len is filled with sizeof(something).
So, both the checks look for corrupted metadata, I don't see the need to swap them.
david
Quoted 40 lines · David Sterba
Quoted 16 lines · Wang Sheng-Hui
Check range early to avoid further check/compute in case of range error.
Signed-off-by Wang Sheng-Hui <[email protected]>--- fs/btrfs/extent_io.c | 16 ++++++++-------- 1 files changed, 8 insertions(+), 8 deletions(-)fs/btrfs/extent_io.c +0
-0@@ -4643,6 +4643,14 @@ int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start,unsigned long end_i = (start_offset + start + min_len -1 ) >>PAGE_CACHE_SHIFT ;fs/btrfs/extent_io.c int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start, · line 4655
Quoted 10 lines
fs/btrfs/extent_io.c +8
-0+if (start + min_len > eb->len) { +printk (KERN_ERR "btrfs bad mapping eb start %llu len %lu, " +"wanted %lu %lu\n" , (unsigned long long )eb->start, + eb->len, start, min_len); +WARN_ON (1 ); +return -EINVAL ; + } +if (i != end_i)return -EINVAL ;4665 unsigned long i = (
start_offset+ start) >>PAGE_CACHE_SHIFT;
4666 unsigned longend_i= (start_offset+ start +min_len- 1) >>
4667PAGE_CACHE_SHIFT;so the check above effectively verifies that
min_len- 1 <PAGE_CACHE_SIZE
AND
is within the same pageThe other check
Quoted 7 lines
if (start + min_len > eb->len) {looks if the requested data do not lie out of the bounds of the extent buffer, where
min_lenis filled with sizeof(something).So, both the checks look for corrupted metadata, I don't see the need to swap them.
Reread the code and it really does the check.
Got it. Thanks for your explanation.
Quoted 2 lines
david