From: ljsebald <ljs...@us...> - 2023-03-12 04:32:31
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via bc1c46ecc373d834770633e41b18a94b9b1873d7 (commit) via 55f142357f1a6ceaa9f0b0a997bd7c4097b4ae83 (commit) via 3c642bf921459112fe559484ab176f73721ab67b (commit) via 3f97576228a1335245ec1cda4dc44c111fac576b (commit) via b04bf154a2cfc64b8ed182353cc939170763a13e (commit) via e26d0dbdc11326dcf832cd3b831954a0361f23a2 (commit) via 83f2053711c8720a11b1f5938537d9878b876470 (commit) via 325972fdb3d7c4bc82b0325045972e6c445fa933 (commit) from b7799950e6f7672881fdaf2779ae0607e6499c73 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit bc1c46ecc373d834770633e41b18a94b9b1873d7 Merge: b779995 55f1423 Author: Lawrence Sebald <ljs...@us...> Date: Sat Mar 11 23:31:46 2023 -0500 Merge pull request #109 from KallistiOS/implement-dev-urandom Implement a new FS driver for /dev/random and /dev/urandom commit 55f142357f1a6ceaa9f0b0a997bd7c4097b4ae83 Author: Luke Benstead <ka...@gm...> Date: Wed Mar 1 11:01:52 2023 +0000 Move fs_random to fs_dev commit 3c642bf921459112fe559484ab176f73721ab67b Author: Luke Benstead <ka...@gm...> Date: Wed Mar 1 09:18:33 2023 +0000 Update kernel/libc/newlib/newlib_getentropy.c Co-authored-by: Lawrence Sebald <ljs...@us...> commit 3f97576228a1335245ec1cda4dc44c111fac576b Author: Luke Benstead <ka...@gm...> Date: Wed Mar 1 09:17:52 2023 +0000 Update kernel/arch/dreamcast/kernel/init.c Co-authored-by: Lawrence Sebald <ljs...@us...> commit b04bf154a2cfc64b8ed182353cc939170763a13e Author: Luke Benstead <ka...@gm...> Date: Tue Feb 21 20:29:20 2023 +0000 Make sure we remove both handlers commit e26d0dbdc11326dcf832cd3b831954a0361f23a2 Author: Luke Benstead <ka...@gm...> Date: Tue Feb 21 20:25:20 2023 +0000 Move things out of arch/dreamcast commit 83f2053711c8720a11b1f5938537d9878b876470 Author: Colton Pawielski <cep...@mt...> Date: Tue Feb 21 11:09:39 2023 -0600 Use newlib arc4random_buf for random fs device commit 325972fdb3d7c4bc82b0325045972e6c445fa933 Author: Luke Benstead <ka...@gm...> Date: Mon Feb 20 20:29:56 2023 +0000 Implement a new FS driver for /dev/random and /dev/urandom This helps with portability of libraries which expect it to be there. ----------------------------------------------------------------------- Summary of changes: examples/dreamcast/Makefile | 2 +- examples/dreamcast/{hello => random}/Makefile | 6 +- examples/dreamcast/random/random.c | 37 +++ .../dreamcast/random/romdisk}/.keepme | 0 include/kos.h | 1 + include/kos/fs_dev.h | 41 +++ kernel/arch/dreamcast/fs/Makefile | 2 +- kernel/arch/dreamcast/kernel/init.c | 1 + kernel/arch/dreamcast/kernel/initall_hdrs.h | 1 + kernel/fs/Makefile | 4 +- kernel/fs/fs_dev.c | 327 +++++++++++++++++++++ kernel/libc/newlib/Makefile | 4 +- kernel/libc/newlib/newlib_getentropy.c | 38 +++ 13 files changed, 455 insertions(+), 9 deletions(-) copy examples/dreamcast/{hello => random}/Makefile (93%) create mode 100644 examples/dreamcast/random/random.c copy {addons/lib => examples/dreamcast/random/romdisk}/.keepme (100%) create mode 100644 include/kos/fs_dev.h create mode 100644 kernel/fs/fs_dev.c create mode 100644 kernel/libc/newlib/newlib_getentropy.c diff --git a/examples/dreamcast/Makefile b/examples/dreamcast/Makefile index 7ff5a70..f5cc332 100644 --- a/examples/dreamcast/Makefile +++ b/examples/dreamcast/Makefile @@ -5,7 +5,7 @@ # DIRS = 2ndmix basic libdream kgl hello sound png network vmu conio pvr video \ - lua parallax modem dreameye sd g1ata lightgun keyboard sdl + lua parallax modem dreameye sd g1ata lightgun keyboard sdl random ifdef KOS_CCPLUS DIRS += cpp tsunami endif diff --git a/examples/dreamcast/hello/Makefile b/examples/dreamcast/random/Makefile similarity index 93% copy from examples/dreamcast/hello/Makefile copy to examples/dreamcast/random/Makefile index d2ba544..7ac05a3 100644 --- a/examples/dreamcast/hello/Makefile +++ b/examples/dreamcast/random/Makefile @@ -1,14 +1,14 @@ # # Basic KallistiOS skeleton / test program # Copyright (C)2001-2004 Dan Potter -# +# # Put the filename of the output binary here -TARGET = hello.elf +TARGET = random.elf # List all of your C files here, but change the extension to ".o" # Include "romdisk.o" if you want a rom disk. -OBJS = hello.o romdisk.o +OBJS = random.o romdisk.o # If you define this, the Makefile.rules will create a romdisk.o for you # from the named dir. diff --git a/examples/dreamcast/random/random.c b/examples/dreamcast/random/random.c new file mode 100644 index 0000000..0d5adec --- /dev/null +++ b/examples/dreamcast/random/random.c @@ -0,0 +1,37 @@ +/* KallistiOS ##version## + + random.c + Copyright (C) 2023 Luke Benstead +*/ + +#include <kos.h> +#include <stdint.h> + +KOS_INIT_FLAGS(INIT_DEFAULT); + +int main(int argc, char **argv) { + const int buffer_size = 256; + uint8_t buffer[buffer_size]; + + FILE* urandom = fopen("/dev/urandom", "r"); + if(!urandom) { + fprintf(stderr, "Unable to open /dev/urandom for reading\n"); + return 1; + } + + size_t bytes = fread(buffer, 1, buffer_size, urandom); + fclose(urandom); + + if(bytes != buffer_size) { + fprintf(stderr, "Failed to read the correct number of bytes\n"); + return 2; + } + + printf("Generated the following random bytes:\n\n"); + for(int i = 0; i < buffer_size; ++i) { + printf("0x%02X ", (int) buffer[i]); + } + printf("\n\n"); + + return 0; +} diff --git a/addons/lib/.keepme b/examples/dreamcast/random/romdisk/.keepme similarity index 100% copy from addons/lib/.keepme copy to examples/dreamcast/random/romdisk/.keepme diff --git a/include/kos.h b/include/kos.h index 55c7b1c..019d0e9 100644 --- a/include/kos.h +++ b/include/kos.h @@ -35,6 +35,7 @@ __BEGIN_DECLS #include <kos/fs.h> #include <kos/fs_romdisk.h> #include <kos/fs_ramdisk.h> +#include <kos/fs_dev.h> #include <kos/fs_pty.h> #include <kos/limits.h> #include <kos/thread.h> diff --git a/include/kos/fs_dev.h b/include/kos/fs_dev.h new file mode 100644 index 0000000..2c94e3e --- /dev/null +++ b/include/kos/fs_dev.h @@ -0,0 +1,41 @@ +/* KallistiOS ##version## + + dc/fs_dev.h + (c)2023 - Luke Benstead + +*/ + +/** \file dc/fs_dev.h + \brief Driver for /dev/random and /dev/urandom. + + This filesystem driver provides implementations of /dev/random + and /dev/urandom for portability. It seeds randomness from + uninitialized memory, and the clock. Obviously we + are limited in how we can provide sufficient entropy on an + embedded platform like the Dreamcast so the randomness from + this driver will not win any awards but it should be sufficiently + good for most purposes. + + /dev/random is an alias to /dev/urandom for now. + + \author Luke Benstead +*/ + +#ifndef __DC_FS_DEV_H +#define __DC_FS_DEV_H + +#include <sys/cdefs.h> +__BEGIN_DECLS + +#include <kos/fs.h> + +/* \cond */ +/* Initialization */ +int fs_dev_init(); +int fs_dev_shutdown(); +/* \endcond */ + +__END_DECLS + +#endif /* __DC_FS_DEV_H */ + diff --git a/kernel/arch/dreamcast/fs/Makefile b/kernel/arch/dreamcast/fs/Makefile index 03a2c5d..a4bad92 100644 --- a/kernel/arch/dreamcast/fs/Makefile +++ b/kernel/arch/dreamcast/fs/Makefile @@ -8,6 +8,6 @@ OBJS = fs_iso9660.o fs_vmu.o fs_dcload.o dcload-syscall.o vmufs.o \ fs_dclsocket.o -SUBDIRS = +SUBDIRS = include $(KOS_BASE)/Makefile.prefab diff --git a/kernel/arch/dreamcast/kernel/init.c b/kernel/arch/dreamcast/kernel/init.c index 04e8cfe..02efd4b 100644 --- a/kernel/arch/dreamcast/kernel/init.c +++ b/kernel/arch/dreamcast/kernel/init.c @@ -116,6 +116,7 @@ int __attribute__((weak)) arch_auto_init() { fs_pty_init(); /* Pty */ fs_ramdisk_init(); /* Ramdisk */ fs_romdisk_init(); /* Romdisk */ + fs_dev_init(); /* /dev/urandom etc. */ hardware_periph_init(); /* DC peripheral init */ diff --git a/kernel/arch/dreamcast/kernel/initall_hdrs.h b/kernel/arch/dreamcast/kernel/initall_hdrs.h index c3da587..f505df3 100644 --- a/kernel/arch/dreamcast/kernel/initall_hdrs.h +++ b/kernel/arch/dreamcast/kernel/initall_hdrs.h @@ -3,6 +3,7 @@ #include <kos/fs.h> #include <kos/thread.h> #include <kos/fs_pty.h> +#include <kos/fs_dev.h> #include <kos/fs_romdisk.h> #include <kos/fs_ramdisk.h> #include <kos/library.h> diff --git a/kernel/fs/Makefile b/kernel/fs/Makefile index 03d71bb..3e979db 100644 --- a/kernel/fs/Makefile +++ b/kernel/fs/Makefile @@ -4,9 +4,9 @@ # (c)2000-2001 Dan Potter # -OBJS = fs.o fs_romdisk.o fs_ramdisk.o fs_pty.o +OBJS = fs.o fs_dev.o fs_romdisk.o fs_ramdisk.o fs_pty.o OBJS += fs_utils.o elf.o fs_socket.o -SUBDIRS = +SUBDIRS = include $(KOS_BASE)/Makefile.prefab diff --git a/kernel/fs/fs_dev.c b/kernel/fs/fs_dev.c new file mode 100644 index 0000000..dcd00d5 --- /dev/null +++ b/kernel/fs/fs_dev.c @@ -0,0 +1,327 @@ +/* KallistiOS ##version## + + fs_dev.c + Copyright (C) 2023 Luke Benstead +*/ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <stdint.h> +#include <malloc.h> +#include <errno.h> +#include <time.h> +#include <arch/types.h> +#include <kos/mutex.h> +#include <kos/fs_dev.h> +#include <sys/queue.h> +#include <errno.h> +#include <sys/time.h> + +/* This function is declared in <stdlib.h> but behind an if __BSD_VISIBLE + Declaring as extern here to avoid implicit declaration */ +void arc4random_buf (void *, size_t); + +/* File handles */ +typedef struct dev_fh_str { + int mode; /* mode the file was opened with */ + + TAILQ_ENTRY(dev_fh_str) listent; /* list entry */ +} dev_fh_t; + +/* Linked list of open files (controlled by "mutex") */ +TAILQ_HEAD(dev_fh_list, dev_fh_str) dev_fh; + +/* Thread mutex for dev_fh access */ +static mutex_t fh_mutex; + + +/* openfile function */ +static dev_fh_t *dev_open_file(vfs_handler_t * vfs, const char *fn, int mode) { + (void) vfs; + + if(strcmp(fn, "/urandom") != 0 && strcmp(fn, "/random") != 0) { + return NULL; + } + + dev_fh_t * fd; /* file descriptor */ + int realmode; + + /* Malloc a new fh struct */ + fd = malloc(sizeof(dev_fh_t)); + + /* Fill in the filehandle struct */ + fd->mode = mode; + + realmode = mode & O_MODE_MASK; + + /* We only allow reading, not writing */ + if(realmode != O_RDONLY) { + free(fd); + return NULL; + } + + return fd; +} + +/* open function */ +static void * dev_open(vfs_handler_t * vfs, const char *path, int mode) { + dev_fh_t *fh = dev_open_file(vfs, path, mode); + if(!fh) { + return NULL; + } + + /* link the fh onto the top of the list */ + mutex_lock(&fh_mutex); + TAILQ_INSERT_TAIL(&dev_fh, fh, listent); + mutex_unlock(&fh_mutex); + + return (void *)fh; +} + +/* Verify that a given hnd is actually in the list */ +static int dev_verify_hnd(void * hnd) { + dev_fh_t *cur; + int rv; + + rv = 0; + + mutex_lock(&fh_mutex); + TAILQ_FOREACH(cur, &dev_fh, listent) { + if((void *)cur == hnd) { + rv = 1; + break; + } + } + mutex_unlock(&fh_mutex); + + if(rv) + return 1; + else + return 0; +} + +/* close a file */ +static int dev_close(void * hnd) { + dev_fh_t *fh; + int retval = 0; + + /* Check the handle */ + if(!dev_verify_hnd(hnd)) { + errno = EBADF; + return -1; + } + + fh = (dev_fh_t *)hnd; + + /* Look for the one to get rid of */ + mutex_lock(&fh_mutex); + TAILQ_REMOVE(&dev_fh, fh, listent); + mutex_unlock(&fh_mutex); + + free(fh); + return retval; +} + +/* read function */ +static ssize_t dev_read(void * hnd, void *buffer, size_t cnt) { + dev_fh_t *fh; + uint8_t* buf = buffer; + + /* Check the handle */ + if(!dev_verify_hnd(hnd)) + return -1; + + fh = (dev_fh_t *)hnd; + + /* make sure we're opened for reading */ + if((fh->mode & O_MODE_MASK) != O_RDONLY && (fh->mode & O_MODE_MASK) != O_RDWR) + return 0; + + arc4random_buf(buf, cnt); + + return cnt; +} + +/* write function */ +static ssize_t dev_write(void * hnd, const void *buffer, size_t cnt) { + (void) buffer; + (void) cnt; + + dev_fh_t *fh; + + /* Check the handle we were given */ + if(!dev_verify_hnd(hnd)) + return -1; + + fh = (dev_fh_t *)hnd; + + /* Make sure we're opened for writing */ + if((fh->mode & O_MODE_MASK) != O_WRONLY && (fh->mode & O_MODE_MASK) != O_RDWR) + return -1; + + dbglog(DBG_ERROR, "RANDOMFS: writing entropy is not supported\n"); + return -1; +} + + +/* Seek elsewhere in a file */ +static off_t dev_seek(void * hnd, off_t offset, int whence) { + (void) offset; + (void) whence; + + /* Check the handle */ + if(!dev_verify_hnd(hnd)) + return -1; + + return 0; +} + +/* tell the current position in the file */ +static off_t dev_tell(void * hnd) { + /* Check the handle */ + if(!dev_verify_hnd(hnd)) + return -1; + + return 0; +} + +/* return the filesize */ +static size_t dev_total(void * fd) { + /* Check the handle */ + if(!dev_verify_hnd(fd)) + return -1; + + /* The size of /dev/urandom always returns 0 */ + return 0; +} + + +/* Delete a file */ +static int dev_unlink(vfs_handler_t * vfs, const char *path) { + (void) vfs; + (void) path; + + dbglog(DBG_ERROR, "RANDOMFS: Attempted to delete system file\n"); + return -1; +} + +static int dev_stat(vfs_handler_t *vfs, const char *fn, struct stat *rv, + int flag) { + (void)vfs; + (void)fn; + (void)flag; + + memset(rv, 0, sizeof(struct stat)); + rv->st_mode = S_IRUSR; + rv->st_nlink = 1; + + return 0; +} + +static int dev_fcntl(void *fd, int cmd, va_list ap) { + int rv = -1; + + (void)ap; + + /* Check the handle */ + if(!dev_verify_hnd(fd)) { + errno = EBADF; + return -1; + } + + switch(cmd) { + case F_GETFL: + rv = O_RDONLY; + break; + + case F_SETFL: + case F_GETFD: + case F_SETFD: + rv = 0; + break; + + default: + errno = EINVAL; + } + + return rv; +} + +static int dev_fstat(void *fd, struct stat *st) { + + /* Check the handle */ + if(!dev_verify_hnd(fd)) { + errno = EBADF; + return -1; + } + + memset(st, 0, sizeof(struct stat)); + st->st_mode = S_IFREG | S_IRUSR; + st->st_nlink = 1; + + return 0; +} + +/* handler interface */ +static vfs_handler_t vh = { + /* Name handler */ + { + "/dev", /* name */ + 0, /* tbfi */ + 0x00010000, /* Version 1.0 */ + 0, /* flags */ + NMMGR_TYPE_VFS, /* VFS handler */ + NMMGR_LIST_INIT + }, + 0, NULL, /* In-kernel, privdata */ + + dev_open, + dev_close, + dev_read, + dev_write, + dev_seek, + dev_tell, + dev_total, + NULL, + NULL, /* ioctl */ + NULL, /* rename/move */ + dev_unlink, ...<truncated>... hooks/post-receive -- A pseudo Operating System for the Dreamcast. |