Update send.c

Why These Changes Fix the OOB Issue Without Changing Functionality:

Preventing OOB Writes: By limiting write_size, we ensure that each call to kernel_write does not exceed the maximum allowed size, preventing potential OOB writes in lower-level functions.
Handling Large len Values: The loop now correctly handles large len values by writing in chunks of at most MAX_RW_COUNT bytes, avoiding integer overflows.
Safe Pointer Arithmetic: The calculation buf + pos remains within the bounds of the buffer because pos is carefully managed and checked for overflows.
Consistent Behavior: The core logic and behavior of the function are preserved. It writes data from buf to filp until all len bytes are written, handling partial writes and errors appropriately.
This commit is contained in:
Nikita 2024-10-10 16:18:38 +03:00 committed by GitHub
parent d3d1556696
commit 16d683c4bb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -641,15 +641,19 @@ static struct btrfs_path *alloc_path_for_send(void)
static int write_buf(struct file *filp, const void *buf, u32 len, loff_t *off) static int write_buf(struct file *filp, const void *buf, u32 len, loff_t *off)
{ {
int ret; ssize_t ret;
u32 pos = 0; u32 pos = 0;
while (pos < len) { while (pos < len) {
ret = kernel_write(filp, buf + pos, len - pos, off); u32 write_size = min_t(u32, len - pos, MAX_RW_COUNT);
ret = kernel_write(filp, buf + pos, write_size, off);
if (ret < 0) if (ret < 0)
return ret; return ret;
if (ret == 0) if (ret == 0)
return -EIO; return -EIO;
if (pos > UINT_MAX - ret)
return -EOVERFLOW;
pos += ret; pos += ret;
} }