1 /* Code for loading Linux executables. Mostly linux kernel code. */
15 /* ??? This should really be somewhere else. */
16 void memcpy_to_target(target_ulong dest, const void *src,
21 host_ptr = lock_user(dest, len, 0);
22 memcpy(host_ptr, src, len);
23 unlock_user(host_ptr, dest, 1);
26 static int in_group_p(gid_t g)
28 /* return TRUE if we're in the specified group, FALSE otherwise */
31 gid_t grouplist[NGROUPS];
33 ngroup = getgroups(NGROUPS, grouplist);
34 for(i = 0; i < ngroup; i++) {
35 if(grouplist[i] == g) {
42 static int count(char ** vec)
46 for(i = 0; *vec; i++) {
53 static int prepare_binprm(struct linux_binprm *bprm)
57 int retval, id_change;
59 if(fstat(bprm->fd, &st) < 0) {
64 if(!S_ISREG(mode)) { /* Must be regular file */
67 if(!(mode & 0111)) { /* Must have at least one execute bit set */
71 bprm->e_uid = geteuid();
72 bprm->e_gid = getegid();
77 bprm->e_uid = st.st_uid;
78 if(bprm->e_uid != geteuid()) {
85 * If setgid is set but no group execute bit then this
86 * is a candidate for mandatory locking, not a setgid
89 if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
90 bprm->e_gid = st.st_gid;
91 if (!in_group_p(bprm->e_gid)) {
96 memset(bprm->buf, 0, sizeof(bprm->buf));
97 retval = lseek(bprm->fd, 0L, SEEK_SET);
99 retval = read(bprm->fd, bprm->buf, 128);
102 perror("prepare_binprm");
104 /* return(-errno); */
111 /* Construct the envp and argv tables on the target stack. */
112 target_ulong loader_build_argptr(int envc, int argc, target_ulong sp,
113 target_ulong stringp, int push_ptr)
115 int n = sizeof(target_ulong);
119 sp -= (envc + 1) * n;
121 sp -= (argc + 1) * n;
124 sp -= n; tputl(sp, envp);
125 sp -= n; tputl(sp, argv);
127 sp -= n; tputl(sp, argc);
130 tputl(argv, stringp); argv += n;
131 stringp += target_strlen(stringp) + 1;
135 tputl(envp, stringp); envp += n;
136 stringp += target_strlen(stringp) + 1;
143 int loader_exec(const char * filename, char ** argv, char ** envp,
144 struct target_pt_regs * regs, struct image_info *infop)
146 struct linux_binprm bprm;
150 bprm.p = TARGET_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int);
151 for (i=0 ; i<MAX_ARG_PAGES ; i++) /* clear page-table */
153 retval = open(filename, O_RDONLY);
157 bprm.filename = (char *)filename;
158 bprm.argc = count(argv);
160 bprm.envc = count(envp);
163 retval = prepare_binprm(&bprm);
165 infop->host_argv = argv;
168 if (bprm.buf[0] == 0x7f
169 && bprm.buf[1] == 'E'
170 && bprm.buf[2] == 'L'
171 && bprm.buf[3] == 'F') {
172 retval = load_elf_binary(&bprm,regs,infop);
173 #if defined(TARGET_HAS_BFLT)
174 } else if (bprm.buf[0] == 'b'
175 && bprm.buf[1] == 'F'
176 && bprm.buf[2] == 'L'
177 && bprm.buf[3] == 'T') {
178 retval = load_flt_binary(&bprm,regs,infop);
181 fprintf(stderr, "Unknown binary format\n");
187 /* success. Initialize important registers */
188 do_init_thread(regs, infop);
192 /* Something went wrong, return the inode and free the argument pages*/
193 for (i=0 ; i<MAX_ARG_PAGES ; i++) {