1.1 --- a/src/dcload.c Thu Jul 06 22:44:39 2006 +0000
1.2 +++ b/src/dcload.c Fri Dec 15 10:17:08 2006 +0000
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.8 * DC-load syscall implementation.
1.10 @@ -48,40 +48,104 @@
1.11 #define SYS_MAGIC_ADDR 0x8c004004
1.12 #define SYSCALL_ADDR 0x8c004008
1.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.20 - dcload_allow_exit = allow;
1.21 + dcload_allow_unsafe = allow;
1.24 +#define MAX_OPEN_FDS 16
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.29 +int open_fds[MAX_OPEN_FDS];
1.31 +int dcload_alloc_fd()
1.34 + for( i=0; i<MAX_OPEN_FDS; i++ ) {
1.35 + if( open_fds[i] == -1 ) {
1.42 void dcload_syscall( uint32_t syscall_id )
1.44 uint32_t syscall = sh4r.r[4];
1.46 switch( sh4r.r[4] ) {
1.48 - if( sh4r.r[5] == 0 ) {
1.50 + if( fd < 0 || fd >= MAX_OPEN_FDS || open_fds[fd] == -1 ) {
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.61 + if( fd < 0 || fd >= MAX_OPEN_FDS || open_fds[fd] == -1 ) {
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.71 + if( fd < 0 || fd >= MAX_OPEN_FDS || open_fds[fd] == -1 ) {
1.74 + sh4r.r[0] = lseek( open_fds[fd], sh4r.r[6], sh4r.r[7] );
1.78 +/* Secure access only */
1.80 + if( dcload_allow_unsafe ) {
1.81 + fd = dcload_alloc_fd();
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.91 + ERROR( "Denying access to local filesystem" );
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.103 + if( dcload_allow_unsafe ) {
1.105 + if( fd < 0 || fd >= MAX_OPEN_FDS || open_fds[fd] == -1 ) {
1.108 + if( open_fds[fd] > 2 ) {
1.109 + sh4r.r[0] = close( open_fds[fd] );
1.111 + /* Don't actually close real fds 0-2 */
1.114 + open_fds[fd] = -1;
1.119 - if( dcload_allow_exit )
1.120 + if( dcload_allow_unsafe ) {
1.129 @@ -90,6 +154,10 @@
1.131 void dcload_install()
1.133 + memset( &open_fds, -1, sizeof(open_fds) );
1.137 syscall_add_hook_vector( 0xF0, SYSCALL_ADDR, dcload_syscall );
1.138 sh4_write_long( SYS_MAGIC_ADDR, SYS_MAGIC );