diff options
author | Marvin Borner | 2021-02-07 14:23:32 +0100 |
---|---|---|
committer | Marvin Borner | 2021-02-07 14:23:32 +0100 |
commit | eca4dfd49216f6158df69143994a18a0b3edd4fe (patch) | |
tree | 831e2ffe1724d4761d734fe753df0d0ea6958dd2 | |
parent | 03b8f1d1976e0f74c80556315105734354fc06fc (diff) |
Added filesystem and proc permissions
-rw-r--r-- | kernel/drivers/ide.c | 3 | ||||
-rw-r--r-- | kernel/features/fs.c | 36 | ||||
-rw-r--r-- | kernel/features/proc.c | 29 | ||||
-rw-r--r-- | kernel/inc/fs.h | 14 | ||||
-rw-r--r-- | kernel/inc/proc.h | 2 |
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); |