Increase LINUX32_ELF_AUX_ENTRIES to avoid overrun in linux32/. Also, add comments and KASSERTs to make sure people don't forget to increase XX_AUX_ENTRIES's when adding vectors. Reported by martin@ (CV), with suggestions from chs@. ok martin@ chs@diff -r1.20 -r1.21 src/sys/compat/linux/arch/amd64/linux_exec_machdep.c
(maxv)
--- src/sys/compat/linux/arch/amd64/linux_exec_machdep.c 2013/11/18 01:32:22 1.20
+++ src/sys/compat/linux/arch/amd64/linux_exec_machdep.c 2014/02/21 07:53:53 1.21
@@ -1,255 +1,250 @@ | @@ -1,255 +1,250 @@ | |||
1 | /* $NetBSD: linux_exec_machdep.c,v 1.20 2013/11/18 01:32:22 chs Exp $ */ | 1 | /* $NetBSD: linux_exec_machdep.c,v 1.21 2014/02/21 07:53:53 maxv Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2005 Emmanuel Dreyfus, all rights reserved | 4 | * Copyright (c) 2005 Emmanuel Dreyfus, all rights reserved | |
5 | * | 5 | * | |
6 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions | 7 | * modification, are permitted provided that the following conditions | |
8 | * are met: | 8 | * are met: | |
9 | * 1. Redistributions of source code must retain the above copyright | 9 | * 1. Redistributions of source code must retain the above copyright | |
10 | * notice, this list of conditions and the following disclaimer. | 10 | * notice, this list of conditions and the following disclaimer. | |
11 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright | |
12 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the | |
13 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. | |
14 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. All advertising materials mentioning features or use of this software | |
15 | * must display the following acknowledgement: | 15 | * must display the following acknowledgement: | |
16 | * This product includes software developed by Emmanuel Dreyfus | 16 | * This product includes software developed by Emmanuel Dreyfus | |
17 | * 4. The name of the author may not be used to endorse or promote | 17 | * 4. The name of the author may not be used to endorse or promote | |
18 | * products derived from this software without specific prior written | 18 | * products derived from this software without specific prior written | |
19 | * permission. | 19 | * permission. | |
20 | * | 20 | * | |
21 | * THIS SOFTWARE IS PROVIDED BY THE THE AUTHOR AND CONTRIBUTORS ``AS IS'' | 21 | * THIS SOFTWARE IS PROVIDED BY THE THE AUTHOR AND CONTRIBUTORS ``AS IS'' | |
22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | 22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | |
23 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 23 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
24 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS | 24 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS | |
25 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 25 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
31 | * POSSIBILITY OF SUCH DAMAGE. | 31 | * POSSIBILITY OF SUCH DAMAGE. | |
32 | */ | 32 | */ | |
33 | 33 | |||
34 | #include <sys/cdefs.h> | 34 | #include <sys/cdefs.h> | |
35 | __KERNEL_RCSID(0, "$NetBSD: linux_exec_machdep.c,v 1.20 2013/11/18 01:32:22 chs Exp $"); | 35 | __KERNEL_RCSID(0, "$NetBSD: linux_exec_machdep.c,v 1.21 2014/02/21 07:53:53 maxv Exp $"); | |
36 | 36 | |||
37 | #define ELFSIZE 64 | 37 | #define ELFSIZE 64 | |
38 | 38 | |||
39 | #include <sys/param.h> | 39 | #include <sys/param.h> | |
40 | #include <sys/systm.h> | 40 | #include <sys/systm.h> | |
41 | #include <sys/kernel.h> | 41 | #include <sys/kernel.h> | |
42 | #include <sys/resource.h> | 42 | #include <sys/resource.h> | |
43 | #include <sys/proc.h> | 43 | #include <sys/proc.h> | |
44 | #include <sys/conf.h> | 44 | #include <sys/conf.h> | |
45 | #include <sys/kmem.h> | 45 | #include <sys/kmem.h> | |
46 | #include <sys/exec_elf.h> | 46 | #include <sys/exec_elf.h> | |
47 | #include <sys/vnode.h> | 47 | #include <sys/vnode.h> | |
48 | #include <sys/lwp.h> | 48 | #include <sys/lwp.h> | |
49 | #include <sys/exec.h> | 49 | #include <sys/exec.h> | |
50 | #include <sys/stat.h> | 50 | #include <sys/stat.h> | |
51 | #include <sys/kauth.h> | 51 | #include <sys/kauth.h> | |
52 | 52 | |||
53 | #include <sys/cpu.h> | 53 | #include <sys/cpu.h> | |
54 | #include <machine/vmparam.h> | 54 | #include <machine/vmparam.h> | |
55 | #include <sys/syscallargs.h> | 55 | #include <sys/syscallargs.h> | |
56 | 56 | |||
57 | #include <uvm/uvm.h> | 57 | #include <uvm/uvm.h> | |
58 | 58 | |||
59 | #include <compat/linux/common/linux_types.h> | 59 | #include <compat/linux/common/linux_types.h> | |
60 | #include <compat/linux/common/linux_signal.h> | 60 | #include <compat/linux/common/linux_signal.h> | |
61 | #include <compat/linux/common/linux_machdep.h> | 61 | #include <compat/linux/common/linux_machdep.h> | |
62 | #include <compat/linux/common/linux_util.h> | 62 | #include <compat/linux/common/linux_util.h> | |
63 | #include <compat/linux/common/linux_ioctl.h> | 63 | #include <compat/linux/common/linux_ioctl.h> | |
64 | #include <compat/linux/common/linux_hdio.h> | 64 | #include <compat/linux/common/linux_hdio.h> | |
65 | #include <compat/linux/common/linux_exec.h> | 65 | #include <compat/linux/common/linux_exec.h> | |
66 | #include <compat/linux/common/linux_errno.h> | 66 | #include <compat/linux/common/linux_errno.h> | |
67 | #include <compat/linux/common/linux_prctl.h> | 67 | #include <compat/linux/common/linux_prctl.h> | |
68 | #include <compat/linux/common/linux_ipc.h> | 68 | #include <compat/linux/common/linux_ipc.h> | |
69 | #include <compat/linux/common/linux_sem.h> | 69 | #include <compat/linux/common/linux_sem.h> | |
70 | #include <compat/linux/linux_syscallargs.h> | 70 | #include <compat/linux/linux_syscallargs.h> | |
71 | 71 | |||
72 | int | 72 | int | |
73 | linux_exec_setup_stack(struct lwp *l, struct exec_package *epp) | 73 | linux_exec_setup_stack(struct lwp *l, struct exec_package *epp) | |
74 | { | 74 | { | |
75 | u_long max_stack_size; | 75 | u_long max_stack_size; | |
76 | u_long access_linear_min, access_size; | 76 | u_long access_linear_min, access_size; | |
77 | u_long noaccess_linear_min, noaccess_size; | 77 | u_long noaccess_linear_min, noaccess_size; | |
78 | 78 | |||
79 | #ifndef USRSTACK32 | 79 | #ifndef USRSTACK32 | |
80 | #define USRSTACK32 (0x00000000ffffffffL & ~PGOFSET) | 80 | #define USRSTACK32 (0x00000000ffffffffL & ~PGOFSET) | |
81 | #endif | 81 | #endif | |
82 | 82 | |||
83 | if (epp->ep_flags & EXEC_32) { | 83 | if (epp->ep_flags & EXEC_32) { | |
84 | epp->ep_minsaddr = USRSTACK32; | 84 | epp->ep_minsaddr = USRSTACK32; | |
85 | max_stack_size = MAXSSIZ; | 85 | max_stack_size = MAXSSIZ; | |
86 | if (epp->ep_minsaddr > LINUX_USRSTACK32) | 86 | if (epp->ep_minsaddr > LINUX_USRSTACK32) | |
87 | epp->ep_minsaddr = LINUX_USRSTACK32; | 87 | epp->ep_minsaddr = LINUX_USRSTACK32; | |
88 | } else { | 88 | } else { | |
89 | epp->ep_minsaddr = USRSTACK; | 89 | epp->ep_minsaddr = USRSTACK; | |
90 | max_stack_size = MAXSSIZ; | 90 | max_stack_size = MAXSSIZ; | |
91 | if (epp->ep_minsaddr > LINUX_USRSTACK) | 91 | if (epp->ep_minsaddr > LINUX_USRSTACK) | |
92 | epp->ep_minsaddr = LINUX_USRSTACK; | 92 | epp->ep_minsaddr = LINUX_USRSTACK; | |
93 | 93 | |||
94 | } | 94 | } | |
95 | 95 | |||
96 | epp->ep_maxsaddr = (u_long)STACK_GROW(epp->ep_minsaddr, | 96 | epp->ep_maxsaddr = (u_long)STACK_GROW(epp->ep_minsaddr, | |
97 | max_stack_size); | 97 | max_stack_size); | |
98 | epp->ep_ssize = l->l_proc->p_rlimit[RLIMIT_STACK].rlim_cur; | 98 | epp->ep_ssize = l->l_proc->p_rlimit[RLIMIT_STACK].rlim_cur; | |
99 | 99 | |||
100 | /* | 100 | /* | |
101 | * set up commands for stack. note that this takes *two*, one to | 101 | * set up commands for stack. note that this takes *two*, one to | |
102 | * map the part of the stack which we can access, and one to map | 102 | * map the part of the stack which we can access, and one to map | |
103 | * the part which we can't. | 103 | * the part which we can't. | |
104 | * | 104 | * | |
105 | * arguably, it could be made into one, but that would require the | 105 | * arguably, it could be made into one, but that would require the | |
106 | * addition of another mapping proc, which is unnecessary | 106 | * addition of another mapping proc, which is unnecessary | |
107 | */ | 107 | */ | |
108 | access_size = epp->ep_ssize; | 108 | access_size = epp->ep_ssize; | |
109 | access_linear_min = (u_long)STACK_ALLOC(epp->ep_minsaddr, access_size); | 109 | access_linear_min = (u_long)STACK_ALLOC(epp->ep_minsaddr, access_size); | |
110 | noaccess_size = max_stack_size - access_size; | 110 | noaccess_size = max_stack_size - access_size; | |
111 | noaccess_linear_min = (u_long)STACK_ALLOC(STACK_GROW(epp->ep_minsaddr, | 111 | noaccess_linear_min = (u_long)STACK_ALLOC(STACK_GROW(epp->ep_minsaddr, | |
112 | access_size), noaccess_size); | 112 | access_size), noaccess_size); | |
113 | if (noaccess_size > 0) { | 113 | if (noaccess_size > 0) { | |
114 | NEW_VMCMD2(&epp->ep_vmcmds, vmcmd_map_zero, noaccess_size, | 114 | NEW_VMCMD2(&epp->ep_vmcmds, vmcmd_map_zero, noaccess_size, | |
115 | noaccess_linear_min, NULLVP, 0, VM_PROT_NONE, VMCMD_STACK); | 115 | noaccess_linear_min, NULLVP, 0, VM_PROT_NONE, VMCMD_STACK); | |
116 | } | 116 | } | |
117 | KASSERT(access_size > 0); | 117 | KASSERT(access_size > 0); | |
118 | NEW_VMCMD2(&epp->ep_vmcmds, vmcmd_map_zero, access_size, | 118 | NEW_VMCMD2(&epp->ep_vmcmds, vmcmd_map_zero, access_size, | |
119 | access_linear_min, NULLVP, 0, VM_PROT_READ | VM_PROT_WRITE, | 119 | access_linear_min, NULLVP, 0, VM_PROT_READ | VM_PROT_WRITE, | |
120 | VMCMD_STACK); | 120 | VMCMD_STACK); | |
121 | 121 | |||
122 | return 0; | 122 | return 0; | |
123 | } | 123 | } | |
124 | 124 | |||
125 | int | 125 | int | |
126 | ELFNAME2(linux,copyargs)(struct lwp *l, struct exec_package *pack, | 126 | ELFNAME2(linux,copyargs)(struct lwp *l, struct exec_package *pack, | |
127 | struct ps_strings *arginfo, char **stackp, void *argp) | 127 | struct ps_strings *arginfo, char **stackp, void *argp) | |
128 | { | 128 | { | |
129 | struct linux_extra_stack_data64 *esdp, esd; | 129 | struct linux_extra_stack_data64 *esdp, esd; | |
130 | struct elf_args *ap; | 130 | struct elf_args *ap; | |
131 | struct vattr *vap; | 131 | struct vattr *vap; | |
132 | Elf_Ehdr *eh; | 132 | Elf_Ehdr *eh; | |
133 | Elf_Phdr *ph; | 133 | Elf_Phdr *ph; | |
134 | u_long phsize; | 134 | u_long phsize; | |
135 | Elf_Addr phdr = 0; | 135 | Elf_Addr phdr = 0; | |
136 | int error; | 136 | int error; | |
137 | int i; | 137 | int i; | |
138 | 138 | |||
139 | if ((error = copyargs(l, pack, arginfo, stackp, argp)) != 0) | 139 | if ((error = copyargs(l, pack, arginfo, stackp, argp)) != 0) | |
140 | return error; | 140 | return error; | |
141 | 141 | |||
142 | /* | 142 | /* | |
143 | * Push extra arguments on the stack needed by dynamically | 143 | * Push extra arguments on the stack needed by dynamically | |
144 | * linked binaries and static binaries as well. | 144 | * linked binaries and static binaries as well. | |
145 | */ | 145 | */ | |
146 | memset(&esd, 0, sizeof(esd)); | 146 | memset(&esd, 0, sizeof(esd)); | |
147 | esdp = (struct linux_extra_stack_data64 *)(*stackp); | 147 | esdp = (struct linux_extra_stack_data64 *)(*stackp); | |
148 | ap = (struct elf_args *)pack->ep_emul_arg; | 148 | ap = (struct elf_args *)pack->ep_emul_arg; | |
149 | vap = pack->ep_vap; | 149 | vap = pack->ep_vap; | |
150 | eh = (Elf_Ehdr *)pack->ep_hdr; | 150 | eh = (Elf_Ehdr *)pack->ep_hdr; | |
151 | 151 | |||
152 | /* | 152 | /* | |
153 | * We forgot this, so we need to reload it now. XXX keep track of it? | 153 | * We forgot this, so we need to reload it now. XXX keep track of it? | |
154 | */ | 154 | */ | |
155 | if (ap == NULL) { | 155 | if (ap == NULL) { | |
156 | phsize = eh->e_phnum * sizeof(Elf_Phdr); | 156 | phsize = eh->e_phnum * sizeof(Elf_Phdr); | |
157 | ph = (Elf_Phdr *)kmem_alloc(phsize, KM_SLEEP); | 157 | ph = (Elf_Phdr *)kmem_alloc(phsize, KM_SLEEP); | |
158 | error = exec_read_from(l, pack->ep_vp, eh->e_phoff, ph, phsize); | 158 | error = exec_read_from(l, pack->ep_vp, eh->e_phoff, ph, phsize); | |
159 | if (error != 0) { | 159 | if (error != 0) { | |
160 | for (i = 0; i < eh->e_phnum; i++) { | 160 | for (i = 0; i < eh->e_phnum; i++) { | |
161 | if (ph[i].p_type == PT_PHDR) { | 161 | if (ph[i].p_type == PT_PHDR) { | |
162 | phdr = ph[i].p_vaddr; | 162 | phdr = ph[i].p_vaddr; | |
163 | break; | 163 | break; | |
164 | } | 164 | } | |
165 | } | 165 | } | |
166 | } | 166 | } | |
167 | kmem_free(ph, phsize); | 167 | kmem_free(ph, phsize); | |
168 | } | 168 | } | |
169 | 169 | |||
170 | 170 | |||
171 | /* | 171 | /* | |
172 | * The exec_package doesn't have a proc pointer and it's not | 172 | * The exec_package doesn't have a proc pointer and it's not | |
173 | * exactly trivial to add one since the credentials are | 173 | * exactly trivial to add one since the credentials are | |
174 | * changing. XXX Linux uses curlwp's credentials. | 174 | * changing. XXX Linux uses curlwp's credentials. | |
175 | * Why can't we use them too? | 175 | * Why can't we use them too? | |
176 | */ | 176 | */ | |
177 | 177 | |||
178 | i = 0; | 178 | i = 0; | |
179 | esd.ai[i].a_type = LINUX_AT_HWCAP; | 179 | esd.ai[i].a_type = LINUX_AT_HWCAP; | |
180 | esd.ai[i++].a_v = rcr4(); | 180 | esd.ai[i++].a_v = rcr4(); | |
181 | 181 | |||
182 | esd.ai[i].a_type = AT_PAGESZ; | 182 | esd.ai[i].a_type = AT_PAGESZ; | |
183 | esd.ai[i++].a_v = PAGE_SIZE; | 183 | esd.ai[i++].a_v = PAGE_SIZE; | |
184 | 184 | |||
185 | esd.ai[i].a_type = LINUX_AT_CLKTCK; | 185 | esd.ai[i].a_type = LINUX_AT_CLKTCK; | |
186 | esd.ai[i++].a_v = hz; | 186 | esd.ai[i++].a_v = hz; | |
187 | 187 | |||
188 | esd.ai[i].a_type = AT_PHDR; | 188 | esd.ai[i].a_type = AT_PHDR; | |
189 | esd.ai[i++].a_v = (ap ? ap->arg_phaddr: phdr); | 189 | esd.ai[i++].a_v = (ap ? ap->arg_phaddr: phdr); | |
190 | 190 | |||
191 | esd.ai[i].a_type = AT_PHENT; | 191 | esd.ai[i].a_type = AT_PHENT; | |
192 | esd.ai[i++].a_v = (ap ? ap->arg_phentsize : eh->e_phentsize); | 192 | esd.ai[i++].a_v = (ap ? ap->arg_phentsize : eh->e_phentsize); | |
193 | 193 | |||
194 | esd.ai[i].a_type = AT_PHNUM; | 194 | esd.ai[i].a_type = AT_PHNUM; | |
195 | esd.ai[i++].a_v = (ap ? ap->arg_phnum : eh->e_phnum); | 195 | esd.ai[i++].a_v = (ap ? ap->arg_phnum : eh->e_phnum); | |
196 | 196 | |||
197 | esd.ai[i].a_type = AT_BASE; | 197 | esd.ai[i].a_type = AT_BASE; | |
198 | esd.ai[i++].a_v = (ap ? ap->arg_interp : 0); | 198 | esd.ai[i++].a_v = (ap ? ap->arg_interp : 0); | |
199 | 199 | |||
200 | esd.ai[i].a_type = AT_FLAGS; | 200 | esd.ai[i].a_type = AT_FLAGS; | |
201 | esd.ai[i++].a_v = 0; | 201 | esd.ai[i++].a_v = 0; | |
202 | 202 | |||
203 | esd.ai[i].a_type = AT_ENTRY; | 203 | esd.ai[i].a_type = AT_ENTRY; | |
204 | esd.ai[i++].a_v = (ap ? ap->arg_entry : eh->e_entry); | 204 | esd.ai[i++].a_v = (ap ? ap->arg_entry : eh->e_entry); | |
205 | 205 | |||
206 | esd.ai[i].a_type = LINUX_AT_EGID; | 206 | esd.ai[i].a_type = LINUX_AT_EGID; | |
207 | esd.ai[i++].a_v = ((vap->va_mode & S_ISGID) ? | 207 | esd.ai[i++].a_v = ((vap->va_mode & S_ISGID) ? | |
208 | vap->va_gid : kauth_cred_getegid(l->l_cred)); | 208 | vap->va_gid : kauth_cred_getegid(l->l_cred)); | |
209 | 209 | |||
210 | esd.ai[i].a_type = LINUX_AT_GID; | 210 | esd.ai[i].a_type = LINUX_AT_GID; | |
211 | esd.ai[i++].a_v = kauth_cred_getgid(l->l_cred); | 211 | esd.ai[i++].a_v = kauth_cred_getgid(l->l_cred); | |
212 | 212 | |||
213 | esd.ai[i].a_type = LINUX_AT_EUID; | 213 | esd.ai[i].a_type = LINUX_AT_EUID; | |
214 | esd.ai[i++].a_v = ((vap->va_mode & S_ISUID) ? | 214 | esd.ai[i++].a_v = ((vap->va_mode & S_ISUID) ? | |
215 | vap->va_uid : kauth_cred_geteuid(l->l_cred)); | 215 | vap->va_uid : kauth_cred_geteuid(l->l_cred)); | |
216 | 216 | |||
217 | esd.ai[i].a_type = LINUX_AT_UID; | 217 | esd.ai[i].a_type = LINUX_AT_UID; | |
218 | esd.ai[i++].a_v = kauth_cred_getuid(l->l_cred); | 218 | esd.ai[i++].a_v = kauth_cred_getuid(l->l_cred); | |
219 | 219 | |||
220 | esd.ai[i].a_type = LINUX_AT_SECURE; | 220 | esd.ai[i].a_type = LINUX_AT_SECURE; | |
221 | esd.ai[i++].a_v = 0; | 221 | esd.ai[i++].a_v = 0; | |
222 | 222 | |||
223 | esd.ai[i].a_type = LINUX_AT_PLATFORM; | 223 | esd.ai[i].a_type = LINUX_AT_PLATFORM; | |
224 | esd.ai[i++].a_v = (Elf_Addr)&esdp->hw_platform[0]; | 224 | esd.ai[i++].a_v = (Elf_Addr)&esdp->hw_platform[0]; | |
225 | 225 | |||
226 | esd.ai[i].a_type = LINUX_AT_RANDOM; | 226 | esd.ai[i].a_type = LINUX_AT_RANDOM; | |
227 | esd.ai[i++].a_v = (Elf_Addr)&esdp->randbytes[0]; | 227 | esd.ai[i++].a_v = (Elf_Addr)&esdp->randbytes[0]; | |
228 | esd.randbytes[0] = random(); | 228 | esd.randbytes[0] = random(); | |
229 | esd.randbytes[1] = random(); | 229 | esd.randbytes[1] = random(); | |
230 | esd.randbytes[2] = random(); | 230 | esd.randbytes[2] = random(); | |
231 | esd.randbytes[3] = random(); | 231 | esd.randbytes[3] = random(); | |
232 | 232 | |||
233 | esd.ai[i].a_type = AT_NULL; | 233 | esd.ai[i].a_type = AT_NULL; | |
234 | esd.ai[i++].a_v = 0; | 234 | esd.ai[i++].a_v = 0; | |
235 | 235 | |||
236 | #ifdef DEBUG_LINUX | 236 | KASSERT(i == LINUX_ELF_AUX_ENTRIES); | |
237 | if (i != LINUX_ELF_AUX_ENTRIES) { | 237 | ||
238 | printf("linux_elf64_copyargs: %d Aux entries\n", i); | |||
239 | return EINVAL; | |||
240 | } | |||
241 | #endif | |||
242 | ||||
243 | strcpy(esd.hw_platform, LINUX_PLATFORM); | 238 | strcpy(esd.hw_platform, LINUX_PLATFORM); | |
244 | 239 | |||
245 | exec_free_emul_arg(pack); | 240 | exec_free_emul_arg(pack); | |
246 | 241 | |||
247 | /* | 242 | /* | |
248 | * Copy out the ELF auxiliary table and hw platform name | 243 | * Copy out the ELF auxiliary table and hw platform name | |
249 | */ | 244 | */ | |
250 | if ((error = copyout(&esd, esdp, sizeof(esd))) != 0) | 245 | if ((error = copyout(&esd, esdp, sizeof(esd))) != 0) | |
251 | return error; | 246 | return error; | |
252 | *stackp += sizeof(esd); | 247 | *stackp += sizeof(esd); | |
253 | 248 | |||
254 | return 0; | 249 | return 0; | |
255 | } | 250 | } |
--- src/sys/compat/linux/common/linux_exec.h 2014/02/09 16:41:42 1.50
+++ src/sys/compat/linux/common/linux_exec.h 2014/02/21 07:53:53 1.51
@@ -1,193 +1,194 @@ | @@ -1,193 +1,194 @@ | |||
1 | /* $NetBSD: linux_exec.h,v 1.50 2014/02/09 16:41:42 chs Exp $ */ | 1 | /* $NetBSD: linux_exec.h,v 1.51 2014/02/21 07:53:53 maxv Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 1995, 1998 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 1995, 1998 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Frank van der Linden and Eric Haszlakiewicz. | 8 | * by Frank van der Linden and Eric Haszlakiewicz. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | 15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in the | 16 | * notice, this list of conditions and the following disclaimer in the | |
17 | * documentation and/or other materials provided with the distribution. | 17 | * documentation and/or other materials provided with the distribution. | |
18 | * | 18 | * | |
19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | 19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
29 | * POSSIBILITY OF SUCH DAMAGE. | 29 | * POSSIBILITY OF SUCH DAMAGE. | |
30 | */ | 30 | */ | |
31 | 31 | |||
32 | #ifndef _LINUX_EXEC_H | 32 | #ifndef _LINUX_EXEC_H | |
33 | #define _LINUX_EXEC_H | 33 | #define _LINUX_EXEC_H | |
34 | 34 | |||
35 | #if defined(EXEC_AOUT) | 35 | #if defined(EXEC_AOUT) | |
36 | #include <sys/exec_aout.h> | 36 | #include <sys/exec_aout.h> | |
37 | #endif | 37 | #endif | |
38 | 38 | |||
39 | #if defined(EXEC_ELF32) || defined(EXEC_ELF64) | 39 | #if defined(EXEC_ELF32) || defined(EXEC_ELF64) | |
40 | #include <sys/exec_elf.h> | 40 | #include <sys/exec_elf.h> | |
41 | #endif | 41 | #endif | |
42 | 42 | |||
43 | #if defined(__i386__) | 43 | #if defined(__i386__) | |
44 | #include <compat/linux/arch/i386/linux_exec.h> | 44 | #include <compat/linux/arch/i386/linux_exec.h> | |
45 | #elif defined(__m68k__) | 45 | #elif defined(__m68k__) | |
46 | #include <compat/linux/arch/m68k/linux_exec.h> | 46 | #include <compat/linux/arch/m68k/linux_exec.h> | |
47 | #elif defined(__alpha__) | 47 | #elif defined(__alpha__) | |
48 | #include <compat/linux/arch/alpha/linux_exec.h> | 48 | #include <compat/linux/arch/alpha/linux_exec.h> | |
49 | #elif defined(__powerpc__) | 49 | #elif defined(__powerpc__) | |
50 | #include <compat/linux/arch/powerpc/linux_exec.h> | 50 | #include <compat/linux/arch/powerpc/linux_exec.h> | |
51 | #elif defined(__mips__) | 51 | #elif defined(__mips__) | |
52 | #include <compat/linux/arch/mips/linux_exec.h> | 52 | #include <compat/linux/arch/mips/linux_exec.h> | |
53 | #elif defined(__arm__) | 53 | #elif defined(__arm__) | |
54 | #include <compat/linux/arch/arm/linux_exec.h> | 54 | #include <compat/linux/arch/arm/linux_exec.h> | |
55 | #elif defined(__amd64__) | 55 | #elif defined(__amd64__) | |
56 | #include <compat/linux/arch/amd64/linux_exec.h> | 56 | #include <compat/linux/arch/amd64/linux_exec.h> | |
57 | #endif | 57 | #endif | |
58 | 58 | |||
59 | 59 | |||
60 | /* Defines for a.out executables */ | 60 | /* Defines for a.out executables */ | |
61 | #define LINUX_AOUT_HDR_SIZE (sizeof (struct exec)) | 61 | #define LINUX_AOUT_HDR_SIZE (sizeof (struct exec)) | |
62 | #define LINUX_AOUT_AUX_ARGSIZ 2 | 62 | #define LINUX_AOUT_AUX_ARGSIZ 2 | |
63 | 63 | |||
64 | #define LINUX_N_MAGIC(ep) ((ep)->a_midmag & 0xffff) | 64 | #define LINUX_N_MAGIC(ep) ((ep)->a_midmag & 0xffff) | |
65 | #define LINUX_N_MACHTYPE(ep) (((ep)->a_midmag >> 16) & 0xff) | 65 | #define LINUX_N_MACHTYPE(ep) (((ep)->a_midmag >> 16) & 0xff) | |
66 | 66 | |||
67 | #define LINUX_N_TXTOFF(x,m) \ | 67 | #define LINUX_N_TXTOFF(x,m) \ | |
68 | ((m) == ZMAGIC ? 1024 : ((m) == QMAGIC ? 0 : sizeof (struct exec))) | 68 | ((m) == ZMAGIC ? 1024 : ((m) == QMAGIC ? 0 : sizeof (struct exec))) | |
69 | 69 | |||
70 | #define LINUX_N_DATOFF(x,m) (LINUX_N_TXTOFF(x,m) + (x).a_text) | 70 | #define LINUX_N_DATOFF(x,m) (LINUX_N_TXTOFF(x,m) + (x).a_text) | |
71 | 71 | |||
72 | #define LINUX_N_TXTADDR(x,m) ((m) == QMAGIC ? PAGE_SIZE : 0) | 72 | #define LINUX_N_TXTADDR(x,m) ((m) == QMAGIC ? PAGE_SIZE : 0) | |
73 | 73 | |||
74 | #define LINUX__N_SEGMENT_ROUND(x) (((x) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) | 74 | #define LINUX__N_SEGMENT_ROUND(x) (((x) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) | |
75 | 75 | |||
76 | #define LINUX__N_TXTENDADDR(x,m) (LINUX_N_TXTADDR(x,m)+(x).a_text) | 76 | #define LINUX__N_TXTENDADDR(x,m) (LINUX_N_TXTADDR(x,m)+(x).a_text) | |
77 | 77 | |||
78 | #define LINUX_N_DATADDR(x,m) \ | 78 | #define LINUX_N_DATADDR(x,m) \ | |
79 | ((m)==OMAGIC? (LINUX__N_TXTENDADDR(x,m)) \ | 79 | ((m)==OMAGIC? (LINUX__N_TXTENDADDR(x,m)) \ | |
80 | : (LINUX__N_SEGMENT_ROUND (LINUX__N_TXTENDADDR(x,m)))) | 80 | : (LINUX__N_SEGMENT_ROUND (LINUX__N_TXTENDADDR(x,m)))) | |
81 | 81 | |||
82 | #define LINUX_N_BSSADDR(x,m) (LINUX_N_DATADDR(x,m) + (x).a_data) | 82 | #define LINUX_N_BSSADDR(x,m) (LINUX_N_DATADDR(x,m) + (x).a_data) | |
83 | 83 | |||
84 | #ifndef LINUX_MACHDEP_ELF_COPYARGS | 84 | #ifndef LINUX_MACHDEP_ELF_COPYARGS | |
85 | /* Counted from linux_exec_elf32.c */ | |||
85 | #define LINUX_ELF_AUX_ENTRIES 14 | 86 | #define LINUX_ELF_AUX_ENTRIES 14 | |
86 | #endif | 87 | #endif | |
87 | 88 | |||
88 | /* | 89 | /* | |
89 | * From Linux's include/linux/elf.h | 90 | * From Linux's include/linux/elf.h | |
90 | */ | 91 | */ | |
91 | #define LINUX_AT_UID 11 /* real uid */ | 92 | #define LINUX_AT_UID 11 /* real uid */ | |
92 | #define LINUX_AT_EUID 12 /* effective uid */ | 93 | #define LINUX_AT_EUID 12 /* effective uid */ | |
93 | #define LINUX_AT_GID 13 /* real gid */ | 94 | #define LINUX_AT_GID 13 /* real gid */ | |
94 | #define LINUX_AT_EGID 14 /* effective gid */ | 95 | #define LINUX_AT_EGID 14 /* effective gid */ | |
95 | #define LINUX_AT_PLATFORM 15 /* CPU string for optimizations */ | 96 | #define LINUX_AT_PLATFORM 15 /* CPU string for optimizations */ | |
96 | #define LINUX_AT_HWCAP 16 /* arch dependent CPU capabilities */ | 97 | #define LINUX_AT_HWCAP 16 /* arch dependent CPU capabilities */ | |
97 | #define LINUX_AT_CLKTCK 17 /* frequency times() increments */ | 98 | #define LINUX_AT_CLKTCK 17 /* frequency times() increments */ | |
98 | #define LINUX_AT_SECURE 23 /* secure mode boolean */ | 99 | #define LINUX_AT_SECURE 23 /* secure mode boolean */ | |
99 | #define LINUX_AT_RANDOM 25 /* address of 16 random bytes */ | 100 | #define LINUX_AT_RANDOM 25 /* address of 16 random bytes */ | |
100 | #define LINUX_AT_SYSINFO 32 /* pointer to __kernel_vsyscall */ | 101 | #define LINUX_AT_SYSINFO 32 /* pointer to __kernel_vsyscall */ | |
101 | #define LINUX_AT_SYSINFO_EHDR 33 /* pointer to ELF header */ | 102 | #define LINUX_AT_SYSINFO_EHDR 33 /* pointer to ELF header */ | |
102 | 103 | |||
103 | #define LINUX_RANDOM_BYTES 16 /* 16 bytes for AT_RANDOM */ | 104 | #define LINUX_RANDOM_BYTES 16 /* 16 bytes for AT_RANDOM */ | |
104 | 105 | |||
105 | /* | 106 | /* | |
106 | * Emulation specific sysctls. | 107 | * Emulation specific sysctls. | |
107 | */ | 108 | */ | |
108 | #define EMUL_LINUX_KERN 1 | 109 | #define EMUL_LINUX_KERN 1 | |
109 | #define EMUL_LINUX_MAXID 2 | 110 | #define EMUL_LINUX_MAXID 2 | |
110 | 111 | |||
111 | #define EMUL_LINUX_NAMES { \ | 112 | #define EMUL_LINUX_NAMES { \ | |
112 | { 0, 0 }, \ | 113 | { 0, 0 }, \ | |
113 | { "kern", CTLTYPE_NODE }, \ | 114 | { "kern", CTLTYPE_NODE }, \ | |
114 | } | 115 | } | |
115 | 116 | |||
116 | #define EMUL_LINUX_KERN_OSTYPE 1 | 117 | #define EMUL_LINUX_KERN_OSTYPE 1 | |
117 | #define EMUL_LINUX_KERN_OSRELEASE 2 | 118 | #define EMUL_LINUX_KERN_OSRELEASE 2 | |
118 | #define EMUL_LINUX_KERN_VERSION 3 | 119 | #define EMUL_LINUX_KERN_VERSION 3 | |
119 | #define EMUL_LINUX_KERN_MAXID 4 | 120 | #define EMUL_LINUX_KERN_MAXID 4 | |
120 | 121 | |||
121 | #define EMUL_LINUX_KERN_NAMES { \ | 122 | #define EMUL_LINUX_KERN_NAMES { \ | |
122 | { 0, 0 }, \ | 123 | { 0, 0 }, \ | |
123 | { "ostype", CTLTYPE_STRING }, \ | 124 | { "ostype", CTLTYPE_STRING }, \ | |
124 | { "osrelease", CTLTYPE_STRING }, \ | 125 | { "osrelease", CTLTYPE_STRING }, \ | |
125 | { "osversion", CTLTYPE_STRING }, \ | 126 | { "osversion", CTLTYPE_STRING }, \ | |
126 | } | 127 | } | |
127 | 128 | |||
128 | #ifdef _KERNEL | 129 | #ifdef _KERNEL | |
129 | __BEGIN_DECLS | 130 | __BEGIN_DECLS | |
130 | extern struct emul emul_linux; | 131 | extern struct emul emul_linux; | |
131 | 132 | |||
132 | int linux_sysctl(int *, u_int, void *, size_t *, void *, size_t, | 133 | int linux_sysctl(int *, u_int, void *, size_t *, void *, size_t, | |
133 | struct lwp *); | 134 | struct lwp *); | |
134 | void linux_setregs(struct lwp *, struct exec_package *, vaddr_t); | 135 | void linux_setregs(struct lwp *, struct exec_package *, vaddr_t); | |
135 | #ifdef EXEC_AOUT | 136 | #ifdef EXEC_AOUT | |
136 | int exec_linux_aout_makecmds(struct lwp *, struct exec_package *); | 137 | int exec_linux_aout_makecmds(struct lwp *, struct exec_package *); | |
137 | int linux_aout_copyargs(struct lwp *, struct exec_package *, | 138 | int linux_aout_copyargs(struct lwp *, struct exec_package *, | |
138 | struct ps_strings *, char **, void *); | 139 | struct ps_strings *, char **, void *); | |
139 | #endif | 140 | #endif | |
140 | void linux_trapsignal(struct lwp *, ksiginfo_t *); | 141 | void linux_trapsignal(struct lwp *, ksiginfo_t *); | |
141 | int linux_usertrap(struct lwp *, vaddr_t, void *); | 142 | int linux_usertrap(struct lwp *, vaddr_t, void *); | |
142 | int linux_lwp_setprivate(struct lwp *, void *); | 143 | int linux_lwp_setprivate(struct lwp *, void *); | |
143 | 144 | |||
144 | void linux_e_proc_exec(struct proc *, struct exec_package *); | 145 | void linux_e_proc_exec(struct proc *, struct exec_package *); | |
145 | void linux_e_proc_fork(struct proc *, struct lwp *, int); | 146 | void linux_e_proc_fork(struct proc *, struct lwp *, int); | |
146 | void linux_e_proc_exit(struct proc *); | 147 | void linux_e_proc_exit(struct proc *); | |
147 | void linux_e_lwp_fork(struct lwp *, struct lwp *); | 148 | void linux_e_lwp_fork(struct lwp *, struct lwp *); | |
148 | void linux_e_lwp_exit(struct lwp *); | 149 | void linux_e_lwp_exit(struct lwp *); | |
149 | 150 | |||
150 | #ifdef EXEC_ELF32 | 151 | #ifdef EXEC_ELF32 | |
151 | int linux_elf32_probe(struct lwp *, struct exec_package *, void *, | 152 | int linux_elf32_probe(struct lwp *, struct exec_package *, void *, | |
152 | char *, vaddr_t *); | 153 | char *, vaddr_t *); | |
153 | int linux_elf32_copyargs(struct lwp *, struct exec_package *, | 154 | int linux_elf32_copyargs(struct lwp *, struct exec_package *, | |
154 | struct ps_strings *, char **, void *); | 155 | struct ps_strings *, char **, void *); | |
155 | int linux_elf32_signature(struct lwp *, struct exec_package *, | 156 | int linux_elf32_signature(struct lwp *, struct exec_package *, | |
156 | Elf32_Ehdr *, char *); | 157 | Elf32_Ehdr *, char *); | |
157 | #ifdef LINUX_GCC_SIGNATURE | 158 | #ifdef LINUX_GCC_SIGNATURE | |
158 | int linux_elf32_gcc_signature(struct lwp *l, | 159 | int linux_elf32_gcc_signature(struct lwp *l, | |
159 | struct exec_package *, Elf32_Ehdr *); | 160 | struct exec_package *, Elf32_Ehdr *); | |
160 | #endif | 161 | #endif | |
161 | #ifdef LINUX_DEBUGLINK_SIGNATURE | 162 | #ifdef LINUX_DEBUGLINK_SIGNATURE | |
162 | int linux_elf32_debuglink_signature(struct lwp *l, | 163 | int linux_elf32_debuglink_signature(struct lwp *l, | |
163 | struct exec_package *, Elf32_Ehdr *); | 164 | struct exec_package *, Elf32_Ehdr *); | |
164 | #endif | 165 | #endif | |
165 | #ifdef LINUX_ATEXIT_SIGNATURE | 166 | #ifdef LINUX_ATEXIT_SIGNATURE | |
166 | int linux_elf32_atexit_signature(struct lwp *l, | 167 | int linux_elf32_atexit_signature(struct lwp *l, | |
167 | struct exec_package *, Elf32_Ehdr *); | 168 | struct exec_package *, Elf32_Ehdr *); | |
168 | #endif | 169 | #endif | |
169 | #endif | 170 | #endif | |
170 | #ifdef EXEC_ELF64 | 171 | #ifdef EXEC_ELF64 | |
171 | int linux_elf64_probe(struct lwp *, struct exec_package *, void *, | 172 | int linux_elf64_probe(struct lwp *, struct exec_package *, void *, | |
172 | char *, vaddr_t *); | 173 | char *, vaddr_t *); | |
173 | int linux_elf64_copyargs(struct lwp *, struct exec_package *, | 174 | int linux_elf64_copyargs(struct lwp *, struct exec_package *, | |
174 | struct ps_strings *, char **, void *); | 175 | struct ps_strings *, char **, void *); | |
175 | int linux_elf64_signature(struct lwp *, struct exec_package *, | 176 | int linux_elf64_signature(struct lwp *, struct exec_package *, | |
176 | Elf64_Ehdr *, char *); | 177 | Elf64_Ehdr *, char *); | |
177 | #ifdef LINUX_GCC_SIGNATURE | 178 | #ifdef LINUX_GCC_SIGNATURE | |
178 | int linux_elf64_gcc_signature(struct lwp *l, | 179 | int linux_elf64_gcc_signature(struct lwp *l, | |
179 | struct exec_package *, Elf64_Ehdr *); | 180 | struct exec_package *, Elf64_Ehdr *); | |
180 | #endif | 181 | #endif | |
181 | #ifdef LINUX_DEBUGLINK_SIGNATURE | 182 | #ifdef LINUX_DEBUGLINK_SIGNATURE | |
182 | int linux_elf64_debuglink_signature(struct lwp *l, | 183 | int linux_elf64_debuglink_signature(struct lwp *l, | |
183 | struct exec_package *, Elf64_Ehdr *); | 184 | struct exec_package *, Elf64_Ehdr *); | |
184 | #endif | 185 | #endif | |
185 | #ifdef LINUX_ATEXIT_SIGNATURE | 186 | #ifdef LINUX_ATEXIT_SIGNATURE | |
186 | int linux_elf64_atexit_signature(struct lwp *l, | 187 | int linux_elf64_atexit_signature(struct lwp *l, | |
187 | struct exec_package *, Elf64_Ehdr *); | 188 | struct exec_package *, Elf64_Ehdr *); | |
188 | #endif | 189 | #endif | |
189 | #endif | 190 | #endif | |
190 | __END_DECLS | 191 | __END_DECLS | |
191 | #endif /* !_KERNEL */ | 192 | #endif /* !_KERNEL */ | |
192 | 193 | |||
193 | #endif /* !_LINUX_EXEC_H */ | 194 | #endif /* !_LINUX_EXEC_H */ |
--- src/sys/compat/linux/common/linux_exec_elf32.c 2014/02/09 16:41:42 1.88
+++ src/sys/compat/linux/common/linux_exec_elf32.c 2014/02/21 07:53:53 1.89
@@ -1,504 +1,505 @@ | @@ -1,504 +1,505 @@ | |||
1 | /* $NetBSD: linux_exec_elf32.c,v 1.88 2014/02/09 16:41:42 chs Exp $ */ | 1 | /* $NetBSD: linux_exec_elf32.c,v 1.89 2014/02/21 07:53:53 maxv Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 1995, 1998, 2000, 2001 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 1995, 1998, 2000, 2001 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Christos Zoulas, Frank van der Linden, Eric Haszlakiewicz and | 8 | * by Christos Zoulas, Frank van der Linden, Eric Haszlakiewicz and | |
9 | * Emmanuel Dreyfus. | 9 | * Emmanuel Dreyfus. | |
10 | * | 10 | * | |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without | |
12 | * modification, are permitted provided that the following conditions | 12 | * modification, are permitted provided that the following conditions | |
13 | * are met: | 13 | * are met: | |
14 | * 1. Redistributions of source code must retain the above copyright | 14 | * 1. Redistributions of source code must retain the above copyright | |
15 | * notice, this list of conditions and the following disclaimer. | 15 | * notice, this list of conditions and the following disclaimer. | |
16 | * 2. Redistributions in binary form must reproduce the above copyright | 16 | * 2. Redistributions in binary form must reproduce the above copyright | |
17 | * notice, this list of conditions and the following disclaimer in the | 17 | * notice, this list of conditions and the following disclaimer in the | |
18 | * documentation and/or other materials provided with the distribution. | 18 | * documentation and/or other materials provided with the distribution. | |
19 | * | 19 | * | |
20 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | 20 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
21 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 21 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
24 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 24 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
30 | * POSSIBILITY OF SUCH DAMAGE. | 30 | * POSSIBILITY OF SUCH DAMAGE. | |
31 | */ | 31 | */ | |
32 | 32 | |||
33 | /* | 33 | /* | |
34 | * based on exec_aout.c, sunos_exec.c and svr4_exec.c | 34 | * based on exec_aout.c, sunos_exec.c and svr4_exec.c | |
35 | */ | 35 | */ | |
36 | 36 | |||
37 | #include <sys/cdefs.h> | 37 | #include <sys/cdefs.h> | |
38 | __KERNEL_RCSID(0, "$NetBSD: linux_exec_elf32.c,v 1.88 2014/02/09 16:41:42 chs Exp $"); | 38 | __KERNEL_RCSID(0, "$NetBSD: linux_exec_elf32.c,v 1.89 2014/02/21 07:53:53 maxv Exp $"); | |
39 | 39 | |||
40 | #ifndef ELFSIZE | 40 | #ifndef ELFSIZE | |
41 | /* XXX should die */ | 41 | /* XXX should die */ | |
42 | #define ELFSIZE 32 | 42 | #define ELFSIZE 32 | |
43 | #endif | 43 | #endif | |
44 | 44 | |||
45 | #include <sys/param.h> | 45 | #include <sys/param.h> | |
46 | #include <sys/systm.h> | 46 | #include <sys/systm.h> | |
47 | #include <sys/kernel.h> | 47 | #include <sys/kernel.h> | |
48 | #include <sys/proc.h> | 48 | #include <sys/proc.h> | |
49 | #include <sys/malloc.h> | 49 | #include <sys/malloc.h> | |
50 | #include <sys/namei.h> | 50 | #include <sys/namei.h> | |
51 | #include <sys/vnode.h> | 51 | #include <sys/vnode.h> | |
52 | #include <sys/mount.h> | 52 | #include <sys/mount.h> | |
53 | #include <sys/exec.h> | 53 | #include <sys/exec.h> | |
54 | #include <sys/exec_elf.h> | 54 | #include <sys/exec_elf.h> | |
55 | #include <sys/stat.h> | 55 | #include <sys/stat.h> | |
56 | #include <sys/kauth.h> | 56 | #include <sys/kauth.h> | |
57 | #include <sys/cprng.h> | 57 | #include <sys/cprng.h> | |
58 | 58 | |||
59 | #include <sys/mman.h> | 59 | #include <sys/mman.h> | |
60 | #include <sys/syscallargs.h> | 60 | #include <sys/syscallargs.h> | |
61 | 61 | |||
62 | #include <sys/cpu.h> | 62 | #include <sys/cpu.h> | |
63 | #include <machine/reg.h> | 63 | #include <machine/reg.h> | |
64 | 64 | |||
65 | #include <compat/linux/common/linux_types.h> | 65 | #include <compat/linux/common/linux_types.h> | |
66 | #include <compat/linux/common/linux_signal.h> | 66 | #include <compat/linux/common/linux_signal.h> | |
67 | #include <compat/linux/common/linux_util.h> | 67 | #include <compat/linux/common/linux_util.h> | |
68 | #include <compat/linux/common/linux_exec.h> | 68 | #include <compat/linux/common/linux_exec.h> | |
69 | #include <compat/linux/common/linux_machdep.h> | 69 | #include <compat/linux/common/linux_machdep.h> | |
70 | #include <compat/linux/common/linux_ipc.h> | 70 | #include <compat/linux/common/linux_ipc.h> | |
71 | #include <compat/linux/common/linux_sem.h> | 71 | #include <compat/linux/common/linux_sem.h> | |
72 | 72 | |||
73 | #include <compat/linux/linux_syscallargs.h> | 73 | #include <compat/linux/linux_syscallargs.h> | |
74 | #include <compat/linux/linux_syscall.h> | 74 | #include <compat/linux/linux_syscall.h> | |
75 | 75 | |||
76 | #ifdef DEBUG_LINUX | 76 | #ifdef DEBUG_LINUX | |
77 | #define DPRINTF(a) uprintf a | 77 | #define DPRINTF(a) uprintf a | |
78 | #else | 78 | #else | |
79 | #define DPRINTF(a) | 79 | #define DPRINTF(a) | |
80 | #endif | 80 | #endif | |
81 | 81 | |||
82 | #ifdef LINUX_ATEXIT_SIGNATURE | 82 | #ifdef LINUX_ATEXIT_SIGNATURE | |
83 | /* | 83 | /* | |
84 | * On the PowerPC, statically linked Linux binaries are not recognized | 84 | * On the PowerPC, statically linked Linux binaries are not recognized | |
85 | * by linux_signature nor by linux_gcc_signature. Fortunately, thoses | 85 | * by linux_signature nor by linux_gcc_signature. Fortunately, thoses | |
86 | * binaries features a __libc_atexit ELF section. We therefore assume we | 86 | * binaries features a __libc_atexit ELF section. We therefore assume we | |
87 | * have a Linux binary if we find this section. | 87 | * have a Linux binary if we find this section. | |
88 | */ | 88 | */ | |
89 | int | 89 | int | |
90 | ELFNAME2(linux,atexit_signature)( | 90 | ELFNAME2(linux,atexit_signature)( | |
91 | struct lwp *l, | 91 | struct lwp *l, | |
92 | struct exec_package *epp, | 92 | struct exec_package *epp, | |
93 | Elf_Ehdr *eh) | 93 | Elf_Ehdr *eh) | |
94 | { | 94 | { | |
95 | size_t shsize; | 95 | size_t shsize; | |
96 | int strndx; | 96 | int strndx; | |
97 | size_t i; | 97 | size_t i; | |
98 | static const char signature[] = "__libc_atexit"; | 98 | static const char signature[] = "__libc_atexit"; | |
99 | char *strtable = NULL; | 99 | char *strtable = NULL; | |
100 | Elf_Shdr *sh; | 100 | Elf_Shdr *sh; | |
101 | 101 | |||
102 | int error; | 102 | int error; | |
103 | 103 | |||
104 | /* | 104 | /* | |
105 | * load the section header table | 105 | * load the section header table | |
106 | */ | 106 | */ | |
107 | shsize = eh->e_shnum * sizeof(Elf_Shdr); | 107 | shsize = eh->e_shnum * sizeof(Elf_Shdr); | |
108 | sh = (Elf_Shdr *) malloc(shsize, M_TEMP, M_WAITOK); | 108 | sh = (Elf_Shdr *) malloc(shsize, M_TEMP, M_WAITOK); | |
109 | error = exec_read_from(l, epp->ep_vp, eh->e_shoff, sh, shsize); | 109 | error = exec_read_from(l, epp->ep_vp, eh->e_shoff, sh, shsize); | |
110 | if (error) | 110 | if (error) | |
111 | goto out; | 111 | goto out; | |
112 | 112 | |||
113 | /* | 113 | /* | |
114 | * Now let's find the string table. If it does not exists, give up. | 114 | * Now let's find the string table. If it does not exists, give up. | |
115 | */ | 115 | */ | |
116 | strndx = (int)(eh->e_shstrndx); | 116 | strndx = (int)(eh->e_shstrndx); | |
117 | if (strndx == SHN_UNDEF) { | 117 | if (strndx == SHN_UNDEF) { | |
118 | error = ENOEXEC; | 118 | error = ENOEXEC; | |
119 | goto out; | 119 | goto out; | |
120 | } | 120 | } | |
121 | 121 | |||
122 | /* | 122 | /* | |
123 | * strndx is the index in section header table of the string table | 123 | * strndx is the index in section header table of the string table | |
124 | * section get the whole string table in strtable, and then we get access to the names | 124 | * section get the whole string table in strtable, and then we get access to the names | |
125 | * s->sh_name is the offset of the section name in strtable. | 125 | * s->sh_name is the offset of the section name in strtable. | |
126 | */ | 126 | */ | |
127 | strtable = malloc(sh[strndx].sh_size, M_TEMP, M_WAITOK); | 127 | strtable = malloc(sh[strndx].sh_size, M_TEMP, M_WAITOK); | |
128 | error = exec_read_from(l, epp->ep_vp, sh[strndx].sh_offset, strtable, | 128 | error = exec_read_from(l, epp->ep_vp, sh[strndx].sh_offset, strtable, | |
129 | sh[strndx].sh_size); | 129 | sh[strndx].sh_size); | |
130 | if (error) | 130 | if (error) | |
131 | goto out; | 131 | goto out; | |
132 | 132 | |||
133 | for (i = 0; i < eh->e_shnum; i++) { | 133 | for (i = 0; i < eh->e_shnum; i++) { | |
134 | Elf_Shdr *s = &sh[i]; | 134 | Elf_Shdr *s = &sh[i]; | |
135 | if (!memcmp((void*)(&(strtable[s->sh_name])), signature, | 135 | if (!memcmp((void*)(&(strtable[s->sh_name])), signature, | |
136 | sizeof(signature))) { | 136 | sizeof(signature))) { | |
137 | DPRINTF(("linux_atexit_sig=%s\n", | 137 | DPRINTF(("linux_atexit_sig=%s\n", | |
138 | &(strtable[s->sh_name]))); | 138 | &(strtable[s->sh_name]))); | |
139 | error = 0; | 139 | error = 0; | |
140 | goto out; | 140 | goto out; | |
141 | } | 141 | } | |
142 | } | 142 | } | |
143 | error = ENOEXEC; | 143 | error = ENOEXEC; | |
144 | 144 | |||
145 | out: | 145 | out: | |
146 | free(sh, M_TEMP); | 146 | free(sh, M_TEMP); | |
147 | if (strtable) | 147 | if (strtable) | |
148 | free(strtable, M_TEMP); | 148 | free(strtable, M_TEMP); | |
149 | return (error); | 149 | return (error); | |
150 | } | 150 | } | |
151 | #endif | 151 | #endif | |
152 | 152 | |||
153 | #ifdef LINUX_GCC_SIGNATURE | 153 | #ifdef LINUX_GCC_SIGNATURE | |
154 | /* | 154 | /* | |
155 | * Take advantage of the fact that all the linux binaries are compiled | 155 | * Take advantage of the fact that all the linux binaries are compiled | |
156 | * with gcc, and gcc sticks in the comment field a signature. Note that | 156 | * with gcc, and gcc sticks in the comment field a signature. Note that | |
157 | * on SVR4 binaries, the gcc signature will follow the OS name signature, | 157 | * on SVR4 binaries, the gcc signature will follow the OS name signature, | |
158 | * that will not be a problem. We don't bother to read in the string table, | 158 | * that will not be a problem. We don't bother to read in the string table, | |
159 | * but we check all the progbits headers. | 159 | * but we check all the progbits headers. | |
160 | * | 160 | * | |
161 | * XXX This only works in the i386. On the alpha (at least) | 161 | * XXX This only works in the i386. On the alpha (at least) | |
162 | * XXX we have the same gcc signature which incorrectly identifies | 162 | * XXX we have the same gcc signature which incorrectly identifies | |
163 | * XXX NetBSD binaries as Linux. | 163 | * XXX NetBSD binaries as Linux. | |
164 | */ | 164 | */ | |
165 | int | 165 | int | |
166 | ELFNAME2(linux,gcc_signature)( | 166 | ELFNAME2(linux,gcc_signature)( | |
167 | struct lwp *l, | 167 | struct lwp *l, | |
168 | struct exec_package *epp, | 168 | struct exec_package *epp, | |
169 | Elf_Ehdr *eh) | 169 | Elf_Ehdr *eh) | |
170 | { | 170 | { | |
171 | size_t shsize; | 171 | size_t shsize; | |
172 | size_t i; | 172 | size_t i; | |
173 | static const char signature[] = "\0GCC: (GNU) "; | 173 | static const char signature[] = "\0GCC: (GNU) "; | |
174 | char tbuf[sizeof(signature) - 1]; | 174 | char tbuf[sizeof(signature) - 1]; | |
175 | Elf_Shdr *sh; | 175 | Elf_Shdr *sh; | |
176 | int error; | 176 | int error; | |
177 | 177 | |||
178 | shsize = eh->e_shnum * sizeof(Elf_Shdr); | 178 | shsize = eh->e_shnum * sizeof(Elf_Shdr); | |
179 | sh = (Elf_Shdr *) malloc(shsize, M_TEMP, M_WAITOK); | 179 | sh = (Elf_Shdr *) malloc(shsize, M_TEMP, M_WAITOK); | |
180 | error = exec_read_from(l, epp->ep_vp, eh->e_shoff, sh, shsize); | 180 | error = exec_read_from(l, epp->ep_vp, eh->e_shoff, sh, shsize); | |
181 | if (error) | 181 | if (error) | |
182 | goto out; | 182 | goto out; | |
183 | 183 | |||
184 | for (i = 0; i < eh->e_shnum; i++) { | 184 | for (i = 0; i < eh->e_shnum; i++) { | |
185 | Elf_Shdr *s = &sh[i]; | 185 | Elf_Shdr *s = &sh[i]; | |
186 | 186 | |||
187 | /* | 187 | /* | |
188 | * Identify candidates for the comment header; | 188 | * Identify candidates for the comment header; | |
189 | * Header cannot have a load address, or flags and | 189 | * Header cannot have a load address, or flags and | |
190 | * it must be large enough. | 190 | * it must be large enough. | |
191 | */ | 191 | */ | |
192 | if (s->sh_type != SHT_PROGBITS || | 192 | if (s->sh_type != SHT_PROGBITS || | |
193 | s->sh_addr != 0 || | 193 | s->sh_addr != 0 || | |
194 | s->sh_flags != 0 || | 194 | s->sh_flags != 0 || | |
195 | s->sh_size < sizeof(signature) - 1) | 195 | s->sh_size < sizeof(signature) - 1) | |
196 | continue; | 196 | continue; | |
197 | 197 | |||
198 | error = exec_read_from(l, epp->ep_vp, s->sh_offset, tbuf, | 198 | error = exec_read_from(l, epp->ep_vp, s->sh_offset, tbuf, | |
199 | sizeof(signature) - 1); | 199 | sizeof(signature) - 1); | |
200 | if (error) | 200 | if (error) | |
201 | continue; | 201 | continue; | |
202 | 202 | |||
203 | /* | 203 | /* | |
204 | * error is 0, if the signatures match we are done. | 204 | * error is 0, if the signatures match we are done. | |
205 | */ | 205 | */ | |
206 | DPRINTF(("linux_gcc_sig: sig=%s\n", tbuf)); | 206 | DPRINTF(("linux_gcc_sig: sig=%s\n", tbuf)); | |
207 | if (!memcmp(tbuf, signature, sizeof(signature) - 1)) { | 207 | if (!memcmp(tbuf, signature, sizeof(signature) - 1)) { | |
208 | error = 0; | 208 | error = 0; | |
209 | goto out; | 209 | goto out; | |
210 | } | 210 | } | |
211 | } | 211 | } | |
212 | error = ENOEXEC; | 212 | error = ENOEXEC; | |
213 | 213 | |||
214 | out: | 214 | out: | |
215 | free(sh, M_TEMP); | 215 | free(sh, M_TEMP); | |
216 | return (error); | 216 | return (error); | |
217 | } | 217 | } | |
218 | #endif | 218 | #endif | |
219 | 219 | |||
220 | #ifdef LINUX_DEBUGLINK_SIGNATURE | 220 | #ifdef LINUX_DEBUGLINK_SIGNATURE | |
221 | /* | 221 | /* | |
222 | * Look for a .gnu_debuglink, specific to x86_64 interpeter | 222 | * Look for a .gnu_debuglink, specific to x86_64 interpeter | |
223 | */ | 223 | */ | |
224 | int | 224 | int | |
225 | ELFNAME2(linux,debuglink_signature)(struct lwp *l, struct exec_package *epp, Elf_Ehdr *eh) | 225 | ELFNAME2(linux,debuglink_signature)(struct lwp *l, struct exec_package *epp, Elf_Ehdr *eh) | |
226 | { | 226 | { | |
227 | size_t shsize; | 227 | size_t shsize; | |
228 | int strndx; | 228 | int strndx; | |
229 | size_t i; | 229 | size_t i; | |
230 | static const char signature[] = ".gnu_debuglink"; | 230 | static const char signature[] = ".gnu_debuglink"; | |
231 | char *strtable = NULL; | 231 | char *strtable = NULL; | |
232 | Elf_Shdr *sh; | 232 | Elf_Shdr *sh; | |
233 | 233 | |||
234 | int error; | 234 | int error; | |
235 | 235 | |||
236 | /* | 236 | /* | |
237 | * load the section header table | 237 | * load the section header table | |
238 | */ | 238 | */ | |
239 | shsize = eh->e_shnum * sizeof(Elf_Shdr); | 239 | shsize = eh->e_shnum * sizeof(Elf_Shdr); | |
240 | sh = (Elf_Shdr *) malloc(shsize, M_TEMP, M_WAITOK); | 240 | sh = (Elf_Shdr *) malloc(shsize, M_TEMP, M_WAITOK); | |
241 | error = exec_read_from(l, epp->ep_vp, eh->e_shoff, sh, shsize); | 241 | error = exec_read_from(l, epp->ep_vp, eh->e_shoff, sh, shsize); | |
242 | if (error) | 242 | if (error) | |
243 | goto out; | 243 | goto out; | |
244 | 244 | |||
245 | /* | 245 | /* | |
246 | * Now let's find the string table. If it does not exists, give up. | 246 | * Now let's find the string table. If it does not exists, give up. | |
247 | */ | 247 | */ | |
248 | strndx = (int)(eh->e_shstrndx); | 248 | strndx = (int)(eh->e_shstrndx); | |
249 | if (strndx == SHN_UNDEF) { | 249 | if (strndx == SHN_UNDEF) { | |
250 | error = ENOEXEC; | 250 | error = ENOEXEC; | |
251 | goto out; | 251 | goto out; | |
252 | } | 252 | } | |
253 | 253 | |||
254 | /* | 254 | /* | |
255 | * strndx is the index in section header table of the string table | 255 | * strndx is the index in section header table of the string table | |
256 | * section get the whole string table in strtable, and then we get access to the names | 256 | * section get the whole string table in strtable, and then we get access to the names | |
257 | * s->sh_name is the offset of the section name in strtable. | 257 | * s->sh_name is the offset of the section name in strtable. | |
258 | */ | 258 | */ | |
259 | strtable = malloc(sh[strndx].sh_size, M_TEMP, M_WAITOK); | 259 | strtable = malloc(sh[strndx].sh_size, M_TEMP, M_WAITOK); | |
260 | error = exec_read_from(l, epp->ep_vp, sh[strndx].sh_offset, strtable, | 260 | error = exec_read_from(l, epp->ep_vp, sh[strndx].sh_offset, strtable, | |
261 | sh[strndx].sh_size); | 261 | sh[strndx].sh_size); | |
262 | if (error) | 262 | if (error) | |
263 | goto out; | 263 | goto out; | |
264 | 264 | |||
265 | for (i = 0; i < eh->e_shnum; i++) { | 265 | for (i = 0; i < eh->e_shnum; i++) { | |
266 | Elf_Shdr *s = &sh[i]; | 266 | Elf_Shdr *s = &sh[i]; | |
267 | 267 | |||
268 | if (!memcmp((void*)(&(strtable[s->sh_name])), signature, | 268 | if (!memcmp((void*)(&(strtable[s->sh_name])), signature, | |
269 | sizeof(signature))) { | 269 | sizeof(signature))) { | |
270 | DPRINTF(("linux_debuglink_sig=%s\n", | 270 | DPRINTF(("linux_debuglink_sig=%s\n", | |
271 | &(strtable[s->sh_name]))); | 271 | &(strtable[s->sh_name]))); | |
272 | error = 0; | 272 | error = 0; | |
273 | goto out; | 273 | goto out; | |
274 | } | 274 | } | |
275 | } | 275 | } | |
276 | error = ENOEXEC; | 276 | error = ENOEXEC; | |
277 | 277 | |||
278 | out: | 278 | out: | |
279 | free(sh, M_TEMP); | 279 | free(sh, M_TEMP); | |
280 | if (strtable) | 280 | if (strtable) | |
281 | free(strtable, M_TEMP); | 281 | free(strtable, M_TEMP); | |
282 | return (error); | 282 | return (error); | |
283 | } | 283 | } | |
284 | #endif | 284 | #endif | |
285 | 285 | |||
286 | int | 286 | int | |
287 | ELFNAME2(linux,signature)(struct lwp *l, struct exec_package *epp, Elf_Ehdr *eh, char *itp) | 287 | ELFNAME2(linux,signature)(struct lwp *l, struct exec_package *epp, Elf_Ehdr *eh, char *itp) | |
288 | { | 288 | { | |
289 | size_t i; | 289 | size_t i; | |
290 | Elf_Phdr *ph; | 290 | Elf_Phdr *ph; | |
291 | size_t phsize; | 291 | size_t phsize; | |
292 | int error; | 292 | int error; | |
293 | static const char linux[] = "Linux"; | 293 | static const char linux[] = "Linux"; | |
294 | 294 | |||
295 | if (eh->e_ident[EI_OSABI] == 3 || | 295 | if (eh->e_ident[EI_OSABI] == 3 || | |
296 | memcmp(&eh->e_ident[EI_ABIVERSION], linux, sizeof(linux)) == 0) | 296 | memcmp(&eh->e_ident[EI_ABIVERSION], linux, sizeof(linux)) == 0) | |
297 | return 0; | 297 | return 0; | |
298 | 298 | |||
299 | phsize = eh->e_phnum * sizeof(Elf_Phdr); | 299 | phsize = eh->e_phnum * sizeof(Elf_Phdr); | |
300 | ph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK); | 300 | ph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK); | |
301 | error = exec_read_from(l, epp->ep_vp, eh->e_phoff, ph, phsize); | 301 | error = exec_read_from(l, epp->ep_vp, eh->e_phoff, ph, phsize); | |
302 | if (error) | 302 | if (error) | |
303 | goto out; | 303 | goto out; | |
304 | 304 | |||
305 | for (i = 0; i < eh->e_phnum; i++) { | 305 | for (i = 0; i < eh->e_phnum; i++) { | |
306 | Elf_Phdr *ephp = &ph[i]; | 306 | Elf_Phdr *ephp = &ph[i]; | |
307 | Elf_Nhdr *np; | 307 | Elf_Nhdr *np; | |
308 | u_int32_t *abi; | 308 | u_int32_t *abi; | |
309 | 309 | |||
310 | if (ephp->p_type != PT_NOTE || | 310 | if (ephp->p_type != PT_NOTE || | |
311 | ephp->p_filesz > 1024 || | 311 | ephp->p_filesz > 1024 || | |
312 | ephp->p_filesz < sizeof(Elf_Nhdr) + 20) | 312 | ephp->p_filesz < sizeof(Elf_Nhdr) + 20) | |
313 | continue; | 313 | continue; | |
314 | 314 | |||
315 | np = (Elf_Nhdr *)malloc(ephp->p_filesz, M_TEMP, M_WAITOK); | 315 | np = (Elf_Nhdr *)malloc(ephp->p_filesz, M_TEMP, M_WAITOK); | |
316 | error = exec_read_from(l, epp->ep_vp, ephp->p_offset, np, | 316 | error = exec_read_from(l, epp->ep_vp, ephp->p_offset, np, | |
317 | ephp->p_filesz); | 317 | ephp->p_filesz); | |
318 | if (error) | 318 | if (error) | |
319 | goto next; | 319 | goto next; | |
320 | 320 | |||
321 | if (np->n_type != ELF_NOTE_TYPE_ABI_TAG || | 321 | if (np->n_type != ELF_NOTE_TYPE_ABI_TAG || | |
322 | np->n_namesz != ELF_NOTE_ABI_NAMESZ || | 322 | np->n_namesz != ELF_NOTE_ABI_NAMESZ || | |
323 | np->n_descsz != ELF_NOTE_ABI_DESCSZ || | 323 | np->n_descsz != ELF_NOTE_ABI_DESCSZ || | |
324 | memcmp((void *)(np + 1), ELF_NOTE_ABI_NAME, | 324 | memcmp((void *)(np + 1), ELF_NOTE_ABI_NAME, | |
325 | ELF_NOTE_ABI_NAMESZ)) | 325 | ELF_NOTE_ABI_NAMESZ)) | |
326 | goto next; | 326 | goto next; | |
327 | 327 | |||
328 | /* Make sure the OS is Linux. */ | 328 | /* Make sure the OS is Linux. */ | |
329 | abi = (u_int32_t *)((char *)np + sizeof(Elf_Nhdr) + | 329 | abi = (u_int32_t *)((char *)np + sizeof(Elf_Nhdr) + | |
330 | np->n_namesz); | 330 | np->n_namesz); | |
331 | if (abi[0] == ELF_NOTE_ABI_OS_LINUX) | 331 | if (abi[0] == ELF_NOTE_ABI_OS_LINUX) | |
332 | error = 0; | 332 | error = 0; | |
333 | else | 333 | else | |
334 | error = ENOEXEC; | 334 | error = ENOEXEC; | |
335 | free(np, M_TEMP); | 335 | free(np, M_TEMP); | |
336 | goto out; | 336 | goto out; | |
337 | 337 | |||
338 | next: | 338 | next: | |
339 | free(np, M_TEMP); | 339 | free(np, M_TEMP); | |
340 | continue; | 340 | continue; | |
341 | } | 341 | } | |
342 | 342 | |||
343 | /* Check for certain intepreter names. */ | 343 | /* Check for certain intepreter names. */ | |
344 | if (itp) { | 344 | if (itp) { | |
345 | if (!strncmp(itp, "/lib/ld-linux", 13) || | 345 | if (!strncmp(itp, "/lib/ld-linux", 13) || | |
346 | #if (ELFSIZE == 64) | 346 | #if (ELFSIZE == 64) | |
347 | !strncmp(itp, "/lib64/ld-linux", 15) || | 347 | !strncmp(itp, "/lib64/ld-linux", 15) || | |
348 | #endif | 348 | #endif | |
349 | !strncmp(itp, "/lib/ld.so.", 11)) | 349 | !strncmp(itp, "/lib/ld.so.", 11)) | |
350 | error = 0; | 350 | error = 0; | |
351 | else | 351 | else | |
352 | error = ENOEXEC; | 352 | error = ENOEXEC; | |
353 | goto out; | 353 | goto out; | |
354 | } | 354 | } | |
355 | 355 | |||
356 | error = ENOEXEC; | 356 | error = ENOEXEC; | |
357 | out: | 357 | out: | |
358 | free(ph, M_TEMP); | 358 | free(ph, M_TEMP); | |
359 | return (error); | 359 | return (error); | |
360 | } | 360 | } | |
361 | 361 | |||
362 | int | 362 | int | |
363 | ELFNAME2(linux,probe)(struct lwp *l, struct exec_package *epp, void *eh, | 363 | ELFNAME2(linux,probe)(struct lwp *l, struct exec_package *epp, void *eh, | |
364 | char *itp, vaddr_t *pos) | 364 | char *itp, vaddr_t *pos) | |
365 | { | 365 | { | |
366 | int error; | 366 | int error; | |
367 | 367 | |||
368 | if (((error = ELFNAME2(linux,signature)(l, epp, eh, itp)) != 0) && | 368 | if (((error = ELFNAME2(linux,signature)(l, epp, eh, itp)) != 0) && | |
369 | #ifdef LINUX_GCC_SIGNATURE | 369 | #ifdef LINUX_GCC_SIGNATURE | |
370 | ((error = ELFNAME2(linux,gcc_signature)(l, epp, eh)) != 0) && | 370 | ((error = ELFNAME2(linux,gcc_signature)(l, epp, eh)) != 0) && | |
371 | #endif | 371 | #endif | |
372 | #ifdef LINUX_ATEXIT_SIGNATURE | 372 | #ifdef LINUX_ATEXIT_SIGNATURE | |
373 | ((error = ELFNAME2(linux,atexit_signature)(l, epp, eh)) != 0) && | 373 | ((error = ELFNAME2(linux,atexit_signature)(l, epp, eh)) != 0) && | |
374 | #endif | 374 | #endif | |
375 | #ifdef LINUX_DEBUGLINK_SIGNATURE | 375 | #ifdef LINUX_DEBUGLINK_SIGNATURE | |
376 | ((error = ELFNAME2(linux,debuglink_signature)(l, epp, eh)) != 0) && | 376 | ((error = ELFNAME2(linux,debuglink_signature)(l, epp, eh)) != 0) && | |
377 | #endif | 377 | #endif | |
378 | 1) { | 378 | 1) { | |
379 | DPRINTF(("linux_probe: returning %d\n", error)); | 379 | DPRINTF(("linux_probe: returning %d\n", error)); | |
380 | return error; | 380 | return error; | |
381 | } | 381 | } | |
382 | 382 | |||
383 | if (itp) { | 383 | if (itp) { | |
384 | if ((error = emul_find_interp(l, epp, itp))) | 384 | if ((error = emul_find_interp(l, epp, itp))) | |
385 | return (error); | 385 | return (error); | |
386 | } | 386 | } | |
387 | epp->ep_flags |= EXEC_FORCEAUX; | 387 | epp->ep_flags |= EXEC_FORCEAUX; | |
388 | DPRINTF(("linux_probe: returning 0\n")); | 388 | DPRINTF(("linux_probe: returning 0\n")); | |
389 | return 0; | 389 | return 0; | |
390 | } | 390 | } | |
391 | 391 | |||
392 | #ifndef LINUX_MACHDEP_ELF_COPYARGS | 392 | #ifndef LINUX_MACHDEP_ELF_COPYARGS | |
393 | /* | 393 | /* | |
394 | * Copy arguments onto the stack in the normal way, but add some | 394 | * Copy arguments onto the stack in the normal way, but add some | |
395 | * extra information in case of dynamic binding. | 395 | * extra information in case of dynamic binding. | |
396 | */ | 396 | */ | |
397 | int | 397 | int | |
398 | ELFNAME2(linux,copyargs)(struct lwp *l, struct exec_package *pack, | 398 | ELFNAME2(linux,copyargs)(struct lwp *l, struct exec_package *pack, | |
399 | struct ps_strings *arginfo, char **stackp, void *argp) | 399 | struct ps_strings *arginfo, char **stackp, void *argp) | |
400 | { | 400 | { | |
401 | size_t len; | 401 | size_t len; | |
402 | AuxInfo ai[LINUX_ELF_AUX_ENTRIES], *a; | 402 | AuxInfo ai[LINUX_ELF_AUX_ENTRIES], *a; | |
403 | struct elf_args *ap; | 403 | struct elf_args *ap; | |
404 | int error; | 404 | int error; | |
405 | struct vattr *vap; | 405 | struct vattr *vap; | |
406 | uint32_t randbytes[4]; | 406 | uint32_t randbytes[4]; | |
407 | 407 | |||
408 | if ((error = copyargs(l, pack, arginfo, stackp, argp)) != 0) | 408 | if ((error = copyargs(l, pack, arginfo, stackp, argp)) != 0) | |
409 | return error; | 409 | return error; | |
410 | 410 | |||
411 | a = ai; | 411 | a = ai; | |
412 | 412 | |||
413 | /* | 413 | /* | |
414 | * Push extra arguments used by glibc on the stack. | 414 | * Push extra arguments used by glibc on the stack. | |
415 | */ | 415 | */ | |
416 | 416 | |||
417 | a->a_type = AT_PAGESZ; | 417 | a->a_type = AT_PAGESZ; | |
418 | a->a_v = PAGE_SIZE; | 418 | a->a_v = PAGE_SIZE; | |
419 | a++; | 419 | a++; | |
420 | 420 | |||
421 | if ((ap = (struct elf_args *)pack->ep_emul_arg)) { | 421 | if ((ap = (struct elf_args *)pack->ep_emul_arg)) { | |
422 | 422 | |||
423 | a->a_type = AT_PHDR; | 423 | a->a_type = AT_PHDR; | |
424 | a->a_v = ap->arg_phaddr; | 424 | a->a_v = ap->arg_phaddr; | |
425 | a++; | 425 | a++; | |
426 | 426 | |||
427 | a->a_type = AT_PHENT; | 427 | a->a_type = AT_PHENT; | |
428 | a->a_v = ap->arg_phentsize; | 428 | a->a_v = ap->arg_phentsize; | |
429 | a++; | 429 | a++; | |
430 | 430 | |||
431 | a->a_type = AT_PHNUM; | 431 | a->a_type = AT_PHNUM; | |
432 | a->a_v = ap->arg_phnum; | 432 | a->a_v = ap->arg_phnum; | |
433 | a++; | 433 | a++; | |
434 | 434 | |||
435 | a->a_type = AT_BASE; | 435 | a->a_type = AT_BASE; | |
436 | a->a_v = ap->arg_interp; | 436 | a->a_v = ap->arg_interp; | |
437 | a++; | 437 | a++; | |
438 | 438 | |||
439 | a->a_type = AT_FLAGS; | 439 | a->a_type = AT_FLAGS; | |
440 | a->a_v = 0; | 440 | a->a_v = 0; | |
441 | a++; | 441 | a++; | |
442 | 442 | |||
443 | a->a_type = AT_ENTRY; | 443 | a->a_type = AT_ENTRY; | |
444 | a->a_v = ap->arg_entry; | 444 | a->a_v = ap->arg_entry; | |
445 | a++; | 445 | a++; | |
446 | 446 | |||
447 | exec_free_emul_arg(pack); | 447 | exec_free_emul_arg(pack); | |
448 | } | 448 | } | |
449 | 449 | |||
450 | /* Linux-specific items */ | 450 | /* Linux-specific items */ | |
451 | a->a_type = LINUX_AT_CLKTCK; | 451 | a->a_type = LINUX_AT_CLKTCK; | |
452 | a->a_v = hz; | 452 | a->a_v = hz; | |
453 | a++; | 453 | a++; | |
454 | 454 | |||
455 | vap = pack->ep_vap; | 455 | vap = pack->ep_vap; | |
456 | 456 | |||
457 | a->a_type = LINUX_AT_UID; | 457 | a->a_type = LINUX_AT_UID; | |
458 | a->a_v = kauth_cred_getuid(l->l_cred); | 458 | a->a_v = kauth_cred_getuid(l->l_cred); | |
459 | a++; | 459 | a++; | |
460 | 460 | |||
461 | a->a_type = LINUX_AT_EUID; | 461 | a->a_type = LINUX_AT_EUID; | |
462 | if (vap->va_mode & S_ISUID) | 462 | if (vap->va_mode & S_ISUID) | |
463 | a->a_v = vap->va_uid; | 463 | a->a_v = vap->va_uid; | |
464 | else | 464 | else | |
465 | a->a_v = kauth_cred_geteuid(l->l_cred); | 465 | a->a_v = kauth_cred_geteuid(l->l_cred); | |
466 | a++; | 466 | a++; | |
467 | 467 | |||
468 | a->a_type = LINUX_AT_GID; | 468 | a->a_type = LINUX_AT_GID; | |
469 | a->a_v = kauth_cred_getgid(l->l_cred); | 469 | a->a_v = kauth_cred_getgid(l->l_cred); | |
470 | a++; | 470 | a++; | |
471 | 471 | |||
472 | a->a_type = LINUX_AT_EGID; | 472 | a->a_type = LINUX_AT_EGID; | |
473 | if (vap->va_mode & S_ISGID) | 473 | if (vap->va_mode & S_ISGID) | |
474 | a->a_v = vap->va_gid; | 474 | a->a_v = vap->va_gid; | |
475 | else | 475 | else | |
476 | a->a_v = kauth_cred_getegid(l->l_cred); | 476 | a->a_v = kauth_cred_getegid(l->l_cred); | |
477 | a++; | 477 | a++; | |
478 | 478 | |||
479 | a->a_type = LINUX_AT_RANDOM; | 479 | a->a_type = LINUX_AT_RANDOM; | |
480 | a->a_v = (Elf_Addr)*stackp; | 480 | a->a_v = (Elf_Addr)*stackp; | |
481 | a++; | 481 | a++; | |
482 | 482 | |||
483 | a->a_type = AT_NULL; | 483 | a->a_type = AT_NULL; | |
484 | a->a_v = 0; | 484 | a->a_v = 0; | |
485 | a++; | 485 | a++; | |
486 | 486 | |||
487 | randbytes[0] = cprng_strong32(); | 487 | randbytes[0] = cprng_strong32(); | |
488 | randbytes[1] = cprng_strong32(); | 488 | randbytes[1] = cprng_strong32(); | |
489 | randbytes[2] = cprng_strong32(); | 489 | randbytes[2] = cprng_strong32(); | |
490 | randbytes[3] = cprng_strong32(); | 490 | randbytes[3] = cprng_strong32(); | |
491 | 491 | |||
492 | len = sizeof(randbytes); | 492 | len = sizeof(randbytes); | |
493 | if ((error = copyout(randbytes, *stackp, len)) != 0) | 493 | if ((error = copyout(randbytes, *stackp, len)) != 0) | |
494 | return error; | 494 | return error; | |
495 | *stackp += len; | 495 | *stackp += len; | |
496 | 496 | |||
497 | len = (a - ai) * sizeof(AuxInfo); | 497 | len = (a - ai) * sizeof(AuxInfo); | |
498 | KASSERT(len <= LINUX_ELF_AUX_ENTRIES); | |||
498 | if ((error = copyout(ai, *stackp, len)) != 0) | 499 | if ((error = copyout(ai, *stackp, len)) != 0) | |
499 | return error; | 500 | return error; | |
500 | *stackp += len; | 501 | *stackp += len; | |
501 | 502 | |||
502 | return 0; | 503 | return 0; | |
503 | } | 504 | } | |
504 | #endif /* !LINUX_MACHDEP_ELF_COPYARGS */ | 505 | #endif /* !LINUX_MACHDEP_ELF_COPYARGS */ |
--- src/sys/compat/linux32/arch/amd64/linux32_exec.h 2014/02/09 16:41:42 1.5
+++ src/sys/compat/linux32/arch/amd64/linux32_exec.h 2014/02/21 07:53:53 1.6
@@ -1,86 +1,87 @@ | @@ -1,86 +1,87 @@ | |||
1 | /* $NetBSD: linux32_exec.h,v 1.5 2014/02/09 16:41:42 chs Exp $ */ | 1 | /* $NetBSD: linux32_exec.h,v 1.6 2014/02/21 07:53:53 maxv Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved. | 4 | * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved. | |
5 | * | 5 | * | |
6 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions | 7 | * modification, are permitted provided that the following conditions | |
8 | * are met: | 8 | * are met: | |
9 | * 1. Redistributions of source code must retain the above copyright | 9 | * 1. Redistributions of source code must retain the above copyright | |
10 | * notice, this list of conditions and the following disclaimer. | 10 | * notice, this list of conditions and the following disclaimer. | |
11 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright | |
12 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the | |
13 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. | |
14 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. All advertising materials mentioning features or use of this software | |
15 | * must display the following acknowledgement: | 15 | * must display the following acknowledgement: | |
16 | * This product includes software developed by Emmanuel Dreyfus | 16 | * This product includes software developed by Emmanuel Dreyfus | |
17 | * 4. The name of the author may not be used to endorse or promote | 17 | * 4. The name of the author may not be used to endorse or promote | |
18 | * products derived from this software without specific prior written | 18 | * products derived from this software without specific prior written | |
19 | * permission. | 19 | * permission. | |
20 | * | 20 | * | |
21 | * THIS SOFTWARE IS PROVIDED BY THE THE AUTHOR AND CONTRIBUTORS ``AS IS'' | 21 | * THIS SOFTWARE IS PROVIDED BY THE THE AUTHOR AND CONTRIBUTORS ``AS IS'' | |
22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | 22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | |
23 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 23 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
24 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS | 24 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS | |
25 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 25 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
31 | * POSSIBILITY OF SUCH DAMAGE. | 31 | * POSSIBILITY OF SUCH DAMAGE. | |
32 | */ | 32 | */ | |
33 | #ifndef _AMD64_LINUX32_EXEC_H | 33 | #ifndef _AMD64_LINUX32_EXEC_H | |
34 | #define _AMD64_LINUX32_EXEC_H | 34 | #define _AMD64_LINUX32_EXEC_H | |
35 | 35 | |||
36 | #include <sys/exec_elf.h> | 36 | #include <sys/exec_elf.h> | |
37 | 37 | |||
38 | #define LINUX32_M_I386 100 | 38 | #define LINUX32_M_I386 100 | |
39 | #define LINUX32_MID_MACHINE LINUX_M_I386 | 39 | #define LINUX32_MID_MACHINE LINUX_M_I386 | |
40 | #define LINUX32_USRSTACK 0xC0000000 | 40 | #define LINUX32_USRSTACK 0xC0000000 | |
41 | 41 | |||
42 | #define LINUX32_DEBUGLINK_SIGNATURE 1 | 42 | #define LINUX32_DEBUGLINK_SIGNATURE 1 | |
43 | 43 | |||
44 | #define LINUX32_ELF_AUX_ENTRIES 14 | 44 | /* Counted from common/linux32_exec_elf32.c */ | |
45 | #define LINUX32_ELF_AUX_ENTRIES 15 | |||
45 | 46 | |||
46 | #define LINUX32_RANDOM_BYTES 16 /* 16 bytes for AT_RANDOM */ | 47 | #define LINUX32_RANDOM_BYTES 16 /* 16 bytes for AT_RANDOM */ | |
47 | 48 | |||
48 | #if 0 | 49 | #if 0 | |
49 | 50 | |||
50 | /* Hardware platform identifier string */ | 51 | /* Hardware platform identifier string */ | |
51 | #define LINUX32_PLATFORM "i686" | 52 | #define LINUX32_PLATFORM "i686" | |
52 | 53 | |||
53 | #define LINUX32_CPUCAP (cpu_feature[0]) | 54 | #define LINUX32_CPUCAP (cpu_feature[0]) | |
54 | 55 | |||
55 | /* vsyscall assembly */ | 56 | /* vsyscall assembly */ | |
56 | static char linux32_kernel_vsyscall[] = { | 57 | static char linux32_kernel_vsyscall[] = { | |
57 | 0x55, /* push %ebp */ \ | 58 | 0x55, /* push %ebp */ \ | |
58 | 0x89, 0xcd, /* mov %ecx,%ebp */ \ | 59 | 0x89, 0xcd, /* mov %ecx,%ebp */ \ | |
59 | 0x0f, 0x05, /* syscall */ \ | 60 | 0x0f, 0x05, /* syscall */ \ | |
60 | 0xb9, 0x7b, 0x00, 0x00, 0x00, /* mov $0x7b,%ecx */ \ | 61 | 0xb9, 0x7b, 0x00, 0x00, 0x00, /* mov $0x7b,%ecx */ \ | |
61 | 0x8e, 0xd1, /* movl %ecx,%ss */ \ | 62 | 0x8e, 0xd1, /* movl %ecx,%ss */ \ | |
62 | 0x89, 0xe9, /* mov %ebp,%ecx */ \ | 63 | 0x89, 0xe9, /* mov %ebp,%ecx */ \ | |
63 | 0x5d, /* pop %ebp */ \ | 64 | 0x5d, /* pop %ebp */ \ | |
64 | 0xc3, /* ret */ \ | 65 | 0xc3, /* ret */ \ | |
65 | }; | 66 | }; | |
66 | 67 | |||
67 | /* The extra data (ELF auxiliary table and platform name) on stack */ | 68 | /* The extra data (ELF auxiliary table and platform name) on stack */ | |
68 | struct linux32_extra_stack_data { | 69 | struct linux32_extra_stack_data { | |
69 | Aux32Info ai[LINUX32_ELF_AUX_ENTRIES]; | 70 | Aux32Info ai[LINUX32_ELF_AUX_ENTRIES]; | |
70 | char hw_platform[sizeof(LINUX32_PLATFORM)]; | 71 | char hw_platform[sizeof(LINUX32_PLATFORM)]; | |
71 | int pad; | 72 | int pad; | |
72 | Elf32_Ehdr elfhdr; | 73 | Elf32_Ehdr elfhdr; | |
73 | char kernel_vsyscall[sizeof(linux32_kernel_vsyscall)]; | 74 | char kernel_vsyscall[sizeof(linux32_kernel_vsyscall)]; | |
74 | }; | 75 | }; | |
75 | #define LINUX32_ELF_AUX_ARGSIZ sizeof(struct linux32_extra_stack_data) | 76 | #define LINUX32_ELF_AUX_ARGSIZ sizeof(struct linux32_extra_stack_data) | |
76 | 77 | |||
77 | #endif | 78 | #endif | |
78 | 79 | |||
79 | #define LINUX32_ELF_AUX_ARGSIZ \ | 80 | #define LINUX32_ELF_AUX_ARGSIZ \ | |
80 | (howmany(LINUX32_ELF_AUX_ENTRIES * sizeof(Aux32Info), sizeof(Elf32_Addr)) + LINUX32_RANDOM_BYTES) | 81 | (howmany(LINUX32_ELF_AUX_ENTRIES * sizeof(Aux32Info), sizeof(Elf32_Addr)) + LINUX32_RANDOM_BYTES) | |
81 | 82 | |||
82 | #ifdef _KERNEL | 83 | #ifdef _KERNEL | |
83 | int linux32_exec_setup_stack(struct lwp *, struct exec_package *); | 84 | int linux32_exec_setup_stack(struct lwp *, struct exec_package *); | |
84 | #endif | 85 | #endif | |
85 | 86 | |||
86 | #endif /* !_AMD64_LINUX32_EXEC_H */ | 87 | #endif /* !_AMD64_LINUX32_EXEC_H */ |
--- src/sys/compat/linux32/common/linux32_exec_elf32.c 2014/02/09 16:41:42 1.14
+++ src/sys/compat/linux32/common/linux32_exec_elf32.c 2014/02/21 07:53:53 1.15
@@ -1,247 +1,250 @@ | @@ -1,247 +1,250 @@ | |||
1 | /* $NetBSD: linux32_exec_elf32.c,v 1.14 2014/02/09 16:41:42 chs Exp $ */ | 1 | /* $NetBSD: linux32_exec_elf32.c,v 1.15 2014/02/21 07:53:53 maxv Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 1995, 1998, 2000, 2001,2006 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 1995, 1998, 2000, 2001,2006 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Christos Zoulas, Frank van der Linden, Eric Haszlakiewicz and | 8 | * by Christos Zoulas, Frank van der Linden, Eric Haszlakiewicz and | |
9 | * Emmanuel Dreyfus. | 9 | * Emmanuel Dreyfus. | |
10 | * | 10 | * | |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without | |
12 | * modification, are permitted provided that the following conditions | 12 | * modification, are permitted provided that the following conditions | |
13 | * are met: | 13 | * are met: | |
14 | * 1. Redistributions of source code must retain the above copyright | 14 | * 1. Redistributions of source code must retain the above copyright | |
15 | * notice, this list of conditions and the following disclaimer. | 15 | * notice, this list of conditions and the following disclaimer. | |
16 | * 2. Redistributions in binary form must reproduce the above copyright | 16 | * 2. Redistributions in binary form must reproduce the above copyright | |
17 | * notice, this list of conditions and the following disclaimer in the | 17 | * notice, this list of conditions and the following disclaimer in the | |
18 | * documentation and/or other materials provided with the distribution. | 18 | * documentation and/or other materials provided with the distribution. | |
19 | * | 19 | * | |
20 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | 20 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
21 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 21 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
24 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 24 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
30 | * POSSIBILITY OF SUCH DAMAGE. | 30 | * POSSIBILITY OF SUCH DAMAGE. | |
31 | */ | 31 | */ | |
32 | 32 | |||
33 | #include <sys/cdefs.h> | 33 | #include <sys/cdefs.h> | |
34 | __KERNEL_RCSID(0, "$NetBSD: linux32_exec_elf32.c,v 1.14 2014/02/09 16:41:42 chs Exp $"); | 34 | __KERNEL_RCSID(0, "$NetBSD: linux32_exec_elf32.c,v 1.15 2014/02/21 07:53:53 maxv Exp $"); | |
35 | 35 | |||
36 | #define ELFSIZE 32 | 36 | #define ELFSIZE 32 | |
37 | 37 | |||
38 | #include <sys/param.h> | 38 | #include <sys/param.h> | |
39 | #include <sys/systm.h> | 39 | #include <sys/systm.h> | |
40 | #include <sys/proc.h> | 40 | #include <sys/proc.h> | |
41 | #include <sys/vnode.h> | 41 | #include <sys/vnode.h> | |
42 | #include <sys/exec.h> | 42 | #include <sys/exec.h> | |
43 | #include <sys/exec_elf.h> | 43 | #include <sys/exec_elf.h> | |
44 | #include <sys/kauth.h> | 44 | #include <sys/kauth.h> | |
45 | #include <sys/kernel.h> | 45 | #include <sys/kernel.h> | |
46 | #include <sys/resourcevar.h> | 46 | #include <sys/resourcevar.h> | |
47 | #include <sys/signal.h> | 47 | #include <sys/signal.h> | |
48 | #include <sys/signalvar.h> | 48 | #include <sys/signalvar.h> | |
49 | #include <sys/cprng.h> | 49 | #include <sys/cprng.h> | |
50 | 50 | |||
51 | #include <compat/linux/common/linux_exec.h> | 51 | #include <compat/linux/common/linux_exec.h> | |
52 | #include <compat/netbsd32/netbsd32.h> | 52 | #include <compat/netbsd32/netbsd32.h> | |
53 | #include <compat/netbsd32/netbsd32_exec.h> | 53 | #include <compat/netbsd32/netbsd32_exec.h> | |
54 | #include <compat/linux32/common/linux32_exec.h> | 54 | #include <compat/linux32/common/linux32_exec.h> | |
55 | 55 | |||
56 | #include <machine/cpuvar.h> | 56 | #include <machine/cpuvar.h> | |
57 | #include <machine/frame.h> | 57 | #include <machine/frame.h> | |
58 | 58 | |||
59 | #ifdef DEBUG_LINUX | 59 | #ifdef DEBUG_LINUX | |
60 | #define DPRINTF(a) uprintf a | 60 | #define DPRINTF(a) uprintf a | |
61 | #else | 61 | #else | |
62 | #define DPRINTF(a) | 62 | #define DPRINTF(a) | |
63 | #endif | 63 | #endif | |
64 | 64 | |||
65 | int linux32_copyinargs(struct exec_package *, struct ps_strings *, | 65 | int linux32_copyinargs(struct exec_package *, struct ps_strings *, | |
66 | void *, size_t, const void *, const void *); | 66 | void *, size_t, const void *, const void *); | |
67 | 67 | |||
68 | int | 68 | int | |
69 | ELFNAME2(linux32,probe)(struct lwp *l, struct exec_package *epp, | 69 | ELFNAME2(linux32,probe)(struct lwp *l, struct exec_package *epp, | |
70 | void *eh, char *itp, vaddr_t *pos) | 70 | void *eh, char *itp, vaddr_t *pos) | |
71 | { | 71 | { | |
72 | int error; | 72 | int error; | |
73 | 73 | |||
74 | if (((error = ELFNAME2(linux,signature)(l, epp, eh, itp)) != 0) && | 74 | if (((error = ELFNAME2(linux,signature)(l, epp, eh, itp)) != 0) && | |
75 | #ifdef LINUX32_GCC_SIGNATURE | 75 | #ifdef LINUX32_GCC_SIGNATURE | |
76 | ((error = ELFNAME2(linux,gcc_signature)(l, epp, eh)) != 0) && | 76 | ((error = ELFNAME2(linux,gcc_signature)(l, epp, eh)) != 0) && | |
77 | #endif | 77 | #endif | |
78 | #ifdef LINUX32_ATEXIT_SIGNATURE | 78 | #ifdef LINUX32_ATEXIT_SIGNATURE | |
79 | ((error = ELFNAME2(linux,atexit_signature)(l, epp, eh)) != 0) && | 79 | ((error = ELFNAME2(linux,atexit_signature)(l, epp, eh)) != 0) && | |
80 | #endif | 80 | #endif | |
81 | #ifdef LINUX32_DEBUGLINK_SIGNATURE | 81 | #ifdef LINUX32_DEBUGLINK_SIGNATURE | |
82 | ((error = ELFNAME2(linux,debuglink_signature)(l, epp, eh)) != 0) && | 82 | ((error = ELFNAME2(linux,debuglink_signature)(l, epp, eh)) != 0) && | |
83 | #endif | 83 | #endif | |
84 | 1) | 84 | 1) | |
85 | return error; | 85 | return error; | |
86 | 86 | |||
87 | if (itp) { | 87 | if (itp) { | |
88 | if ((error = emul_find_interp(l, epp, itp))) | 88 | if ((error = emul_find_interp(l, epp, itp))) | |
89 | return (error); | 89 | return (error); | |
90 | } | 90 | } | |
91 | #if 0 | 91 | #if 0 | |
92 | DPRINTF(("linux32_probe: returning 0\n")); | 92 | DPRINTF(("linux32_probe: returning 0\n")); | |
93 | #endif | 93 | #endif | |
94 | 94 | |||
95 | epp->ep_flags |= EXEC_32 | EXEC_FORCEAUX; | 95 | epp->ep_flags |= EXEC_32 | EXEC_FORCEAUX; | |
96 | epp->ep_vm_minaddr = VM_MIN_ADDRESS; | 96 | epp->ep_vm_minaddr = VM_MIN_ADDRESS; | |
97 | epp->ep_vm_maxaddr = USRSTACK32; | 97 | epp->ep_vm_maxaddr = USRSTACK32; | |
98 | 98 | |||
99 | return 0; | 99 | return 0; | |
100 | } | 100 | } | |
101 | 101 | |||
102 | /* | 102 | /* | |
103 | * Copy arguments onto the stack in the normal way, but add some | 103 | * Copy arguments onto the stack in the normal way, but add some | |
104 | * extra information in case of dynamic binding. | 104 | * extra information in case of dynamic binding. | |
105 | */ | 105 | */ | |
106 | int | 106 | int | |
107 | linux32_elf32_copyargs(struct lwp *l, struct exec_package *pack, | 107 | linux32_elf32_copyargs(struct lwp *l, struct exec_package *pack, | |
108 | struct ps_strings *arginfo, char **stackp, void *argp) | 108 | struct ps_strings *arginfo, char **stackp, void *argp) | |
109 | { | 109 | { | |
110 | Aux32Info ai[LINUX32_ELF_AUX_ENTRIES], *a; | 110 | Aux32Info ai[LINUX32_ELF_AUX_ENTRIES], *a; | |
111 | uint32_t randbytes[4]; | 111 | uint32_t randbytes[4]; | |
112 | struct elf_args *ap; | 112 | struct elf_args *ap; | |
113 | struct vattr *vap; | 113 | struct vattr *vap; | |
114 | size_t len; | 114 | size_t len; | |
115 | int error; | 115 | int error; | |
116 | 116 | |||
117 | if ((error = netbsd32_copyargs(l, pack, arginfo, stackp, argp)) != 0) | 117 | if ((error = netbsd32_copyargs(l, pack, arginfo, stackp, argp)) != 0) | |
118 | return error; | 118 | return error; | |
119 | 119 | |||
120 | a = ai; | 120 | a = ai; | |
121 | 121 | |||
122 | /* | 122 | /* | |
123 | * Push extra arguments on the stack needed by dynamically | 123 | * Push extra arguments on the stack needed by dynamically | |
124 | * linked binaries and static binaries as well. | 124 | * linked binaries and static binaries as well. | |
125 | */ | 125 | */ | |
126 | 126 | |||
127 | a->a_type = AT_PAGESZ; | 127 | a->a_type = AT_PAGESZ; | |
128 | a->a_v = PAGE_SIZE; | 128 | a->a_v = PAGE_SIZE; | |
129 | a++; | 129 | a++; | |
130 | 130 | |||
131 | if ((ap = (struct elf_args *)pack->ep_emul_arg)) { | 131 | if ((ap = (struct elf_args *)pack->ep_emul_arg)) { | |
132 | 132 | |||
133 | a->a_type = AT_PHDR; | 133 | a->a_type = AT_PHDR; | |
134 | a->a_v = ap->arg_phaddr; | 134 | a->a_v = ap->arg_phaddr; | |
135 | a++; | 135 | a++; | |
136 | 136 | |||
137 | a->a_type = AT_PHENT; | 137 | a->a_type = AT_PHENT; | |
138 | a->a_v = ap->arg_phentsize; | 138 | a->a_v = ap->arg_phentsize; | |
139 | a++; | 139 | a++; | |
140 | 140 | |||
141 | a->a_type = AT_PHNUM; | 141 | a->a_type = AT_PHNUM; | |
142 | a->a_v = ap->arg_phnum; | 142 | a->a_v = ap->arg_phnum; | |
143 | a++; | 143 | a++; | |
144 | 144 | |||
145 | a->a_type = AT_BASE; | 145 | a->a_type = AT_BASE; | |
146 | a->a_v = ap->arg_interp; | 146 | a->a_v = ap->arg_interp; | |
147 | a++; | 147 | a++; | |
148 | 148 | |||
149 | a->a_type = AT_FLAGS; | 149 | a->a_type = AT_FLAGS; | |
150 | a->a_v = 0; | 150 | a->a_v = 0; | |
151 | a++; | 151 | a++; | |
152 | 152 | |||
153 | a->a_type = AT_ENTRY; | 153 | a->a_type = AT_ENTRY; | |
154 | a->a_v = ap->arg_entry; | 154 | a->a_v = ap->arg_entry; | |
155 | a++; | 155 | a++; | |
156 | 156 | |||
157 | exec_free_emul_arg(pack); | 157 | exec_free_emul_arg(pack); | |
158 | } | 158 | } | |
159 | 159 | |||
160 | /* Linux-specific items */ | 160 | /* Linux-specific items */ | |
161 | a->a_type = LINUX_AT_CLKTCK; | 161 | a->a_type = LINUX_AT_CLKTCK; | |
162 | a->a_v = hz; | 162 | a->a_v = hz; | |
163 | a++; | 163 | a++; | |
164 | 164 | |||
165 | vap = pack->ep_vap; | 165 | vap = pack->ep_vap; | |
166 | 166 | |||
167 | a->a_type = LINUX_AT_UID; | 167 | a->a_type = LINUX_AT_UID; | |
168 | a->a_v = kauth_cred_getuid(l->l_cred); | 168 | a->a_v = kauth_cred_getuid(l->l_cred); | |
169 | a++; | 169 | a++; | |
170 | 170 | |||
171 | a->a_type = LINUX_AT_EUID; | 171 | a->a_type = LINUX_AT_EUID; | |
172 | a->a_v = ((vap->va_mode & S_ISUID) ? | 172 | a->a_v = ((vap->va_mode & S_ISUID) ? | |
173 | vap->va_uid : kauth_cred_geteuid(l->l_cred)); | 173 | vap->va_uid : kauth_cred_geteuid(l->l_cred)); | |
174 | a++; | 174 | a++; | |
175 | 175 | |||
176 | a->a_type = LINUX_AT_GID; | 176 | a->a_type = LINUX_AT_GID; | |
177 | a->a_v = kauth_cred_getgid(l->l_cred); | 177 | a->a_v = kauth_cred_getgid(l->l_cred); | |
178 | a++; | 178 | a++; | |
179 | 179 | |||
180 | a->a_type = LINUX_AT_EGID; | 180 | a->a_type = LINUX_AT_EGID; | |
181 | a->a_v = ((vap->va_mode & S_ISGID) ? | 181 | a->a_v = ((vap->va_mode & S_ISGID) ? | |
182 | vap->va_gid : kauth_cred_getegid(l->l_cred)); | 182 | vap->va_gid : kauth_cred_getegid(l->l_cred)); | |
183 | a++; | 183 | a++; | |
184 | 184 | |||
185 | a->a_type = LINUX_AT_SECURE; | 185 | a->a_type = LINUX_AT_SECURE; | |
186 | a->a_v = 0; | 186 | a->a_v = 0; | |
187 | a++; | 187 | a++; | |
188 | 188 | |||
189 | a->a_type = LINUX_AT_RANDOM; | 189 | a->a_type = LINUX_AT_RANDOM; | |
190 | a->a_v = NETBSD32PTR32I(*stackp); | 190 | a->a_v = NETBSD32PTR32I(*stackp); | |
191 | a++; | 191 | a++; | |
192 | 192 | |||
193 | #if 0 | 193 | #if 0 | |
194 | /* XXX: increase LINUX32_ELF_AUX_ENTRIES if we enable those things */ | |||
195 | ||||
194 | a->a_type = LINUX_AT_SYSINFO; | 196 | a->a_type = LINUX_AT_SYSINFO; | |
195 | a->a_v = NETBSD32PTR32I(&esdp->kernel_vsyscall[0]); | 197 | a->a_v = NETBSD32PTR32I(&esdp->kernel_vsyscall[0]); | |
196 | a++; | 198 | a++; | |
197 | 199 | |||
198 | a->a_type = LINUX_AT_SYSINFO_EHDR; | 200 | a->a_type = LINUX_AT_SYSINFO_EHDR; | |
199 | a->a_v = NETBSD32PTR32I(&esdp->elfhdr); | 201 | a->a_v = NETBSD32PTR32I(&esdp->elfhdr); | |
200 | a++; | 202 | a++; | |
201 | 203 | |||
202 | a->a_type = LINUX_AT_HWCAP; | 204 | a->a_type = LINUX_AT_HWCAP; | |
203 | a->a_v = LINUX32_CPUCAP; | 205 | a->a_v = LINUX32_CPUCAP; | |
204 | a++; | 206 | a++; | |
205 | 207 | |||
206 | a->a_type = LINUX_AT_PLATFORM; | 208 | a->a_type = LINUX_AT_PLATFORM; | |
207 | a->a_v = NETBSD32PTR32I(&esdp->hw_platform[0]); | 209 | a->a_v = NETBSD32PTR32I(&esdp->hw_platform[0]); | |
208 | a++; | 210 | a++; | |
209 | #endif | 211 | #endif | |
210 | 212 | |||
211 | a->a_type = AT_NULL; | 213 | a->a_type = AT_NULL; | |
212 | a->a_v = 0; | 214 | a->a_v = 0; | |
213 | a++; | 215 | a++; | |
214 | 216 | |||
215 | randbytes[0] = cprng_strong32(); | 217 | randbytes[0] = cprng_strong32(); | |
216 | randbytes[1] = cprng_strong32(); | 218 | randbytes[1] = cprng_strong32(); | |
217 | randbytes[2] = cprng_strong32(); | 219 | randbytes[2] = cprng_strong32(); | |
218 | randbytes[3] = cprng_strong32(); | 220 | randbytes[3] = cprng_strong32(); | |
219 | 221 | |||
220 | len = sizeof(randbytes); | 222 | len = sizeof(randbytes); | |
221 | if ((error = copyout(randbytes, *stackp, len)) != 0) | 223 | if ((error = copyout(randbytes, *stackp, len)) != 0) | |
222 | return error; | 224 | return error; | |
223 | *stackp += len; | 225 | *stackp += len; | |
224 | 226 | |||
225 | #if 0 | 227 | #if 0 | |
226 | memcpy(esd.kernel_vsyscall, linux32_kernel_vsyscall, | 228 | memcpy(esd.kernel_vsyscall, linux32_kernel_vsyscall, | |
227 | sizeof(linux32_kernel_vsyscall)); | 229 | sizeof(linux32_kernel_vsyscall)); | |
228 | 230 | |||
229 | memcpy(&esd.elfhdr, eh, sizeof(*eh)); | 231 | memcpy(&esd.elfhdr, eh, sizeof(*eh)); | |
230 | 232 | |||
231 | strcpy(esd.hw_platform, LINUX32_PLATFORM); | 233 | strcpy(esd.hw_platform, LINUX32_PLATFORM); | |
232 | 234 | |||
233 | /* | 235 | /* | |
234 | * Copy out the ELF auxiliary table and hw platform name | 236 | * Copy out the ELF auxiliary table and hw platform name | |
235 | */ | 237 | */ | |
236 | if ((error = copyout(&esd, esdp, sizeof(esd))) != 0) | 238 | if ((error = copyout(&esd, esdp, sizeof(esd))) != 0) | |
237 | return error; | 239 | return error; | |
238 | *stackp += sizeof(esd); | 240 | *stackp += sizeof(esd); | |
239 | #endif | 241 | #endif | |
240 | 242 | |||
241 | len = (a - ai) * sizeof(AuxInfo); | 243 | len = (a - ai) * sizeof(AuxInfo); | |
244 | KASSERT(len <= LINUX32_ELF_AUX_ENTRIES); | |||
242 | if ((error = copyout(ai, *stackp, len)) != 0) | 245 | if ((error = copyout(ai, *stackp, len)) != 0) | |
243 | return error; | 246 | return error; | |
244 | *stackp += len; | 247 | *stackp += len; | |
245 | 248 | |||
246 | return 0; | 249 | return 0; | |
247 | } | 250 | } |