Skip to content

Commit

Permalink
btrfs-util: check current offset before read
Browse files Browse the repository at this point in the history
Fixes #32936.
  • Loading branch information
yuwata authored and bluca committed May 20, 2024
1 parent 1d640a0 commit 125cca1
Showing 1 changed file with 37 additions and 12 deletions.
49 changes: 37 additions & 12 deletions src/shared/btrfs-util.c
Original file line number Diff line number Diff line change
Expand Up @@ -262,24 +262,49 @@ static int btrfs_ioctl_search_args_compare(const struct btrfs_ioctl_search_args
}

typedef struct BtrfsForeachIterator {
const void *p;
size_t i;
const struct btrfs_ioctl_search_args *args;
size_t offset;
unsigned index;
struct btrfs_ioctl_search_header *header;
const void **body;
} BtrfsForeachIterator;

static int btrfs_iterate(BtrfsForeachIterator *i) {
assert(i);
assert(i->args);
assert(i->header);
assert(i->body);

if (i->index >= i->args->key.nr_items)
return 0; /* end */

assert_cc(BTRFS_SEARCH_ARGS_BUFSIZE >= sizeof(struct btrfs_ioctl_search_header));
if (i->offset > BTRFS_SEARCH_ARGS_BUFSIZE - sizeof(struct btrfs_ioctl_search_header))
return -EBADMSG;

struct btrfs_ioctl_search_header h;
memcpy(&h, (const uint8_t*) i->args->buf + i->offset, sizeof(struct btrfs_ioctl_search_header));

if (i->offset > BTRFS_SEARCH_ARGS_BUFSIZE - sizeof(struct btrfs_ioctl_search_header) - h.len)
return -EBADMSG;

*i->body = (const uint8_t*) i->args->buf + i->offset + sizeof(struct btrfs_ioctl_search_header);
*i->header = h;
i->offset += sizeof(struct btrfs_ioctl_search_header) + h.len;
i->index++;

return 1;
}

/* Iterates through a series of struct btrfs_file_extent_item elements. They are unfortunately not aligned,
* hence we copy out the header from them */
#define FOREACH_BTRFS_IOCTL_SEARCH_HEADER(sh, body, args) \
#define FOREACH_BTRFS_IOCTL_SEARCH_HEADER(_sh, _body, _args) \
for (BtrfsForeachIterator iterator = { \
.p = ({ \
memcpy(&(sh), (args).buf, sizeof(struct btrfs_ioctl_search_header)); \
(body) = (const void*) ((const uint8_t*) (args).buf + sizeof(struct btrfs_ioctl_search_header)); \
(args).buf; \
}), \
.args = &(_args), \
.header = &(_sh), \
.body = &(_body), \
}; \
iterator.i < (args).key.nr_items; \
iterator.i++, \
memcpy(&(sh), iterator.p = (const uint8_t*) iterator.p + sizeof(struct btrfs_ioctl_search_header) + (sh).len, sizeof(struct btrfs_ioctl_search_header)), \
(body) = (const void*) ((const uint8_t*) iterator.p + sizeof(struct btrfs_ioctl_search_header)))
btrfs_iterate(&iterator) > 0; )

int btrfs_subvol_get_info_fd(int fd, uint64_t subvol_id, BtrfsSubvolInfo *ret) {
struct btrfs_ioctl_search_args args = {
Expand Down

0 comments on commit 125cca1

Please sign in to comment.