aboutsummaryrefslogtreecommitdiff
path: root/kernel/features
diff options
context:
space:
mode:
authorMarvin Borner2021-04-25 16:31:40 +0200
committerMarvin Borner2021-04-25 16:31:40 +0200
commit0fe14a1ff936c38ab9aa7f85219d0c155d276823 (patch)
treeb3e4b1f9000819a564656fabf0496f871c1e6eba /kernel/features
parentf2b4acb2fe6a366288b19843e0d2678b8590bdf4 (diff)
Added range-based memory validator
Diffstat (limited to 'kernel/features')
-rw-r--r--kernel/features/fs.c8
-rw-r--r--kernel/features/io.c4
-rw-r--r--kernel/features/mm.c40
-rw-r--r--kernel/features/proc.c12
4 files changed, 36 insertions, 28 deletions
diff --git a/kernel/features/fs.c b/kernel/features/fs.c
index 34c70e8..6cb10c8 100644
--- a/kernel/features/fs.c
+++ b/kernel/features/fs.c
@@ -147,7 +147,7 @@ res vfs_read(const char *path, void *buf, u32 offset, u32 count)
if (!memory_readable(path))
return -EFAULT;
- if (!memory_writable(buf))
+ if (!memory_writable_range(memory_range(buf, count)))
return -EFAULT;
struct mount_info *m = vfs_find_mount_info(path);
@@ -170,12 +170,12 @@ res vfs_read(const char *path, void *buf, u32 offset, u32 count)
return m->dev->vfs->read(path, buf, offset, count, m->dev);
}
-res vfs_write(const char *path, void *buf, u32 offset, u32 count)
+res vfs_write(const char *path, const void *buf, u32 offset, u32 count)
{
if (!memory_readable(path))
return -EFAULT;
- if (!memory_writable(buf))
+ if (!memory_readable_range(memory_range(buf, count)))
return -EFAULT;
struct mount_info *m = vfs_find_mount_info(path);
@@ -203,7 +203,7 @@ res vfs_stat(const char *path, struct stat *buf)
if (!memory_readable(path))
return -EFAULT;
- if (!memory_writable(buf))
+ if (!memory_writable_range(memory_range(buf, sizeof(*buf))))
return -EFAULT;
struct mount_info *m = vfs_find_mount_info(path);
diff --git a/kernel/features/io.c b/kernel/features/io.c
index fbae5cf..d4737bf 100644
--- a/kernel/features/io.c
+++ b/kernel/features/io.c
@@ -120,7 +120,7 @@ res io_control(enum io_type io, u32 request, void *arg1, void *arg2, void *arg3)
res io_write(enum io_type io, const void *buf, u32 offset, u32 count)
{
- if (!memory_readable(buf))
+ if (!memory_readable_range(memory_range(buf, count)))
return -EFAULT;
struct io_dev *dev;
@@ -132,7 +132,7 @@ res io_write(enum io_type io, const void *buf, u32 offset, u32 count)
res io_read(enum io_type io, void *buf, u32 offset, u32 count)
{
- if (!memory_readable(buf))
+ if (!memory_writable_range(memory_range(buf, count)))
return -EFAULT;
struct io_dev *dev;
diff --git a/kernel/features/mm.c b/kernel/features/mm.c
index 4ed3ab9..a3812bd 100644
--- a/kernel/features/mm.c
+++ b/kernel/features/mm.c
@@ -608,28 +608,48 @@ u8 memory_is_user(const void *addr)
return PDI((u32)addr) >= PAGE_KERNEL_COUNT;
}
-u8 memory_readable(const void *addr)
+u8 memory_readable_range(struct memory_range vrange)
{
- if (!addr)
+ if (!vrange.base)
return 0;
struct proc *proc = proc_current();
- if (proc && !memory_bypass_validity)
- return memory_is_user(addr) && virtual_user_readable(proc->page_dir, (u32)addr);
- else
+ if (memory_bypass_validity || !proc)
return 1;
+
+ u32 offset = 0;
+ do {
+ u8 valid = memory_is_user((void *)(vrange.base + offset)) &&
+ virtual_user_readable(proc->page_dir, vrange.base + offset);
+ if (!valid)
+ return 0;
+
+ offset += PAGE_SIZE;
+ } while (offset < vrange.size);
+
+ return 1;
}
-u8 memory_writable(const void *addr)
+u8 memory_writable_range(struct memory_range vrange)
{
- if (!addr)
+ if (!vrange.base)
return 0;
struct proc *proc = proc_current();
- if (proc && !memory_bypass_validity)
- return memory_is_user(addr) && virtual_user_writable(proc->page_dir, (u32)addr);
- else
+ if (memory_bypass_validity || !proc)
return 1;
+
+ u32 offset = 0;
+ do {
+ u8 valid = memory_is_user((void *)(vrange.base + offset)) &&
+ virtual_user_writable(proc->page_dir, vrange.base + offset);
+ if (!valid)
+ return 0;
+
+ offset += PAGE_SIZE;
+ } while (offset < vrange.size);
+
+ return 1;
}
struct memory_range memory_range_from(u32 base, u32 size)
diff --git a/kernel/features/proc.c b/kernel/features/proc.c
index 4cf4005..b47df0b 100644
--- a/kernel/features/proc.c
+++ b/kernel/features/proc.c
@@ -256,17 +256,6 @@ struct procfs_message {
u32 size;
};
-static res procfs_write(const char *path, void *buf, u32 offset, u32 count, struct vfs_dev *dev)
-{
- UNUSED(path);
- UNUSED(buf);
- UNUSED(offset);
- UNUSED(count);
- UNUSED(dev);
-
- return -ENOENT;
-}
-
static res procfs_read(const char *path, void *buf, u32 offset, u32 count, struct vfs_dev *dev)
{
(void)dev;
@@ -331,7 +320,6 @@ NORETURN void proc_init(void)
struct vfs *vfs = zalloc(sizeof(*vfs));
vfs->type = VFS_PROCFS;
vfs->read = procfs_read;
- vfs->write = procfs_write;
vfs->perm = procfs_perm;
vfs->data = NULL;
struct vfs_dev *dev = zalloc(sizeof(*dev));