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