]>
git.proxmox.com Git - qemu.git/blob - linux-user/linuxload.c
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
++) {