1:
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:
16: abi_long memcpy_to_target(abi_ulong dest, const void *src,
17: unsigned long len)
18: {
19: void *host_ptr;
20:
21: host_ptr = lock_user(VERIFY_WRITE, dest, len, 0);
22: if (!host_ptr)
23: return -TARGET_EFAULT;
24: memcpy(host_ptr, src, len);
25: unlock_user(host_ptr, dest, 1);
26: return 0;
27: }
28:
29: static int in_group_p(gid_t g)
30: {
31:
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)) {
68: return(-EACCES);
69: }
70: if(!(mode & 0111)) {
71: return(-EACCES);
72: }
73:
74: bprm->e_uid = geteuid();
75: bprm->e_gid = getegid();
76: id_change = 0;
77:
78:
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:
87:
88:
89:
90:
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:
108: }
109: else {
110: return(retval);
111: }
112: }
113:
114:
115: abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
116: abi_ulong stringp, int push_ptr)
117: {
118: int n = sizeof(abi_ulong);
119: abi_ulong envp;
120: abi_ulong argv;
121:
122: sp -= (envc + 1) * n;
123: envp = sp;
124: sp -= (argc + 1) * n;
125: argv = sp;
126: if (push_ptr) {
127:
128: sp -= n;
129: put_user_ual(envp, sp);
130: sp -= n;
131: put_user_ual(argv, sp);
132: }
133: sp -= n;
134:
135: put_user_ual(argc, sp);
136:
137: while (argc-- > 0) {
138:
139: put_user_ual(stringp, argv);
140: argv += n;
141: stringp += target_strlen(stringp) + 1;
142: }
143:
144: put_user_ual(0, argv);
145: while (envc-- > 0) {
146:
147: put_user_ual(stringp, envp);
148: envp += n;
149: stringp += target_strlen(stringp) + 1;
150: }
151:
152: put_user_ual(0, envp);
153:
154: return sp;
155: }
156:
157: int loader_exec(const char * filename, char ** argv, char ** envp,
158: struct target_pt_regs * regs, struct image_info *infop)
159: {
160: struct linux_binprm bprm;
161: int retval;
162: int i;
163:
164: bprm.p = TARGET_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int);
165: for (i=0 ; i<MAX_ARG_PAGES ; i++)
166: bprm.page[i] = 0;
167: retval = open(filename, O_RDONLY);
168: if (retval < 0)
169: return retval;
170: bprm.fd = retval;
171: bprm.filename = (char *)filename;
172: bprm.argc = count(argv);
173: bprm.argv = argv;
174: bprm.envc = count(envp);
175: bprm.envp = envp;
176:
177: retval = prepare_binprm(&bprm);
178:
179: infop->host_argv = argv;
180:
181: if(retval>=0) {
182: if (bprm.buf[0] == 0x7f
183: && bprm.buf[1] == 'E'
184: && bprm.buf[2] == 'L'
185: && bprm.buf[3] == 'F') {
186: #ifndef TARGET_HAS_ELFLOAD32
187: retval = load_elf_binary(&bprm,regs,infop);
188: #else
189: retval = load_elf_binary_multi(&bprm, regs, infop);
190: #endif
191: #if defined(TARGET_HAS_BFLT)
192: } else if (bprm.buf[0] == 'b'
193: && bprm.buf[1] == 'F'
194: && bprm.buf[2] == 'L'
195: && bprm.buf[3] == 'T') {
196: retval = load_flt_binary(&bprm,regs,infop);
197: #endif
198: } else {
199: fprintf(stderr, "Unknown binary format\n");
200: return -1;
201: }
202: }
203:
204: if(retval>=0) {
205:
206: do_init_thread(regs, infop);
207: return retval;
208: }
209:
210:
211: for (i=0 ; i<MAX_ARG_PAGES ; i++) {
212: free(bprm.page[i]);
213: }
214: return(retval);
215: }