Skip to content

Commit 5e39468

Browse files
committed
btrfs: add separate bounds checker for set/get helpers
The bounds checking is now done in map_private_extent_buffer but that will be removed in following patches and some sanity checks should still be done. There are two separate checks to see the kind of out of bounds access: partial (start offset is in the buffer) or complete (both start and end are out). Reviewed-by: Johannes Thumshirn <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 870b388 commit 5e39468

File tree

1 file changed

+25
-0
lines changed

1 file changed

+25
-0
lines changed

fs/btrfs/struct-funcs.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,27 @@ static inline void put_unaligned_le8(u8 val, void *p)
1717
*(u8 *)p = val;
1818
}
1919

20+
static bool check_setget_bounds(const struct extent_buffer *eb,
21+
const void *ptr, unsigned off, int size)
22+
{
23+
const unsigned long member_offset = (unsigned long)ptr + off;
24+
25+
if (member_offset > eb->len) {
26+
btrfs_warn(eb->fs_info,
27+
"bad eb member start: ptr 0x%lx start %llu member offset %lu size %d",
28+
(unsigned long)ptr, eb->start, member_offset, size);
29+
return false;
30+
}
31+
if (member_offset + size > eb->len) {
32+
btrfs_warn(eb->fs_info,
33+
"bad eb member end: ptr 0x%lx start %llu member offset %lu size %d",
34+
(unsigned long)ptr, eb->start, member_offset, size);
35+
return false;
36+
}
37+
38+
return true;
39+
}
40+
2041
/*
2142
* this is some deeply nasty code.
2243
*
@@ -53,6 +74,7 @@ u##bits btrfs_get_token_##bits(struct btrfs_map_token *token, \
5374
\
5475
ASSERT(token); \
5576
ASSERT(token->kaddr); \
77+
ASSERT(check_setget_bounds(token->eb, ptr, off, size)); \
5678
if (token->offset <= offset && \
5779
(token->offset + PAGE_SIZE >= offset + size)) { \
5880
kaddr = token->kaddr; \
@@ -87,6 +109,7 @@ u##bits btrfs_get_##bits(const struct extent_buffer *eb, \
87109
int size = sizeof(u##bits); \
88110
u##bits res; \
89111
\
112+
ASSERT(check_setget_bounds(eb, ptr, off, size)); \
90113
err = map_private_extent_buffer(eb, offset, size, \
91114
&kaddr, &map_start, &map_len); \
92115
if (err) { \
@@ -114,6 +137,7 @@ void btrfs_set_token_##bits(struct btrfs_map_token *token, \
114137
\
115138
ASSERT(token); \
116139
ASSERT(token->kaddr); \
140+
ASSERT(check_setget_bounds(token->eb, ptr, off, size)); \
117141
if (token->offset <= offset && \
118142
(token->offset + PAGE_SIZE >= offset + size)) { \
119143
kaddr = token->kaddr; \
@@ -147,6 +171,7 @@ void btrfs_set_##bits(struct extent_buffer *eb, void *ptr, \
147171
unsigned long map_len; \
148172
int size = sizeof(u##bits); \
149173
\
174+
ASSERT(check_setget_bounds(eb, ptr, off, size)); \
150175
err = map_private_extent_buffer(eb, offset, size, \
151176
&kaddr, &map_start, &map_len); \
152177
if (err) { \

0 commit comments

Comments
 (0)