|
|
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.4 ! root 118: TaskState *ts = (TaskState *)thread_env->opaque;
1.1.1.3 root 119: int n = sizeof(abi_ulong);
120: abi_ulong envp;
121: abi_ulong argv;
1.1 root 122:
123: sp -= (envc + 1) * n;
124: envp = sp;
125: sp -= (argc + 1) * n;
126: argv = sp;
127: if (push_ptr) {
1.1.1.3 root 128: /* FIXME - handle put_user() failures */
129: sp -= n;
130: put_user_ual(envp, sp);
131: sp -= n;
132: put_user_ual(argv, sp);
133: }
134: sp -= n;
135: /* FIXME - handle put_user() failures */
136: put_user_ual(argc, sp);
1.1.1.4 ! root 137: ts->info->arg_start = stringp;
1.1 root 138: while (argc-- > 0) {
1.1.1.3 root 139: /* FIXME - handle put_user() failures */
140: put_user_ual(stringp, argv);
141: argv += n;
1.1 root 142: stringp += target_strlen(stringp) + 1;
143: }
1.1.1.4 ! root 144: ts->info->arg_end = stringp;
1.1.1.3 root 145: /* FIXME - handle put_user() failures */
146: put_user_ual(0, argv);
1.1 root 147: while (envc-- > 0) {
1.1.1.3 root 148: /* FIXME - handle put_user() failures */
149: put_user_ual(stringp, envp);
150: envp += n;
1.1 root 151: stringp += target_strlen(stringp) + 1;
152: }
1.1.1.3 root 153: /* FIXME - handle put_user() failures */
154: put_user_ual(0, envp);
1.1 root 155:
156: return sp;
157: }
158:
1.1.1.3 root 159: int loader_exec(const char * filename, char ** argv, char ** envp,
1.1.1.4 ! root 160: struct target_pt_regs * regs, struct image_info *infop,
! 161: struct linux_binprm *bprm)
1.1 root 162: {
163: int retval;
164: int i;
165:
1.1.1.4 ! root 166: bprm->p = TARGET_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int);
1.1 root 167: for (i=0 ; i<MAX_ARG_PAGES ; i++) /* clear page-table */
1.1.1.4 ! root 168: bprm->page[i] = NULL;
1.1 root 169: retval = open(filename, O_RDONLY);
170: if (retval < 0)
171: return retval;
1.1.1.4 ! root 172: bprm->fd = retval;
! 173: bprm->filename = (char *)filename;
! 174: bprm->argc = count(argv);
! 175: bprm->argv = argv;
! 176: bprm->envc = count(envp);
! 177: bprm->envp = envp;
1.1 root 178:
1.1.1.4 ! root 179: retval = prepare_binprm(bprm);
1.1 root 180:
1.1.1.2 root 181: infop->host_argv = argv;
182:
1.1 root 183: if(retval>=0) {
1.1.1.4 ! root 184: if (bprm->buf[0] == 0x7f
! 185: && bprm->buf[1] == 'E'
! 186: && bprm->buf[2] == 'L'
! 187: && bprm->buf[3] == 'F') {
1.1.1.3 root 188: #ifndef TARGET_HAS_ELFLOAD32
1.1.1.4 ! root 189: retval = load_elf_binary(bprm,regs,infop);
1.1.1.3 root 190: #else
1.1.1.4 ! root 191: retval = load_elf_binary_multi(bprm, regs, infop);
1.1.1.3 root 192: #endif
1.1 root 193: #if defined(TARGET_HAS_BFLT)
1.1.1.4 ! root 194: } else if (bprm->buf[0] == 'b'
! 195: && bprm->buf[1] == 'F'
! 196: && bprm->buf[2] == 'L'
! 197: && bprm->buf[3] == 'T') {
! 198: retval = load_flt_binary(bprm,regs,infop);
1.1 root 199: #endif
200: } else {
201: fprintf(stderr, "Unknown binary format\n");
202: return -1;
203: }
204: }
1.1.1.3 root 205:
1.1 root 206: if(retval>=0) {
207: /* success. Initialize important registers */
208: do_init_thread(regs, infop);
209: return retval;
210: }
211:
212: /* Something went wrong, return the inode and free the argument pages*/
213: for (i=0 ; i<MAX_ARG_PAGES ; i++) {
1.1.1.4 ! root 214: free(bprm->page[i]);
1.1 root 215: }
216: return(retval);
217: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.