-
Notifications
You must be signed in to change notification settings - Fork 119
Open
Description
Issue
In functions nova_seq_delete_snapshot
and nova_seq_test_perf
, NOVA directly sscanf
from the user's buffer, which is unsafe and could cause Segment Fault sometimes. Instead, in the function nova_seq_gc
, NOVA copies the buffer from the user space to kernel space before sscanf
the content.
Lines 317 to 329 in 976a4d1
ssize_t nova_seq_delete_snapshot(struct file *filp, const char __user *buf, | |
size_t len, loff_t *ppos) | |
{ | |
struct address_space *mapping = filp->f_mapping; | |
struct inode *inode = mapping->host; | |
struct super_block *sb = PDE_DATA(inode); | |
u64 epoch_id; | |
sscanf(buf, "%llu", &epoch_id); | |
nova_delete_snapshot(sb, epoch_id); | |
return len; | |
} |
Lines 377 to 392 in 976a4d1
ssize_t nova_seq_test_perf(struct file *filp, const char __user *buf, | |
size_t len, loff_t *ppos) | |
{ | |
struct address_space *mapping = filp->f_mapping; | |
struct inode *inode = mapping->host; | |
struct super_block *sb = PDE_DATA(inode); | |
size_t size; | |
unsigned int func_id, poolmb, disks; | |
if (sscanf(buf, "%u:%u:%zu:%u", &func_id, &poolmb, &size, &disks) == 4) | |
nova_test_perf(sb, func_id, poolmb, size, disks); | |
else | |
nova_warn("Couldn't parse test_perf request: %s", buf); | |
return len; | |
} |
Lines 419 to 448 in 976a4d1
ssize_t nova_seq_gc(struct file *filp, const char __user *buf, | |
size_t len, loff_t *ppos) | |
{ | |
u64 target_inode_number; | |
struct address_space *mapping = filp->f_mapping; | |
struct inode *inode = mapping->host; | |
struct super_block *sb = PDE_DATA(inode); | |
struct inode *target_inode; | |
struct nova_inode *target_pi; | |
struct nova_inode_info *target_sih; | |
char *_buf; | |
int retval = len; | |
_buf = kmalloc(len, GFP_KERNEL); | |
if (_buf == NULL) { | |
retval = -ENOMEM; | |
nova_dbg("%s: kmalloc failed\n", __func__); | |
goto out; | |
} | |
if (copy_from_user(_buf, buf, len)) { | |
retval = -EFAULT; | |
goto out; | |
} | |
_buf[len] = 0; | |
sscanf(_buf, "%llu", &target_inode_number); | |
nova_info("%s: target_inode_number=%llu.", __func__, | |
target_inode_number); |
Fix
copy_from_user
before sscanf
.
Metadata
Metadata
Assignees
Labels
No labels