1 /* Code for loading BSD executables. Mostly linux kernel code. */ 2 3 #include "qemu/osdep.h" 4 5 #include "qemu.h" 6 7 #define TARGET_NGROUPS 32 8 9 /* ??? This should really be somewhere else. */ 10 abi_long memcpy_to_target(abi_ulong dest, const void *src, 11 unsigned long len) 12 { 13 void *host_ptr; 14 15 host_ptr = lock_user(VERIFY_WRITE, dest, len, 0); 16 if (!host_ptr) 17 return -TARGET_EFAULT; 18 memcpy(host_ptr, src, len); 19 unlock_user(host_ptr, dest, 1); 20 return 0; 21 } 22 23 static int count(char ** vec) 24 { 25 int i; 26 27 for(i = 0; *vec; i++) { 28 vec++; 29 } 30 31 return(i); 32 } 33 34 static int prepare_binprm(struct linux_binprm *bprm) 35 { 36 struct stat st; 37 int mode; 38 int retval; 39 40 if(fstat(bprm->fd, &st) < 0) { 41 return(-errno); 42 } 43 44 mode = st.st_mode; 45 if(!S_ISREG(mode)) { /* Must be regular file */ 46 return(-EACCES); 47 } 48 if(!(mode & 0111)) { /* Must have at least one execute bit set */ 49 return(-EACCES); 50 } 51 52 bprm->e_uid = geteuid(); 53 bprm->e_gid = getegid(); 54 55 /* Set-uid? */ 56 if(mode & S_ISUID) { 57 bprm->e_uid = st.st_uid; 58 } 59 60 /* Set-gid? */ 61 /* 62 * If setgid is set but no group execute bit then this 63 * is a candidate for mandatory locking, not a setgid 64 * executable. 65 */ 66 if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { 67 bprm->e_gid = st.st_gid; 68 } 69 70 memset(bprm->buf, 0, sizeof(bprm->buf)); 71 retval = lseek(bprm->fd, 0L, SEEK_SET); 72 if(retval >= 0) { 73 retval = read(bprm->fd, bprm->buf, 128); 74 } 75 if(retval < 0) { 76 perror("prepare_binprm"); 77 exit(-1); 78 /* return(-errno); */ 79 } 80 else { 81 return(retval); 82 } 83 } 84 85 /* Construct the envp and argv tables on the target stack. */ 86 abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp, 87 abi_ulong stringp, int push_ptr) 88 { 89 int n = sizeof(abi_ulong); 90 abi_ulong envp; 91 abi_ulong argv; 92 93 sp -= (envc + 1) * n; 94 envp = sp; 95 sp -= (argc + 1) * n; 96 argv = sp; 97 if (push_ptr) { 98 /* FIXME - handle put_user() failures */ 99 sp -= n; 100 put_user_ual(envp, sp); 101 sp -= n; 102 put_user_ual(argv, sp); 103 } 104 sp -= n; 105 /* FIXME - handle put_user() failures */ 106 put_user_ual(argc, sp); 107 108 while (argc-- > 0) { 109 /* FIXME - handle put_user() failures */ 110 put_user_ual(stringp, argv); 111 argv += n; 112 stringp += target_strlen(stringp) + 1; 113 } 114 /* FIXME - handle put_user() failures */ 115 put_user_ual(0, argv); 116 while (envc-- > 0) { 117 /* FIXME - handle put_user() failures */ 118 put_user_ual(stringp, envp); 119 envp += n; 120 stringp += target_strlen(stringp) + 1; 121 } 122 /* FIXME - handle put_user() failures */ 123 put_user_ual(0, envp); 124 125 return sp; 126 } 127 128 int loader_exec(const char * filename, char ** argv, char ** envp, 129 struct target_pt_regs * regs, struct image_info *infop) 130 { 131 struct linux_binprm bprm; 132 int retval; 133 int i; 134 135 bprm.p = TARGET_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int); 136 for (i=0 ; i<MAX_ARG_PAGES ; i++) /* clear page-table */ 137 bprm.page[i] = NULL; 138 retval = open(filename, O_RDONLY); 139 if (retval < 0) 140 return retval; 141 bprm.fd = retval; 142 bprm.filename = (char *)filename; 143 bprm.argc = count(argv); 144 bprm.argv = argv; 145 bprm.envc = count(envp); 146 bprm.envp = envp; 147 148 retval = prepare_binprm(&bprm); 149 150 if(retval>=0) { 151 if (bprm.buf[0] == 0x7f 152 && bprm.buf[1] == 'E' 153 && bprm.buf[2] == 'L' 154 && bprm.buf[3] == 'F') { 155 retval = load_elf_binary(&bprm,regs,infop); 156 } else { 157 fprintf(stderr, "Unknown binary format\n"); 158 return -1; 159 } 160 } 161 162 if(retval>=0) { 163 /* success. Initialize important registers */ 164 do_init_thread(regs, infop); 165 return retval; 166 } 167 168 /* Something went wrong, return the inode and free the argument pages*/ 169 for (i=0 ; i<MAX_ARG_PAGES ; i++) { 170 g_free(bprm.page[i]); 171 } 172 return(retval); 173 } 174