1 /* Code for loading Linux executables. Mostly linux kernel code. */ 2 3 #include "qemu/osdep.h" 4 #include "qemu.h" 5 #include "user-internals.h" 6 #include "user-mmap.h" 7 #include "loader.h" 8 #include "qapi/error.h" 9 10 #define NGROUPS 32 11 12 /* ??? This should really be somewhere else. */ 13 abi_long memcpy_to_target(abi_ulong dest, const void *src, unsigned long len) 14 { 15 void *host_ptr; 16 17 host_ptr = lock_user(VERIFY_WRITE, dest, len, 0); 18 if (!host_ptr) { 19 return -TARGET_EFAULT; 20 } 21 memcpy(host_ptr, src, len); 22 unlock_user(host_ptr, dest, 1); 23 return 0; 24 } 25 26 static int count(char **vec) 27 { 28 int i; 29 30 for (i = 0; *vec; i++) { 31 vec++; 32 } 33 return i; 34 } 35 36 static int prepare_binprm(struct linux_binprm *bprm) 37 { 38 struct stat st; 39 int mode; 40 int retval; 41 42 if (fstat(bprm->fd, &st) < 0) { 43 return -errno; 44 } 45 46 mode = st.st_mode; 47 if (!S_ISREG(mode)) { /* Must be regular file */ 48 return -EACCES; 49 } 50 if (!(mode & 0111)) { /* Must have at least one execute bit set */ 51 return -EACCES; 52 } 53 54 bprm->e_uid = geteuid(); 55 bprm->e_gid = getegid(); 56 57 /* Set-uid? */ 58 if (mode & S_ISUID) { 59 bprm->e_uid = st.st_uid; 60 } 61 62 /* Set-gid? */ 63 /* 64 * If setgid is set but no group execute bit then this 65 * is a candidate for mandatory locking, not a setgid 66 * executable. 67 */ 68 if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { 69 bprm->e_gid = st.st_gid; 70 } 71 72 retval = read(bprm->fd, bprm->buf, BPRM_BUF_SIZE); 73 if (retval < 0) { 74 perror("prepare_binprm"); 75 exit(-1); 76 } 77 if (retval < BPRM_BUF_SIZE) { 78 /* Make sure the rest of the loader won't read garbage. */ 79 memset(bprm->buf + retval, 0, BPRM_BUF_SIZE - retval); 80 } 81 82 bprm->src.cache = bprm->buf; 83 bprm->src.cache_size = retval; 84 85 return retval; 86 } 87 88 /* Construct the envp and argv tables on the target stack. */ 89 abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp, 90 abi_ulong stringp, int push_ptr) 91 { 92 TaskState *ts = (TaskState *)thread_cpu->opaque; 93 int n = sizeof(abi_ulong); 94 abi_ulong envp; 95 abi_ulong argv; 96 97 sp -= (envc + 1) * n; 98 envp = sp; 99 sp -= (argc + 1) * n; 100 argv = sp; 101 ts->info->envp = envp; 102 ts->info->envc = envc; 103 ts->info->argv = argv; 104 ts->info->argc = argc; 105 106 if (push_ptr) { 107 /* FIXME - handle put_user() failures */ 108 sp -= n; 109 put_user_ual(envp, sp); 110 sp -= n; 111 put_user_ual(argv, sp); 112 } 113 114 sp -= n; 115 /* FIXME - handle put_user() failures */ 116 put_user_ual(argc, sp); 117 118 ts->info->arg_strings = stringp; 119 while (argc-- > 0) { 120 /* FIXME - handle put_user() failures */ 121 put_user_ual(stringp, argv); 122 argv += n; 123 stringp += target_strlen(stringp) + 1; 124 } 125 /* FIXME - handle put_user() failures */ 126 put_user_ual(0, argv); 127 128 ts->info->env_strings = stringp; 129 while (envc-- > 0) { 130 /* FIXME - handle put_user() failures */ 131 put_user_ual(stringp, envp); 132 envp += n; 133 stringp += target_strlen(stringp) + 1; 134 } 135 /* FIXME - handle put_user() failures */ 136 put_user_ual(0, envp); 137 138 return sp; 139 } 140 141 int loader_exec(int fdexec, const char *filename, char **argv, char **envp, 142 struct target_pt_regs *regs, struct image_info *infop, 143 struct linux_binprm *bprm) 144 { 145 int retval; 146 147 bprm->fd = fdexec; 148 bprm->src.fd = fdexec; 149 bprm->filename = (char *)filename; 150 bprm->argc = count(argv); 151 bprm->argv = argv; 152 bprm->envc = count(envp); 153 bprm->envp = envp; 154 155 retval = prepare_binprm(bprm); 156 157 if (retval < 4) { 158 return -ENOEXEC; 159 } 160 if (bprm->buf[0] == 0x7f 161 && bprm->buf[1] == 'E' 162 && bprm->buf[2] == 'L' 163 && bprm->buf[3] == 'F') { 164 retval = load_elf_binary(bprm, infop); 165 #if defined(TARGET_HAS_BFLT) 166 } else if (bprm->buf[0] == 'b' 167 && bprm->buf[1] == 'F' 168 && bprm->buf[2] == 'L' 169 && bprm->buf[3] == 'T') { 170 retval = load_flt_binary(bprm, infop); 171 #endif 172 } else { 173 return -ENOEXEC; 174 } 175 if (retval < 0) { 176 return retval; 177 } 178 179 /* Success. Initialize important registers. */ 180 do_init_thread(regs, infop); 181 return 0; 182 } 183 184 bool imgsrc_read(void *dst, off_t offset, size_t len, 185 const ImageSource *img, Error **errp) 186 { 187 ssize_t ret; 188 189 if (offset + len <= img->cache_size) { 190 memcpy(dst, img->cache + offset, len); 191 return true; 192 } 193 194 if (img->fd < 0) { 195 error_setg(errp, "read past end of buffer"); 196 return false; 197 } 198 199 ret = pread(img->fd, dst, len, offset); 200 if (ret == len) { 201 return true; 202 } 203 if (ret < 0) { 204 error_setg_errno(errp, errno, "Error reading file header"); 205 } else { 206 error_setg(errp, "Incomplete read of file header"); 207 } 208 return false; 209 } 210 211 void *imgsrc_read_alloc(off_t offset, size_t len, 212 const ImageSource *img, Error **errp) 213 { 214 void *alloc = g_malloc(len); 215 bool ok = imgsrc_read(alloc, offset, len, img, errp); 216 217 if (!ok) { 218 g_free(alloc); 219 alloc = NULL; 220 } 221 return alloc; 222 } 223 224 abi_long imgsrc_mmap(abi_ulong start, abi_ulong len, int prot, 225 int flags, const ImageSource *src, abi_ulong offset) 226 { 227 const int prot_write = PROT_READ | PROT_WRITE; 228 abi_long ret; 229 void *haddr; 230 231 assert(flags == (MAP_PRIVATE | MAP_FIXED)); 232 233 if (src->fd >= 0) { 234 return target_mmap(start, len, prot, flags, src->fd, offset); 235 } 236 237 /* 238 * This case is for the vdso; we don't expect bad images. 239 * The mmap may extend beyond the end of the image, especially 240 * to the end of the page. Zero fill. 241 */ 242 assert(offset < src->cache_size); 243 244 ret = target_mmap(start, len, prot_write, flags | MAP_ANON, -1, 0); 245 if (ret == -1) { 246 return ret; 247 } 248 249 haddr = lock_user(VERIFY_WRITE, start, len, 0); 250 assert(haddr != NULL); 251 if (offset + len <= src->cache_size) { 252 memcpy(haddr, src->cache + offset, len); 253 } else { 254 size_t rest = src->cache_size - offset; 255 memcpy(haddr, src->cache + offset, rest); 256 memset(haddr + rest, 0, len - rest); 257 } 258 unlock_user(haddr, start, len); 259 260 if (prot != prot_write) { 261 target_mprotect(start, len, prot); 262 } 263 264 return ret; 265 } 266