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