revision 209:ff67a7b9aa17
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 209:ff67a7b9aa17 |
parent | 208:ad290228eea1 |
child | 210:c356f597c896 |
author | nkeynes |
date | Mon Aug 07 13:18:16 2006 +0000 (14 years ago) |
Implement open/close dcload syscalls, change permission flag to "unsafe"
![]() | src/dcload.c | view | annotate | diff | log | |
![]() | src/main.c | view | annotate | diff | log | |
![]() | src/syscall.h | view | annotate | diff | log |
1.1 --- a/src/dcload.c Sun Aug 06 09:43:03 2006 +00001.2 +++ b/src/dcload.c Mon Aug 07 13:18:16 2006 +00001.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 0x8c0040041.12 #define SYSCALL_ADDR 0x8c0040081.14 -static gboolean dcload_allow_exit = FALSE;1.15 +static gboolean dcload_allow_unsafe = FALSE;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 161.25 +/**1.26 + * Mapping from emulator fd to real fd (so we can limit read/write1.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.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 - else1.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.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 +00002.2 +++ b/src/main.c Mon Aug 07 13:18:16 2006 +00002.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 to2.9 * the gtk main loop (currently).2.10 @@ -35,7 +35,7 @@2.12 #define S3M_PLAYER "s3mplay.bin"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 +00003.2 +++ b/src/syscall.h Mon Aug 07 13:18:16 2006 +00003.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 out3.9 * to the emu.3.10 @@ -69,7 +69,7 @@3.11 * Set the flag that indicates whether the dcload exit() syscall will be3.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.17 #ifdef __cplusplus3.18 }
.