|
|
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:
1.1.1.7 ! root 99: retval = read(bprm->fd, bprm->buf, BPRM_BUF_SIZE);
! 100: if (retval < 0) {
1.1 root 101: perror("prepare_binprm");
102: exit(-1);
103: }
1.1.1.7 ! root 104: if (retval < BPRM_BUF_SIZE) {
! 105: /* Make sure the rest of the loader won't read garbage. */
! 106: memset(bprm->buf + retval, 0, BPRM_BUF_SIZE - retval);
1.1 root 107: }
1.1.1.7 ! root 108: return retval;
1.1 root 109: }
110:
111: /* Construct the envp and argv tables on the target stack. */
1.1.1.3 root 112: abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
113: abi_ulong stringp, int push_ptr)
1.1 root 114: {
1.1.1.4 root 115: TaskState *ts = (TaskState *)thread_env->opaque;
1.1.1.3 root 116: int n = sizeof(abi_ulong);
117: abi_ulong envp;
118: abi_ulong argv;
1.1 root 119:
120: sp -= (envc + 1) * n;
121: envp = sp;
122: sp -= (argc + 1) * n;
123: argv = sp;
124: if (push_ptr) {
1.1.1.3 root 125: /* FIXME - handle put_user() failures */
126: sp -= n;
127: put_user_ual(envp, sp);
128: sp -= n;
129: put_user_ual(argv, sp);
130: }
131: sp -= n;
132: /* FIXME - handle put_user() failures */
133: put_user_ual(argc, sp);
1.1.1.4 root 134: ts->info->arg_start = stringp;
1.1 root 135: while (argc-- > 0) {
1.1.1.3 root 136: /* FIXME - handle put_user() failures */
137: put_user_ual(stringp, argv);
138: argv += n;
1.1 root 139: stringp += target_strlen(stringp) + 1;
140: }
1.1.1.4 root 141: ts->info->arg_end = stringp;
1.1.1.3 root 142: /* FIXME - handle put_user() failures */
143: put_user_ual(0, argv);
1.1 root 144: while (envc-- > 0) {
1.1.1.3 root 145: /* FIXME - handle put_user() failures */
146: put_user_ual(stringp, envp);
147: envp += n;
1.1 root 148: stringp += target_strlen(stringp) + 1;
149: }
1.1.1.3 root 150: /* FIXME - handle put_user() failures */
151: put_user_ual(0, envp);
1.1 root 152:
153: return sp;
154: }
155:
1.1.1.3 root 156: int loader_exec(const char * filename, char ** argv, char ** envp,
1.1.1.4 root 157: struct target_pt_regs * regs, struct image_info *infop,
158: struct linux_binprm *bprm)
1.1 root 159: {
160: int retval;
161: int i;
162:
1.1.1.4 root 163: bprm->p = TARGET_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int);
1.1.1.7 ! root 164: memset(bprm->page, 0, sizeof(bprm->page));
1.1 root 165: retval = open(filename, O_RDONLY);
166: if (retval < 0)
167: return retval;
1.1.1.4 root 168: bprm->fd = retval;
169: bprm->filename = (char *)filename;
170: bprm->argc = count(argv);
171: bprm->argv = argv;
172: bprm->envc = count(envp);
173: bprm->envp = envp;
1.1 root 174:
1.1.1.4 root 175: retval = prepare_binprm(bprm);
1.1 root 176:
177: if(retval>=0) {
1.1.1.4 root 178: if (bprm->buf[0] == 0x7f
179: && bprm->buf[1] == 'E'
180: && bprm->buf[2] == 'L'
181: && bprm->buf[3] == 'F') {
1.1.1.6 root 182: retval = load_elf_binary(bprm, regs, infop);
1.1 root 183: #if defined(TARGET_HAS_BFLT)
1.1.1.4 root 184: } else if (bprm->buf[0] == 'b'
185: && bprm->buf[1] == 'F'
186: && bprm->buf[2] == 'L'
187: && bprm->buf[3] == 'T') {
188: retval = load_flt_binary(bprm,regs,infop);
1.1 root 189: #endif
190: } else {
191: fprintf(stderr, "Unknown binary format\n");
192: return -1;
193: }
194: }
1.1.1.3 root 195:
1.1 root 196: if(retval>=0) {
197: /* success. Initialize important registers */
198: do_init_thread(regs, infop);
199: return retval;
200: }
201:
202: /* Something went wrong, return the inode and free the argument pages*/
203: for (i=0 ; i<MAX_ARG_PAGES ; i++) {
1.1.1.4 root 204: free(bprm->page[i]);
1.1 root 205: }
206: return(retval);
207: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.