Search
lxdream.org :: lxdream :: r209:ff67a7b9aa17
lxdream 0.9.1
released Jun 29
Download Now
changeset209:ff67a7b9aa17
parent208:ad290228eea1
child210:c356f597c896
authornkeynes
dateMon Aug 07 13:18:16 2006 +0000 (13 years ago)
Implement open/close dcload syscalls, change permission flag to "unsafe"
src/dcload.c
src/main.c
src/syscall.h
1.1 --- a/src/dcload.c Sun Aug 06 09:43:03 2006 +0000
1.2 +++ b/src/dcload.c Mon Aug 07 13:18:16 2006 +0000
1.3 @@ -1,5 +1,5 @@
1.4 /**
1.5 - * $Id: dcload.c,v 1.5 2006-07-06 22:44:39 nkeynes Exp $
1.6 + * $Id: dcload.c,v 1.6 2006-08-07 13:18:16 nkeynes Exp $
1.7 *
1.8 * DC-load syscall implementation.
1.9 *
1.10 @@ -48,40 +48,104 @@
1.11 #define SYS_MAGIC_ADDR 0x8c004004
1.12 #define SYSCALL_ADDR 0x8c004008
1.13
1.14 -static gboolean dcload_allow_exit = FALSE;
1.15 +static gboolean dcload_allow_unsafe = FALSE;
1.16
1.17 -void dcload_set_allow_exit( gboolean allow )
1.18 +void dcload_set_allow_unsafe( gboolean allow )
1.19 {
1.20 - dcload_allow_exit = allow;
1.21 + dcload_allow_unsafe = allow;
1.22 +}
1.23 +
1.24 +#define MAX_OPEN_FDS 16
1.25 +/**
1.26 + * Mapping from emulator fd to real fd (so we can limit read/write
1.27 + * to only fds we've explicitly granted access to).
1.28 + */
1.29 +int open_fds[MAX_OPEN_FDS];
1.30 +
1.31 +int dcload_alloc_fd()
1.32 +{
1.33 + int i;
1.34 + for( i=0; i<MAX_OPEN_FDS; i++ ) {
1.35 + if( open_fds[i] == -1 ) {
1.36 + return i;
1.37 + }
1.38 + }
1.39 + return -1;
1.40 }
1.41
1.42 void dcload_syscall( uint32_t syscall_id )
1.43 {
1.44 uint32_t syscall = sh4r.r[4];
1.45 + int fd;
1.46 switch( sh4r.r[4] ) {
1.47 case SYS_READ:
1.48 - if( sh4r.r[5] == 0 ) {
1.49 + fd = sh4r.r[5];
1.50 + if( fd < 0 || fd >= MAX_OPEN_FDS || open_fds[fd] == -1 ) {
1.51 + sh4r.r[0] = -1;
1.52 + } else {
1.53 char *buf = mem_get_region( sh4r.r[6] );
1.54 int length = sh4r.r[7];
1.55 - sh4r.r[0] = read( 0, buf, length );
1.56 + sh4r.r[0] = read( open_fds[fd], buf, length );
1.57 + }
1.58 + break;
1.59 + case SYS_WRITE:
1.60 + fd = sh4r.r[5];
1.61 + if( fd < 0 || fd >= MAX_OPEN_FDS || open_fds[fd] == -1 ) {
1.62 + sh4r.r[0] = -1;
1.63 } else {
1.64 + char *buf = mem_get_region( sh4r.r[6] );
1.65 + int length = sh4r.r[7];
1.66 + sh4r.r[0] = write( open_fds[fd], buf, length );
1.67 + }
1.68 + break;
1.69 + case SYS_LSEEK:
1.70 + fd = sh4r.r[5];
1.71 + if( fd < 0 || fd >= MAX_OPEN_FDS || open_fds[fd] == -1 ) {
1.72 + sh4r.r[0] = -1;
1.73 + } else {
1.74 + sh4r.r[0] = lseek( open_fds[fd], sh4r.r[6], sh4r.r[7] );
1.75 + }
1.76 + break;
1.77 +
1.78 +/* Secure access only */
1.79 + case SYS_OPEN:
1.80 + if( dcload_allow_unsafe ) {
1.81 + fd = dcload_alloc_fd();
1.82 + if( fd == -1 ) {
1.83 + sh4r.r[0] = -1;
1.84 + } else {
1.85 + char *filename = mem_get_region( sh4r.r[5] );
1.86 + int realfd = open( filename, sh4r.r[6] );
1.87 + open_fds[fd] = realfd;
1.88 + sh4r.r[0] = realfd;
1.89 + }
1.90 + } else {
1.91 + ERROR( "Denying access to local filesystem" );
1.92 sh4r.r[0] = -1;
1.93 }
1.94 break;
1.95 - case SYS_WRITE:
1.96 - if( sh4r.r[5] == 1 || sh4r.r[5] == 2 ) {
1.97 - char *buf = mem_get_region( sh4r.r[6] );
1.98 - int length = sh4r.r[7];
1.99 - sh4r.r[0] = write( sh4r.r[5], buf, length );
1.100 - } else {
1.101 - sh4r.r[0] = -1;
1.102 + case SYS_CLOSE:
1.103 + if( dcload_allow_unsafe ) {
1.104 + fd = sh4r.r[5];
1.105 + if( fd < 0 || fd >= MAX_OPEN_FDS || open_fds[fd] == -1 ) {
1.106 + sh4r.r[0] = -1;
1.107 + } else {
1.108 + if( open_fds[fd] > 2 ) {
1.109 + sh4r.r[0] = close( open_fds[fd] );
1.110 + } else {
1.111 + /* Don't actually close real fds 0-2 */
1.112 + sh4r.r[0] = 0;
1.113 + }
1.114 + open_fds[fd] = -1;
1.115 + }
1.116 }
1.117 break;
1.118 case SYS_EXIT:
1.119 - if( dcload_allow_exit )
1.120 + if( dcload_allow_unsafe ) {
1.121 exit( sh4r.r[5] );
1.122 - else
1.123 + } else {
1.124 dreamcast_stop();
1.125 + }
1.126 default:
1.127 sh4r.r[0] = -1;
1.128 }
1.129 @@ -90,6 +154,10 @@
1.130
1.131 void dcload_install()
1.132 {
1.133 + memset( &open_fds, -1, sizeof(open_fds) );
1.134 + open_fds[0] = 0;
1.135 + open_fds[1] = 1;
1.136 + open_fds[2] = 2;
1.137 syscall_add_hook_vector( 0xF0, SYSCALL_ADDR, dcload_syscall );
1.138 sh4_write_long( SYS_MAGIC_ADDR, SYS_MAGIC );
1.139 }
2.1 --- a/src/main.c Sun Aug 06 09:43:03 2006 +0000
2.2 +++ b/src/main.c Mon Aug 07 13:18:16 2006 +0000
2.3 @@ -1,5 +1,5 @@
2.4 /**
2.5 - * $Id: main.c,v 1.19 2006-07-06 08:47:33 nkeynes Exp $
2.6 + * $Id: main.c,v 1.20 2006-08-07 13:18:16 nkeynes Exp $
2.7 *
2.8 * Main program, initializes dreamcast and gui, then passes control off to
2.9 * the gtk main loop (currently).
2.10 @@ -35,7 +35,7 @@
2.11
2.12 #define S3M_PLAYER "s3mplay.bin"
2.13
2.14 -char *option_list = "a:s:A:V:pqhbd:c:";
2.15 +char *option_list = "a:s:A:V:puhbd:c:";
2.16 struct option longopts[1] = { { NULL, 0, 0, 0 } };
2.17 char *aica_program = NULL;
2.18 char *s3m_file = NULL;
2.19 @@ -87,8 +87,8 @@
2.20 case 'p': /* Start immediately */
2.21 start_immediately = TRUE;
2.22 break;
2.23 - case 'q': /* Quit on DC program exit */
2.24 - dcload_set_allow_exit(TRUE);
2.25 + case 'u': /* Allow unsafe dcload syscalls */
2.26 + dcload_set_allow_unsafe(TRUE);
2.27 break;
2.28 case 'b': /* No BIOS */
2.29 without_bios = TRUE;
3.1 --- a/src/syscall.h Sun Aug 06 09:43:03 2006 +0000
3.2 +++ b/src/syscall.h Mon Aug 07 13:18:16 2006 +0000
3.3 @@ -1,5 +1,5 @@
3.4 /**
3.5 - * $Id: syscall.h,v 1.2 2006-07-06 08:47:33 nkeynes Exp $
3.6 + * $Id: syscall.h,v 1.3 2006-08-07 13:18:16 nkeynes Exp $
3.7 *
3.8 * Generic syscall support - ability to add hooks into SH4 code to call out
3.9 * to the emu.
3.10 @@ -69,7 +69,7 @@
3.11 * Set the flag that indicates whether the dcload exit() syscall will be
3.12 * honoured by exiting the VM.
3.13 */
3.14 -void dcload_set_allow_exit( gboolean allow );
3.15 +void dcload_set_allow_unsafe( gboolean allow );
3.16
3.17 #ifdef __cplusplus
3.18 }
.