aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Borner2021-02-07 14:23:32 +0100
committerMarvin Borner2021-02-07 14:23:32 +0100
commiteca4dfd49216f6158df69143994a18a0b3edd4fe (patch)
tree831e2ffe1724d4761d734fe753df0d0ea6958dd2
parent03b8f1d1976e0f74c80556315105734354fc06fc (diff)
Added filesystem and proc permissions
-rw-r--r--kernel/drivers/ide.c3
-rw-r--r--kernel/features/fs.c36
-rw-r--r--kernel/features/proc.c29
-rw-r--r--kernel/inc/fs.h14
-rw-r--r--kernel/inc/proc.h2
5 files changed, 76 insertions, 8 deletions
diff --git a/kernel/drivers/ide.c b/kernel/drivers/ide.c
index 7dd2416..8fc90c9 100644
--- a/kernel/drivers/ide.c
+++ b/kernel/drivers/ide.c
@@ -147,8 +147,9 @@ void ata_probe(void)
struct vfs *vfs = malloc(sizeof(*vfs));
vfs->type = VFS_EXT2;
vfs->read = ext2_read;
- vfs->ready = ext2_ready;
vfs->stat = ext2_stat;
+ vfs->perm = ext2_perm;
+ vfs->ready = ext2_ready;
dev->vfs = vfs;
dev->data = data;
vfs_mount(dev, "/");
diff --git a/kernel/features/fs.c b/kernel/features/fs.c
index b59eb03..ecb2b85 100644
--- a/kernel/features/fs.c
+++ b/kernel/features/fs.c
@@ -130,12 +130,15 @@ s32 vfs_read(const char *path, void *buf, u32 offset, u32 count)
path++;
struct mount_info *m = vfs_find_mount_info(path);
- assert(m && m->dev && m->dev->vfs && m->dev->vfs->read);
+ assert(m && m->dev && m->dev->vfs && m->dev->vfs->read && m->dev->vfs->perm);
u32 len = strlen(m->path);
if (len > 1)
path += len;
+ if (!m->dev->vfs->perm(path, VFS_READ, m->dev) && !proc_super())
+ return -1;
+
return m->dev->vfs->read(path, buf, offset, count, m->dev);
}
@@ -151,12 +154,15 @@ s32 vfs_write(const char *path, void *buf, u32 offset, u32 count)
path++;
struct mount_info *m = vfs_find_mount_info(path);
- assert(m && m->dev && m->dev->vfs && m->dev->vfs->write);
+ assert(m && m->dev && m->dev->vfs && m->dev->vfs->write && m->dev->vfs->perm);
u32 len = strlen(m->path);
if (len > 1)
path += len;
+ if (!m->dev->vfs->perm(path, VFS_WRITE, m->dev) && !proc_super())
+ return -1;
+
return m->dev->vfs->write(path, buf, offset, count, m->dev);
}
@@ -237,6 +243,14 @@ s32 devfs_read(const char *path, void *buf, u32 offset, u32 count, struct device
return target->read(buf, offset, count, dev);
}
+u8 devfs_perm(const char *path, enum vfs_perm perm, struct device *dev)
+{
+ (void)path;
+ (void)perm;
+ (void)dev;
+ return 1;
+}
+
u8 devfs_ready(const char *path, struct device *dev)
{
(void)dev;
@@ -307,7 +321,7 @@ struct ext2_inode *get_inode(u32 i, struct device *dev)
(struct ext2_inode *)((u32)buf +
(index % (BLOCK_SIZE / EXT2_INODE_SIZE)) * EXT2_INODE_SIZE);
- free(buf);
+ free(buf); // TODO: Fix use after free with *in
free(s);
free(b - block_group);
@@ -466,6 +480,22 @@ s32 ext2_stat(const char *path, struct stat *buf, struct device *dev)
return 0;
}
+u8 ext2_perm(const char *path, enum vfs_perm perm, struct device *dev)
+{
+ struct ext2_inode *in = find_inode_by_path(path, dev);
+
+ switch (perm) {
+ case VFS_EXEC:
+ return (in->mode & EXT2_PERM_UEXEC) != 0;
+ case VFS_WRITE:
+ return (in->mode & EXT2_PERM_UWRITE) != 0;
+ case VFS_READ:
+ return (in->mode & EXT2_PERM_UREAD) != 0;
+ default:
+ return 0;
+ }
+}
+
u8 ext2_ready(const char *path, struct device *dev)
{
(void)path;
diff --git a/kernel/features/proc.c b/kernel/features/proc.c
index bec48fa..5dde2bd 100644
--- a/kernel/features/proc.c
+++ b/kernel/features/proc.c
@@ -14,10 +14,10 @@
u32 current_pid = 0;
u32 quantum = 0;
-struct proc *priority_proc;
-struct list *proc_list;
-struct node *idle_proc;
-struct node *current;
+struct proc *priority_proc = NULL;
+struct list *proc_list = NULL;
+struct node *idle_proc = NULL;
+struct node *current = NULL;
// TODO: Use less memcpy and only copy relevant registers
// TODO: 20 priority queues (https://www.kernel.org/doc/html/latest/scheduler/sched-nice-design.html)
@@ -88,6 +88,17 @@ struct proc *proc_current(void)
return current && current->data ? current->data : NULL;
}
+u8 proc_super(void)
+{
+ struct proc *proc = proc_current();
+ if (proc)
+ return proc->super;
+ else if (current_pid == 0)
+ return 1; // Kernel has super permissions
+ else
+ return 0; // Should never happen
+}
+
struct proc *proc_from_pid(u32 pid)
{
struct node *iterator = proc_list->head;
@@ -156,6 +167,7 @@ struct proc *proc_make(void)
{
struct proc *proc = malloc(sizeof(*proc));
proc->pid = current_pid++;
+ proc->super = 0;
proc->messages = stack_new();
proc->state = PROC_RUNNING;
@@ -246,6 +258,14 @@ s32 procfs_read(const char *path, void *buf, u32 offset, u32 count, struct devic
return -1;
}
+u8 procfs_perm(const char *path, enum vfs_perm perm, struct device *dev)
+{
+ (void)path;
+ (void)perm;
+ (void)dev;
+ return 1;
+}
+
u8 procfs_ready(const char *path, struct device *dev)
{
(void)path;
@@ -293,6 +313,7 @@ void proc_init(void)
_eip = ((struct proc *)new->data)->regs.eip;
_esp = ((struct proc *)new->data)->regs.useresp;
+ ((struct proc *)new->data)->super = 1;
u32 argc = 2;
char **argv = malloc(sizeof(*argv) * (argc + 1));
diff --git a/kernel/inc/fs.h b/kernel/inc/fs.h
index 64f3970..1069597 100644
--- a/kernel/inc/fs.h
+++ b/kernel/inc/fs.h
@@ -32,6 +32,7 @@ void device_add(struct device *dev);
*/
enum vfs_type { VFS_DEVFS, VFS_TMPFS, VFS_PROCFS, VFS_EXT2 };
+enum vfs_perm { VFS_EXEC, VFS_WRITE, VFS_READ };
struct vfs {
enum vfs_type type;
@@ -40,6 +41,7 @@ struct vfs {
s32 (*read)(const char *path, void *buf, u32 offset, u32 count, struct device *dev);
s32 (*write)(const char *path, void *buf, u32 offset, u32 count, struct device *dev);
s32 (*stat)(const char *path, struct stat *buf, struct device *dev);
+ u8 (*perm)(const char *path, enum vfs_perm perm, struct device *dev);
u8 (*ready)(const char *path, struct device *dev);
};
@@ -71,6 +73,17 @@ struct device *device_get_by_name(const char *name);
#define EXT2_ROOT 2
#define EXT2_MAGIC 0x0000EF53
+// TODO: Support other and group permissions?
+#define EXT2_PERM_OEXEC 0x001
+#define EXT2_PERM_OWRITE 0x002
+#define EXT2_PERM_OREAD 0x004
+#define EXT2_PERM_GEXEC 0x008
+#define EXT2_PERM_GWRITE 0x010
+#define EXT2_PERM_GREAD 0x020
+#define EXT2_PERM_UEXEC 0x040
+#define EXT2_PERM_UWRITE 0x080
+#define EXT2_PERM_UREAD 0x100
+
struct ext2_superblock {
u32 total_inodes;
u32 total_blocks;
@@ -155,6 +168,7 @@ struct ext2_file {
s32 ext2_read(const char *path, void *buf, u32 offset, u32 count, struct device *dev);
s32 ext2_stat(const char *path, struct stat *buf, struct device *dev);
+u8 ext2_perm(const char *path, enum vfs_perm perm, struct device *dev);
u8 ext2_ready(const char *path, struct device *dev);
#endif
diff --git a/kernel/inc/proc.h b/kernel/inc/proc.h
index 6be7da3..4a75638 100644
--- a/kernel/inc/proc.h
+++ b/kernel/inc/proc.h
@@ -26,6 +26,7 @@ struct proc_wait {
struct proc {
u32 pid;
+ u8 super;
char name[32];
struct regs regs;
struct proc_wait wait; // dev_id
@@ -37,6 +38,7 @@ void scheduler(struct regs *regs);
void proc_init(void);
void proc_print(void);
struct proc *proc_current(void);
+u8 proc_super(void);
struct proc *proc_from_pid(u32 pid);
void proc_exit(struct proc *proc, int status);
void proc_yield(struct regs *r);