diff --git a/kernel/fs/pipe.c b/kernel/fs/pipe.c index 81f174b28..7a5441f19 100644 --- a/kernel/fs/pipe.c +++ b/kernel/fs/pipe.c @@ -221,6 +221,7 @@ fs_node_t * make_pipe(size_t size) { sprintf(fnode->name, "[pipe]"); fnode->uid = 0; fnode->gid = 0; + fnode->mask = 0666; fnode->flags = FS_PIPE; fnode->read = read_pipe; fnode->write = write_pipe; diff --git a/kernel/fs/ramdisk.c b/kernel/fs/ramdisk.c index 2a3b5e1bc..4c15e00bf 100644 --- a/kernel/fs/ramdisk.c +++ b/kernel/fs/ramdisk.c @@ -64,6 +64,7 @@ static fs_node_t * ramdisk_device_create(int device_number, uintptr_t location, sprintf(fnode->name, "ram%d", device_number); fnode->uid = 0; fnode->gid = 0; + fnode->mask = 0660; fnode->length = size; fnode->flags = FS_BLOCKDEVICE; fnode->read = read_ramdisk; diff --git a/kernel/fs/tty.c b/kernel/fs/tty.c index f3802539d..8f647f52a 100644 --- a/kernel/fs/tty.c +++ b/kernel/fs/tty.c @@ -288,6 +288,7 @@ fs_node_t * pty_master_create(pty_t * pty) { sprintf(fnode->name, "pty master"); fnode->uid = 0; fnode->gid = 0; + fnode->mask = 0666; fnode->flags = FS_PIPE; fnode->read = read_pty_master; fnode->write = write_pty_master; @@ -311,6 +312,7 @@ fs_node_t * pty_slave_create(pty_t * pty) { sprintf(fnode->name, "pty slave"); fnode->uid = 0; fnode->gid = 0; + fnode->mask = 0666; fnode->flags = FS_PIPE; fnode->read = read_pty_slave; fnode->write = write_pty_slave; diff --git a/kernel/fs/unixpipe.c b/kernel/fs/unixpipe.c index c6c5cd8d6..f4ca036b6 100644 --- a/kernel/fs/unixpipe.c +++ b/kernel/fs/unixpipe.c @@ -105,6 +105,9 @@ int make_unix_pipe(fs_node_t ** pipes) { sprintf(pipes[0]->name, "[pipe:read]"); sprintf(pipes[1]->name, "[pipe:write]"); + pipes[0]->flags = 0666; + pipes[1]->flags = 0666; + pipes[0]->flags = FS_PIPE; pipes[1]->flags = FS_PIPE; diff --git a/kernel/fs/vfs.c b/kernel/fs/vfs.c index 978dd980c..a743a33d6 100644 --- a/kernel/fs/vfs.c +++ b/kernel/fs/vfs.c @@ -25,6 +25,24 @@ fs_node_t * fs_root = NULL; /* Pointer to the root mount fs_node (must be some f hashmap_t * fs_types = NULL; +int has_permission(fs_node_t * node, int permission_bit) { + if (!node) return 0; + + uint32_t permissions = node->mask; + + uint8_t user_perm = (permissions >> 6) & 07; + //uint8_t group_perm = (permissions >> 3) & 07; + uint8_t other_perm = (permissions) & 07; + + if (current_process->user == node->uid) { + return (permission_bit & user_perm); + /* TODO group permissions? */ + } else { + return (permission_bit & other_perm); + } + +} + static struct dirent * readdir_mapper(fs_node_t *node, uint32_t index) { tree_node_t * d = (tree_node_t *)node->device; @@ -272,6 +290,10 @@ int create_file_fs(char *name, uint16_t permission) { return -1; } + if (!has_permission(parent, 02)) { + return -EACCES; + } + if (parent->create) { parent->create(parent, f_path, permission); } diff --git a/kernel/include/fs.h b/kernel/include/fs.h index 92db56d74..35dd96795 100644 --- a/kernel/include/fs.h +++ b/kernel/include/fs.h @@ -123,6 +123,7 @@ struct vfs_entry { extern fs_node_t *fs_root; extern int pty_create(void *size, fs_node_t ** fs_master, fs_node_t ** fs_slave); +int has_permission(fs_node_t *node, int permission_bit); uint32_t read_fs(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer); uint32_t write_fs(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer); void open_fs(fs_node_t *node, unsigned int flags); diff --git a/kernel/sys/syscall.c b/kernel/sys/syscall.c index 01dbd9ecd..23add10df 100644 --- a/kernel/sys/syscall.c +++ b/kernel/sys/syscall.c @@ -59,6 +59,7 @@ static int __attribute__((noreturn)) sys_exit(int retval) { static int sys_read(int fd, char * ptr, int len) { if (FD_CHECK(fd)) { PTR_VALIDATE(ptr); + fs_node_t * node = FD_ENTRY(fd); uint32_t out = read_fs(node, node->offset, len, (uint8_t *)ptr); node->offset += out; @@ -94,6 +95,10 @@ static int sys_write(int fd, char * ptr, int len) { if (FD_CHECK(fd)) { PTR_VALIDATE(ptr); fs_node_t * node = FD_ENTRY(fd); + if (!has_permission(node, 02)) { + debug_print(WARNING, "access denied (write, fd=%d)", fd); + return -EACCES; + } uint32_t out = write_fs(node, node->offset, len, (uint8_t *)ptr); node->offset += out; return out; @@ -112,11 +117,27 @@ static int sys_open(const char * file, int flags, int mode) { PTR_VALIDATE(file); debug_print(NOTICE, "open(%s) flags=0x%x; mode=0x%x", file, flags, mode); fs_node_t * node = kopen((char *)file, flags); + + if (node && !has_permission(node, 04)) { + debug_print(WARNING, "access denied (read, sys_open, file=%s)", file); + return -EACCES; + } + if (node && ((flags & O_RDWR) || (flags & O_APPEND) || (flags & O_WRONLY))) { + if (!has_permission(node, 02)) { + debug_print(WARNING, "access denied (write, sys_open, file=%s)", file); + return -EACCES; + } + } + if (!node && (flags & O_CREAT)) { + /* TODO check directory permissions */ debug_print(NOTICE, "- file does not exist and create was requested."); /* Um, make one */ - if (!create_file_fs((char *)file, mode)) { + int result = create_file_fs((char *)file, mode); + if (!result) { node = kopen((char *)file, flags); + } else { + return result; } } if (!node) { diff --git a/modules/ata.c b/modules/ata.c index fdf40230b..cfc46bba0 100644 --- a/modules/ata.c +++ b/modules/ata.c @@ -275,6 +275,7 @@ static fs_node_t * atapi_device_create(struct ata_device * device) { fnode->device = device; fnode->uid = 0; fnode->gid = 0; + fnode->mask = 0660; fnode->length = atapi_max_offset(device); fnode->flags = FS_BLOCKDEVICE; fnode->read = read_atapi; @@ -296,6 +297,7 @@ static fs_node_t * ata_device_create(struct ata_device * device) { fnode->device = device; fnode->uid = 0; fnode->gid = 0; + fnode->mask = 0660; fnode->length = ata_max_offset(device); /* TODO */ fnode->flags = FS_BLOCKDEVICE; fnode->read = read_ata; diff --git a/modules/ataold.c b/modules/ataold.c index 921508b9b..05206f955 100644 --- a/modules/ataold.c +++ b/modules/ataold.c @@ -175,6 +175,7 @@ static fs_node_t * ata_device_create(struct ata_device * device) { fnode->device = device; fnode->uid = 0; fnode->gid = 0; + fnode->mask = 0660; fnode->length = ata_max_offset(device); /* TODO */ fnode->flags = FS_BLOCKDEVICE; fnode->read = read_ata; diff --git a/modules/dospart.c b/modules/dospart.c index cb88636d7..d955326aa 100644 --- a/modules/dospart.c +++ b/modules/dospart.c @@ -71,6 +71,7 @@ static fs_node_t * dospart_device_create(int i, fs_node_t * dev, partition_t * p fnode->device = device; fnode->uid = 0; fnode->gid = 0; + fnode->mask = 0660; fnode->length = device->partition.sector_count * SECTORSIZE; /* TODO */ fnode->flags = FS_BLOCKDEVICE; fnode->read = read_part; diff --git a/modules/iso9660.c b/modules/iso9660.c index 1f5a4da6b..89b2fda69 100644 --- a/modules/iso9660.c +++ b/modules/iso9660.c @@ -332,7 +332,7 @@ static void file_from_dir_entry(iso_9660_fs_t * this, size_t sector, iso_9660_di fs->uid = 0; fs->gid = 0; fs->length = dir->extent_length_LSB; - fs->mask = 0x0; + fs->mask = 0444; fs->nlink = 0; /* Unsupported */ if (dir->flags & FLAG_DIRECTORY) { fs->flags = FS_DIRECTORY; diff --git a/modules/lfbvideo.c b/modules/lfbvideo.c index 41a74c5b2..53cb4620d 100644 --- a/modules/lfbvideo.c +++ b/modules/lfbvideo.c @@ -160,6 +160,7 @@ static fs_node_t * lfb_video_device_create(void /* TODO */) { sprintf(fnode->name, "fb0"); /* TODO */ fnode->length = lfb_resolution_x * lfb_resolution_y * (lfb_resolution_b / 8); fnode->flags = FS_BLOCKDEVICE; + fnode->mask = 0660; fnode->ioctl = ioctl_vid; return fnode; } diff --git a/modules/net.c b/modules/net.c index 6866ed90e..3acfe56a9 100644 --- a/modules/net.c +++ b/modules/net.c @@ -392,7 +392,7 @@ static fs_node_t * finddir_netfs(fs_node_t * node, char * name) { memset(fnode, 0x00, sizeof(fs_node_t)); fnode->inode = 0; strcpy(fnode->name, name); - fnode->mask = 0555; + fnode->mask = 0666; fnode->flags = FS_CHARDEVICE; fnode->read = socket_read; fnode->write = socket_write; diff --git a/modules/packetfs.c b/modules/packetfs.c index 40e52a3d3..c131dfbda 100644 --- a/modules/packetfs.c +++ b/modules/packetfs.c @@ -328,6 +328,7 @@ static fs_node_t * file_from_pex(pex_ex_t * pex) { fnode->inode = 0; strcpy(fnode->name, pex->name); fnode->device = pex; + fnode->mask = 0666; fnode->flags = FS_CHARDEVICE; fnode->open = open_pex; fnode->read = read_server; @@ -434,6 +435,7 @@ static fs_node_t * packetfs_manager(void) { fnode->inode = 0; strcpy(fnode->name, "pex"); fnode->device = pex; + fnode->mask = 0777; fnode->flags = FS_DIRECTORY; fnode->readdir = readdir_packetfs; fnode->finddir = finddir_packetfs; diff --git a/modules/pcspkr.c b/modules/pcspkr.c index 06d12262c..6a74b9657 100644 --- a/modules/pcspkr.c +++ b/modules/pcspkr.c @@ -52,6 +52,7 @@ static fs_node_t * spkr_device_create(void) { fs_node_t * fnode = malloc(sizeof(fs_node_t)); memset(fnode, 0x00, sizeof(fs_node_t)); sprintf(fnode->name, "spkr"); + fnode->mask = 0666; /* TODO need a speaker group */ fnode->flags = FS_CHARDEVICE; fnode->write = write_spkr; return fnode; diff --git a/modules/random.c b/modules/random.c index ffca6dc21..f01c41721 100644 --- a/modules/random.c +++ b/modules/random.c @@ -47,6 +47,7 @@ static fs_node_t * random_device_create(void) { strcpy(fnode->name, "random"); fnode->uid = 0; fnode->gid = 0; + fnode->mask = 0444; fnode->length = 1024; fnode->flags = FS_CHARDEVICE; fnode->read = read_random; diff --git a/modules/serial.c b/modules/serial.c index ad303c053..ac3ba5edf 100644 --- a/modules/serial.c +++ b/modules/serial.c @@ -149,6 +149,7 @@ static fs_node_t * serial_device_create(int device) { strcpy(fnode->name, "serial"); fnode->uid = 0; fnode->gid = 0; + fnode->mask = 0660; fnode->flags = FS_CHARDEVICE; fnode->read = read_serial; fnode->write = write_serial; diff --git a/modules/snd.c b/modules/snd.c index ece7e631b..bbcd19d95 100644 --- a/modules/snd.c +++ b/modules/snd.c @@ -39,6 +39,7 @@ static list_t _devices; static fs_node_t _dsp_fnode = { .name = "dsp", .device = &_devices, + .mask = 0666, .flags = FS_CHARDEVICE, .ioctl = snd_dsp_ioctl, .write = snd_dsp_write, @@ -47,7 +48,8 @@ static fs_node_t _dsp_fnode = { }; static fs_node_t _mixer_fnode = { .name = "mixer", - .flags = FS_CHARDEVICE, + .mask = 0666, + .flags = FS_CHARDEVICE, .ioctl = snd_mixer_ioctl, .open = snd_mixer_open, .close = snd_mixer_close, diff --git a/modules/zero.c b/modules/zero.c index 8b647c6b4..1a7f4a772 100644 --- a/modules/zero.c +++ b/modules/zero.c @@ -60,6 +60,7 @@ static fs_node_t * null_device_create(void) { strcpy(fnode->name, "null"); fnode->uid = 0; fnode->gid = 0; + fnode->mask = 0666; fnode->flags = FS_CHARDEVICE; fnode->read = read_null; fnode->write = write_null; @@ -78,6 +79,7 @@ static fs_node_t * zero_device_create(void) { strcpy(fnode->name, "zero"); fnode->uid = 0; fnode->gid = 0; + fnode->mask = 0666; fnode->flags = FS_CHARDEVICE; fnode->read = read_zero; fnode->write = write_zero; diff --git a/toolchain/patches/newlib/toaru/syscalls.c b/toolchain/patches/newlib/toaru/syscalls.c index 4a7dff935..5dd1dfb2e 100644 --- a/toolchain/patches/newlib/toaru/syscalls.c +++ b/toolchain/patches/newlib/toaru/syscalls.c @@ -259,6 +259,8 @@ int open(const char *name, int flags, ...) { } else { errno = ENOENT; } + } else if (result < 0) { + errno = -result; } return result; } diff --git a/userspace/core/touch.c b/userspace/core/touch.c index 39469ead9..658dba642 100644 --- a/userspace/core/touch.c +++ b/userspace/core/touch.c @@ -18,6 +18,10 @@ int main(int argc, char * argv[]) { } FILE * f = fopen(argv[1], "a"); + if (!f) { + perror(argv[0]); + return 1; + } fclose(f); return 0; diff --git a/util/devtable b/util/devtable index 25dd9ce5f..1a2b7ad50 100644 --- a/util/devtable +++ b/util/devtable @@ -1 +1,4 @@ /bin/sudo f 4555 0 0 - - - - - +/home/local d 775 1000 1000 - - - - - +/home/local/.desktop.conf f 664 1000 1000 - - - - - +/home/local/.menu.desktop f 664 1000 1000 - - - - -