|
|
1.1.1.3 ! root 1: /* Code for loading Linux executables. Mostly linux kernel code. */ 1.1 root 2: 3: #include <sys/types.h> 4: #include <sys/stat.h> 5: #include <fcntl.h> 6: #include <errno.h> 7: #include <unistd.h> 8: #include <stdio.h> 9: #include <stdlib.h> 10: 11: #include "qemu.h" 12: 13: #define NGROUPS 32 14: 15: /* ??? This should really be somewhere else. */ 1.1.1.3 ! root 16: abi_long memcpy_to_target(abi_ulong dest, const void *src, ! 17: unsigned long len) 1.1 root 18: { 19: void *host_ptr; 20: 1.1.1.3 ! root 21: host_ptr = lock_user(VERIFY_WRITE, dest, len, 0); ! 22: if (!host_ptr) ! 23: return -TARGET_EFAULT; 1.1 root 24: memcpy(host_ptr, src, len); 25: unlock_user(host_ptr, dest, 1); 1.1.1.3 ! root 26: return 0; 1.1 root 27: } 28: 29: static int in_group_p(gid_t g) 30: { 31: /* return TRUE if we're in the specified group, FALSE otherwise */ 32: int ngroup; 33: int i; 34: gid_t grouplist[NGROUPS]; 35: 36: ngroup = getgroups(NGROUPS, grouplist); 37: for(i = 0; i < ngroup; i++) { 38: if(grouplist[i] == g) { 39: return 1; 40: } 41: } 42: return 0; 43: } 44: 45: static int count(char ** vec) 46: { 47: int i; 48: 49: for(i = 0; *vec; i++) { 50: vec++; 51: } 52: 53: return(i); 54: } 55: 56: static int prepare_binprm(struct linux_binprm *bprm) 57: { 58: struct stat st; 59: int mode; 60: int retval, id_change; 61: 62: if(fstat(bprm->fd, &st) < 0) { 63: return(-errno); 64: } 65: 66: mode = st.st_mode; 67: if(!S_ISREG(mode)) { /* Must be regular file */ 68: return(-EACCES); 69: } 70: if(!(mode & 0111)) { /* Must have at least one execute bit set */ 71: return(-EACCES); 72: } 73: 74: bprm->e_uid = geteuid(); 75: bprm->e_gid = getegid(); 76: id_change = 0; 77: 78: /* Set-uid? */ 79: if(mode & S_ISUID) { 80: bprm->e_uid = st.st_uid; 81: if(bprm->e_uid != geteuid()) { 82: id_change = 1; 83: } 84: } 85: 86: /* Set-gid? */ 87: /* 88: * If setgid is set but no group execute bit then this 89: * is a candidate for mandatory locking, not a setgid 90: * executable. 91: */ 92: if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { 93: bprm->e_gid = st.st_gid; 94: if (!in_group_p(bprm->e_gid)) { 95: id_change = 1; 96: } 97: } 98: 99: memset(bprm->buf, 0, sizeof(bprm->buf)); 100: retval = lseek(bprm->fd, 0L, SEEK_SET); 101: if(retval >= 0) { 102: retval = read(bprm->fd, bprm->buf, 128); 103: } 104: if(retval < 0) { 105: perror("prepare_binprm"); 106: exit(-1); 107: /* return(-errno); */ 108: } 109: else { 110: return(retval); 111: } 112: } 113: 114: /* Construct the envp and argv tables on the target stack. */ 1.1.1.3 ! root 115: abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp, ! 116: abi_ulong stringp, int push_ptr) 1.1 root 117: { 1.1.1.3 ! root 118: int n = sizeof(abi_ulong); ! 119: abi_ulong envp; ! 120: abi_ulong argv; 1.1 root 121: 122: sp -= (envc + 1) * n; 123: envp = sp; 124: sp -= (argc + 1) * n; 125: argv = sp; 126: if (push_ptr) { 1.1.1.3 ! root 127: /* FIXME - handle put_user() failures */ ! 128: sp -= n; ! 129: put_user_ual(envp, sp); ! 130: sp -= n; ! 131: put_user_ual(argv, sp); ! 132: } ! 133: sp -= n; ! 134: /* FIXME - handle put_user() failures */ ! 135: put_user_ual(argc, sp); 1.1 root 136: 137: while (argc-- > 0) { 1.1.1.3 ! root 138: /* FIXME - handle put_user() failures */ ! 139: put_user_ual(stringp, argv); ! 140: argv += n; 1.1 root 141: stringp += target_strlen(stringp) + 1; 142: } 1.1.1.3 ! root 143: /* FIXME - handle put_user() failures */ ! 144: put_user_ual(0, argv); 1.1 root 145: while (envc-- > 0) { 1.1.1.3 ! root 146: /* FIXME - handle put_user() failures */ ! 147: put_user_ual(stringp, envp); ! 148: envp += n; 1.1 root 149: stringp += target_strlen(stringp) + 1; 150: } 1.1.1.3 ! root 151: /* FIXME - handle put_user() failures */ ! 152: put_user_ual(0, envp); 1.1 root 153: 154: return sp; 155: } 156: 1.1.1.3 ! root 157: int loader_exec(const char * filename, char ** argv, char ** envp, 1.1 root 158: struct target_pt_regs * regs, struct image_info *infop) 159: { 160: struct linux_binprm bprm; 161: int retval; 162: int i; 163: 164: bprm.p = TARGET_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int); 165: for (i=0 ; i<MAX_ARG_PAGES ; i++) /* clear page-table */ 166: bprm.page[i] = 0; 167: retval = open(filename, O_RDONLY); 168: if (retval < 0) 169: return retval; 170: bprm.fd = retval; 171: bprm.filename = (char *)filename; 172: bprm.argc = count(argv); 173: bprm.argv = argv; 174: bprm.envc = count(envp); 175: bprm.envp = envp; 176: 177: retval = prepare_binprm(&bprm); 178: 1.1.1.2 root 179: infop->host_argv = argv; 180: 1.1 root 181: if(retval>=0) { 182: if (bprm.buf[0] == 0x7f 183: && bprm.buf[1] == 'E' 184: && bprm.buf[2] == 'L' 185: && bprm.buf[3] == 'F') { 1.1.1.3 ! root 186: #ifndef TARGET_HAS_ELFLOAD32 1.1 root 187: retval = load_elf_binary(&bprm,regs,infop); 1.1.1.3 ! root 188: #else ! 189: retval = load_elf_binary_multi(&bprm, regs, infop); ! 190: #endif 1.1 root 191: #if defined(TARGET_HAS_BFLT) 192: } else if (bprm.buf[0] == 'b' 193: && bprm.buf[1] == 'F' 194: && bprm.buf[2] == 'L' 195: && bprm.buf[3] == 'T') { 196: retval = load_flt_binary(&bprm,regs,infop); 197: #endif 198: } else { 199: fprintf(stderr, "Unknown binary format\n"); 200: return -1; 201: } 202: } 1.1.1.3 ! root 203: 1.1 root 204: if(retval>=0) { 205: /* success. Initialize important registers */ 206: do_init_thread(regs, infop); 207: return retval; 208: } 209: 210: /* Something went wrong, return the inode and free the argument pages*/ 211: for (i=0 ; i<MAX_ARG_PAGES ; i++) { 212: free(bprm.page[i]); 213: } 214: return(retval); 215: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.