Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unsafe read of user buf in procfs #149

Open
iaoing opened this issue Jan 1, 2024 · 0 comments
Open

Unsafe read of user buf in procfs #149

iaoing opened this issue Jan 1, 2024 · 0 comments

Comments

@iaoing
Copy link
Contributor

iaoing commented Jan 1, 2024

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.

linux-nova/fs/nova/sysfs.c

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;
}

linux-nova/fs/nova/sysfs.c

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;
}

linux-nova/fs/nova/sysfs.c

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant