1 /*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include "los_load_elf.h"
33 #include "fcntl.h"
34 #include "fs/fd_table.h"
35 #include "fs/file.h"
36 #include "fs/fs_operation.h"
37 #include "los_config.h"
38 #include "los_vm_map.h"
39 #include "los_vm_syscall.h"
40 #include "los_vm_phys.h"
41 #include "los_vm_dump.h"
42 #include "los_vm_lock.h"
43 #ifdef LOSCFG_KERNEL_VDSO
44 #include "los_vdso.h"
45 #endif
46 #ifdef LOSCFG_DRIVERS_TZDRIVER
47 #include "tzdriver.h"
48 #endif
49
50 STATIC BOOL g_srandInit;
51
OsELFOpen(const CHAR * fileName,INT32 oflags)52 STATIC INT32 OsELFOpen(const CHAR *fileName, INT32 oflags)
53 {
54 INT32 ret;
55 INT32 procFd;
56
57 procFd = AllocProcessFd();
58 if (procFd < 0) {
59 return -EMFILE;
60 }
61
62 if (oflags & O_CLOEXEC) {
63 SetCloexecFlag(procFd);
64 }
65
66 ret = open(fileName, oflags);
67 if (ret < 0) {
68 FreeProcessFd(procFd);
69 return -get_errno();
70 }
71
72 AssociateSystemFd(procFd, ret);
73 return procFd;
74 }
75
OsELFClose(INT32 procFd)76 STATIC INT32 OsELFClose(INT32 procFd)
77 {
78 INT32 ret;
79 /* Process procfd convert to system global procfd */
80 INT32 sysfd = DisassociateProcessFd(procFd);
81 if (sysfd < 0) {
82 return -EBADF;
83 }
84
85 ret = close(sysfd);
86 if (ret < 0) {
87 AssociateSystemFd(procFd, sysfd);
88 return -get_errno();
89 }
90 FreeProcessFd(procFd);
91 return ret;
92 }
93
OsGetFileLength(UINT32 * fileLen,const CHAR * fileName)94 STATIC INT32 OsGetFileLength(UINT32 *fileLen, const CHAR *fileName)
95 {
96 struct stat buf;
97 INT32 ret;
98
99 ret = stat(fileName, &buf);
100 if (ret < 0) {
101 #ifndef LOSCFG_SHELL
102 if (strcmp(fileName, "/bin/shell") != 0) {
103 #endif
104 PRINT_ERR("%s[%d], Failed to stat file: %s, errno: %d\n", __FUNCTION__, __LINE__, fileName, errno);
105 #ifndef LOSCFG_SHELL
106 }
107 #endif
108 return LOS_NOK;
109 }
110
111 if (S_ISREG(buf.st_mode) == 0) {
112 PRINT_ERR("%s[%d], The file: %s is invalid!\n", __FUNCTION__, __LINE__, fileName);
113 return LOS_NOK;
114 }
115 if (buf.st_size > FILE_LENGTH_MAX) {
116 PRINT_ERR("%s[%d], The file: %s length is out of limit!\n", __FUNCTION__, __LINE__, fileName);
117 return LOS_NOK;
118 }
119
120 *fileLen = (UINT32)buf.st_size;
121 return LOS_OK;
122 }
123
OsReadELFInfo(INT32 procfd,UINT8 * buffer,size_t readSize,off_t offset)124 STATIC INT32 OsReadELFInfo(INT32 procfd, UINT8 *buffer, size_t readSize, off_t offset)
125 {
126 ssize_t byteNum;
127 off_t returnPos;
128 INT32 fd = GetAssociatedSystemFd(procfd);
129 if (fd < 0) {
130 PRINT_ERR("%s[%d], Invalid procfd!\n", __FUNCTION__, __LINE__);
131 return LOS_NOK;
132 }
133
134 if (readSize > 0) {
135 returnPos = lseek(fd, offset, SEEK_SET);
136 if (returnPos != offset) {
137 PRINT_ERR("%s[%d], Failed to seek the position!, offset: %#x\n", __FUNCTION__, __LINE__, offset);
138 return LOS_NOK;
139 }
140
141 byteNum = read(fd, buffer, readSize);
142 if (byteNum <= 0) {
143 PRINT_ERR("%s[%d], Failed to read from offset: %#x!\n", __FUNCTION__, __LINE__, offset);
144 return LOS_NOK;
145 }
146 }
147 return LOS_OK;
148 }
149
OsVerifyELFEhdr(const LD_ELF_EHDR * ehdr,UINT32 fileLen)150 STATIC INT32 OsVerifyELFEhdr(const LD_ELF_EHDR *ehdr, UINT32 fileLen)
151 {
152 if (memcmp(ehdr->elfIdent, LD_ELFMAG, LD_SELFMAG) != 0) {
153 PRINT_ERR("%s[%d], The file is not elf!\n", __FUNCTION__, __LINE__);
154 return LOS_NOK;
155 }
156 if ((ehdr->elfType != LD_ET_EXEC) && (ehdr->elfType != LD_ET_DYN)) {
157 PRINT_ERR("%s[%d], The type of file is not ET_EXEC or ET_DYN!\n", __FUNCTION__, __LINE__);
158 return LOS_NOK;
159 }
160 if (ehdr->elfMachine != LD_EM_ARM) {
161 PRINT_ERR("%s[%d], The type of machine is not EM_ARM!\n", __FUNCTION__, __LINE__);
162 return LOS_NOK;
163 }
164 if (ehdr->elfPhNum > ELF_PHDR_NUM_MAX) {
165 PRINT_ERR("%s[%d], The num of program header is out of limit\n", __FUNCTION__, __LINE__);
166 return LOS_NOK;
167 }
168 if (ehdr->elfPhoff > fileLen) {
169 PRINT_ERR("%s[%d], The offset of program header is invalid, elf file is bad\n", __FUNCTION__, __LINE__);
170 return LOS_NOK;
171 }
172 if (OsIsBadUserAddress((VADDR_T)ehdr->elfEntry)) {
173 PRINT_ERR("%s[%d], The entry of program is invalid\n", __FUNCTION__, __LINE__);
174 return LOS_NOK;
175 }
176
177 return LOS_OK;
178 }
179
OsVerifyELFPhdr(const LD_ELF_PHDR * phdr)180 STATIC INT32 OsVerifyELFPhdr(const LD_ELF_PHDR *phdr)
181 {
182 if ((phdr->fileSize > FILE_LENGTH_MAX) || (phdr->offset > FILE_LENGTH_MAX)) {
183 PRINT_ERR("%s[%d], The size of phdr is out of limit\n", __FUNCTION__, __LINE__);
184 return LOS_NOK;
185 }
186 if (phdr->memSize > MEM_SIZE_MAX) {
187 PRINT_ERR("%s[%d], The mem size of phdr is out of limit\n", __FUNCTION__, __LINE__);
188 return LOS_NOK;
189 }
190 if (OsIsBadUserAddress((VADDR_T)phdr->vAddr)) {
191 PRINT_ERR("%s[%d], The vaddr of phdr is invalid\n", __FUNCTION__, __LINE__);
192 return LOS_NOK;
193 }
194
195 return LOS_OK;
196 }
197
OsLoadInit(ELFLoadInfo * loadInfo)198 STATIC VOID OsLoadInit(ELFLoadInfo *loadInfo)
199 {
200 #ifdef LOSCFG_FS_VFS
201 const struct files_struct *oldFiles = OsCurrProcessGet()->files;
202 loadInfo->oldFiles = (UINTPTR)create_files_snapshot(oldFiles);
203 #else
204 loadInfo->oldFiles = NULL;
205 #endif
206 loadInfo->execInfo.procfd = INVALID_FD;
207 loadInfo->interpInfo.procfd = INVALID_FD;
208 }
209
OsReadEhdr(const CHAR * fileName,ELFInfo * elfInfo,BOOL isExecFile)210 STATIC INT32 OsReadEhdr(const CHAR *fileName, ELFInfo *elfInfo, BOOL isExecFile)
211 {
212 INT32 ret;
213
214 ret = OsGetFileLength(&elfInfo->fileLen, fileName);
215 if (ret != LOS_OK) {
216 return -ENOENT;
217 }
218
219 ret = OsELFOpen(fileName, O_RDONLY | O_EXECVE | O_CLOEXEC);
220 if (ret < 0) {
221 PRINT_ERR("%s[%d], Failed to open ELF file: %s!\n", __FUNCTION__, __LINE__, fileName);
222 return ret;
223 }
224 elfInfo->procfd = ret;
225
226 #ifdef LOSCFG_DRIVERS_TZDRIVER
227 if (isExecFile) {
228 struct file *filep = NULL;
229 ret = fs_getfilep(GetAssociatedSystemFd(elfInfo->procfd), &filep);
230 if (ret) {
231 PRINT_ERR("%s[%d], Failed to get struct file %s!\n", __FUNCTION__, __LINE__, fileName);
232 /* File will be closed by OsLoadELFFile */
233 return ret;
234 }
235 OsCurrProcessGet()->execVnode = filep->f_vnode;
236 }
237 #endif
238 ret = OsReadELFInfo(elfInfo->procfd, (UINT8 *)&elfInfo->elfEhdr, sizeof(LD_ELF_EHDR), 0);
239 if (ret != LOS_OK) {
240 PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__);
241 return -EIO;
242 }
243
244 ret = OsVerifyELFEhdr(&elfInfo->elfEhdr, elfInfo->fileLen);
245 if (ret != LOS_OK) {
246 PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__);
247 return isExecFile ? -ENOEXEC : -ELIBBAD;
248 }
249
250 return LOS_OK;
251 }
252
OsReadPhdrs(ELFInfo * elfInfo,BOOL isExecFile)253 STATIC INT32 OsReadPhdrs(ELFInfo *elfInfo, BOOL isExecFile)
254 {
255 LD_ELF_EHDR *elfEhdr = &elfInfo->elfEhdr;
256 UINT32 size;
257 INT32 ret;
258
259 if (elfEhdr->elfPhNum < 1) {
260 goto OUT;
261 }
262
263 if (elfEhdr->elfPhEntSize != sizeof(LD_ELF_PHDR)) {
264 goto OUT;
265 }
266
267 size = sizeof(LD_ELF_PHDR) * elfEhdr->elfPhNum;
268 if ((elfEhdr->elfPhoff + size) > elfInfo->fileLen) {
269 goto OUT;
270 }
271
272 elfInfo->elfPhdr = LOS_MemAlloc(m_aucSysMem0, size);
273 if (elfInfo->elfPhdr == NULL) {
274 PRINT_ERR("%s[%d], Failed to allocate for elfPhdr!\n", __FUNCTION__, __LINE__);
275 return -ENOMEM;
276 }
277
278 ret = OsReadELFInfo(elfInfo->procfd, (UINT8 *)elfInfo->elfPhdr, size, elfEhdr->elfPhoff);
279 if (ret != LOS_OK) {
280 (VOID)LOS_MemFree(m_aucSysMem0, elfInfo->elfPhdr);
281 elfInfo->elfPhdr = NULL;
282 PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__);
283 return -EIO;
284 }
285
286 return LOS_OK;
287 OUT:
288 PRINT_ERR("%s[%d], elf file is bad!\n", __FUNCTION__, __LINE__);
289 return isExecFile ? -ENOEXEC : -ELIBBAD;
290 }
291
OsReadInterpInfo(ELFLoadInfo * loadInfo)292 STATIC INT32 OsReadInterpInfo(ELFLoadInfo *loadInfo)
293 {
294 LD_ELF_PHDR *elfPhdr = loadInfo->execInfo.elfPhdr;
295 CHAR *elfInterpName = NULL;
296 INT32 ret, i;
297
298 for (i = 0; i < loadInfo->execInfo.elfEhdr.elfPhNum; ++i, ++elfPhdr) {
299 if (elfPhdr->type != LD_PT_INTERP) {
300 continue;
301 }
302
303 if (OsVerifyELFPhdr(elfPhdr) != LOS_OK) {
304 return -ENOEXEC;
305 }
306
307 if ((elfPhdr->fileSize > FILE_PATH_MAX) || (elfPhdr->fileSize < FILE_PATH_MIN) ||
308 (elfPhdr->offset + elfPhdr->fileSize > loadInfo->execInfo.fileLen)) {
309 PRINT_ERR("%s[%d], The size of file is out of limit!\n", __FUNCTION__, __LINE__);
310 return -ENOEXEC;
311 }
312
313 elfInterpName = LOS_MemAlloc(m_aucSysMem0, elfPhdr->fileSize);
314 if (elfInterpName == NULL) {
315 PRINT_ERR("%s[%d], Failed to allocate for elfInterpName!\n", __FUNCTION__, __LINE__);
316 return -ENOMEM;
317 }
318
319 ret = OsReadELFInfo(loadInfo->execInfo.procfd, (UINT8 *)elfInterpName, elfPhdr->fileSize, elfPhdr->offset);
320 if (ret != LOS_OK) {
321 PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__);
322 ret = -EIO;
323 goto OUT;
324 }
325
326 if (elfInterpName[elfPhdr->fileSize - 1] != '\0') {
327 PRINT_ERR("%s[%d], The name of interpreter is invalid!\n", __FUNCTION__, __LINE__);
328 ret = -ENOEXEC;
329 goto OUT;
330 }
331
332 ret = OsReadEhdr(INTERP_FULL_PATH, &loadInfo->interpInfo, FALSE);
333 if (ret != LOS_OK) {
334 PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__);
335 goto OUT;
336 }
337
338 ret = OsReadPhdrs(&loadInfo->interpInfo, FALSE);
339 if (ret != LOS_OK) {
340 goto OUT;
341 }
342
343 (VOID)LOS_MemFree(m_aucSysMem0, elfInterpName);
344 break;
345 }
346
347 return LOS_OK;
348
349 OUT:
350 (VOID)LOS_MemFree(m_aucSysMem0, elfInterpName);
351 return ret;
352 }
353
OsGetProt(UINT32 pFlags)354 STATIC UINT32 OsGetProt(UINT32 pFlags)
355 {
356 UINT32 prot;
357
358 prot = (((pFlags & PF_R) ? PROT_READ : 0) |
359 ((pFlags & PF_W) ? PROT_WRITE : 0) |
360 ((pFlags & PF_X) ? PROT_EXEC : 0));
361 return prot;
362 }
363
OsGetAllocSize(const LD_ELF_PHDR * elfPhdr,INT32 phdrNum)364 STATIC UINT32 OsGetAllocSize(const LD_ELF_PHDR *elfPhdr, INT32 phdrNum)
365 {
366 const LD_ELF_PHDR *elfPhdrTemp = elfPhdr;
367 UINTPTR addrMin = SIZE_MAX;
368 UINTPTR addrMax = 0;
369 UINT32 offStart = 0;
370 UINT64 size;
371 INT32 i;
372
373 for (i = 0; i < phdrNum; ++i, ++elfPhdrTemp) {
374 if (elfPhdrTemp->type != LD_PT_LOAD) {
375 continue;
376 }
377
378 if (OsVerifyELFPhdr(elfPhdrTemp) != LOS_OK) {
379 return 0;
380 }
381
382 if (elfPhdrTemp->vAddr < addrMin) {
383 addrMin = elfPhdrTemp->vAddr;
384 offStart = elfPhdrTemp->offset;
385 }
386 if ((elfPhdrTemp->vAddr + elfPhdrTemp->memSize) > addrMax) {
387 addrMax = elfPhdrTemp->vAddr + elfPhdrTemp->memSize;
388 }
389 }
390
391 if (OsIsBadUserAddress((VADDR_T)addrMax) || OsIsBadUserAddress((VADDR_T)addrMin) || (addrMax < addrMin)) {
392 return 0;
393 }
394 size = ROUNDUP(addrMax, PAGE_SIZE) - ROUNDDOWN(addrMin, PAGE_SIZE) + ROUNDDOWN(offStart, PAGE_SIZE);
395
396 return (size > UINT_MAX) ? 0 : (UINT32)size;
397 }
398
OsDoMmapFile(INT32 fd,UINTPTR addr,const LD_ELF_PHDR * elfPhdr,UINT32 prot,UINT32 flags,UINT32 mapSize)399 STATIC UINTPTR OsDoMmapFile(INT32 fd, UINTPTR addr, const LD_ELF_PHDR *elfPhdr, UINT32 prot, UINT32 flags,
400 UINT32 mapSize)
401 {
402 UINTPTR mapAddr;
403 UINT32 size;
404 UINT32 offset = elfPhdr->offset - ROUNDOFFSET(elfPhdr->vAddr, PAGE_SIZE);
405 addr = ROUNDDOWN(addr, PAGE_SIZE);
406
407 if (mapSize != 0) {
408 mapAddr = (UINTPTR)LOS_MMap(addr, mapSize, prot, flags, fd, offset >> PAGE_SHIFT);
409 } else {
410 size = elfPhdr->memSize + ROUNDOFFSET(elfPhdr->vAddr, PAGE_SIZE);
411 if (size == 0) {
412 return addr;
413 }
414 mapAddr = (UINTPTR)LOS_MMap(addr, size, prot, flags, fd, offset >> PAGE_SHIFT);
415 }
416 if (!LOS_IsUserAddress((VADDR_T)mapAddr)) {
417 PRINT_ERR("%s %d, Failed to map a valid addr\n", __FUNCTION__, __LINE__);
418 return 0;
419 }
420 return mapAddr;
421 }
422
OsGetKernelVaddr(LosVmSpace * space,VADDR_T vaddr,VADDR_T * kvaddr)423 INT32 OsGetKernelVaddr(LosVmSpace *space, VADDR_T vaddr, VADDR_T *kvaddr)
424 {
425 INT32 ret;
426 PADDR_T paddr = 0;
427
428 if ((space == NULL) || (vaddr == 0) || (kvaddr == NULL)) {
429 PRINT_ERR("%s[%d], space: %#x, vaddr: %#x\n", __FUNCTION__, __LINE__, space, vaddr);
430 return LOS_NOK;
431 }
432
433 if (LOS_IsKernelAddress(vaddr)) {
434 *kvaddr = vaddr;
435 return LOS_OK;
436 }
437
438 ret = LOS_ArchMmuQuery(&space->archMmu, vaddr, &paddr, NULL);
439 if (ret != LOS_OK) {
440 PRINT_ERR("%s[%d], Failed to query the vaddr: %#x, status: %d\n", __FUNCTION__, __LINE__, vaddr, ret);
441 return LOS_NOK;
442 }
443 *kvaddr = (VADDR_T)(UINTPTR)LOS_PaddrToKVaddr(paddr);
444 if (*kvaddr == 0) {
445 PRINT_ERR("%s[%d], kvaddr is null\n", __FUNCTION__, __LINE__);
446 return LOS_NOK;
447 }
448
449 return LOS_OK;
450 }
451
OsSetBss(const LD_ELF_PHDR * elfPhdr,INT32 fd,UINTPTR bssStart,UINT32 bssEnd,UINT32 elfProt)452 STATIC INT32 OsSetBss(const LD_ELF_PHDR *elfPhdr, INT32 fd, UINTPTR bssStart, UINT32 bssEnd, UINT32 elfProt)
453 {
454 UINTPTR bssStartPageAlign, bssEndPageAlign;
455 UINTPTR mapBase;
456 UINT32 bssMapSize;
457 INT32 stackFlags;
458 INT32 ret;
459
460 bssStartPageAlign = ROUNDUP(bssStart, PAGE_SIZE);
461 bssEndPageAlign = ROUNDUP(bssEnd, PAGE_SIZE);
462
463 ret = LOS_UserMemClear((VOID *)bssStart, PAGE_SIZE - ROUNDOFFSET(bssStart, PAGE_SIZE));
464 if (ret != 0) {
465 PRINT_ERR("%s[%d], Failed to clear bss\n", __FUNCTION__, __LINE__);
466 return -EFAULT;
467 }
468
469 bssMapSize = bssEndPageAlign - bssStartPageAlign;
470 if (bssMapSize > 0) {
471 stackFlags = MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS;
472 mapBase = (UINTPTR)LOS_MMap(bssStartPageAlign, bssMapSize, elfProt, stackFlags, -1, 0);
473 if (!LOS_IsUserAddress((VADDR_T)mapBase)) {
474 PRINT_ERR("%s[%d], Failed to map bss\n", __FUNCTION__, __LINE__);
475 return -ENOMEM;
476 }
477 }
478
479 return LOS_OK;
480 }
481
OsMmapELFFile(INT32 procfd,const LD_ELF_PHDR * elfPhdr,const LD_ELF_EHDR * elfEhdr,UINTPTR * elfLoadAddr,UINT32 mapSize,UINTPTR * loadBase)482 STATIC INT32 OsMmapELFFile(INT32 procfd, const LD_ELF_PHDR *elfPhdr, const LD_ELF_EHDR *elfEhdr, UINTPTR *elfLoadAddr,
483 UINT32 mapSize, UINTPTR *loadBase)
484 {
485 const LD_ELF_PHDR *elfPhdrTemp = elfPhdr;
486 UINTPTR vAddr, mapAddr, bssStart;
487 UINT32 bssEnd, elfProt, elfFlags;
488 INT32 ret, i;
489 INT32 fd = GetAssociatedSystemFd(procfd);
490
491 for (i = 0; i < elfEhdr->elfPhNum; ++i, ++elfPhdrTemp) {
492 if (elfPhdrTemp->type != LD_PT_LOAD) {
493 continue;
494 }
495 if (elfEhdr->elfType == LD_ET_EXEC) {
496 if (OsVerifyELFPhdr(elfPhdrTemp) != LOS_OK) {
497 return -ENOEXEC;
498 }
499 }
500
501 elfProt = OsGetProt(elfPhdrTemp->flags);
502 if ((elfProt & PROT_READ) == 0) {
503 return -ENOEXEC;
504 }
505 elfFlags = MAP_PRIVATE | MAP_FIXED;
506 vAddr = elfPhdrTemp->vAddr;
507 if ((vAddr == 0) && (*loadBase == 0)) {
508 elfFlags &= ~MAP_FIXED;
509 }
510
511 mapAddr = OsDoMmapFile(fd, (vAddr + *loadBase), elfPhdrTemp, elfProt, elfFlags, mapSize);
512 if (!LOS_IsUserAddress((VADDR_T)mapAddr)) {
513 return -ENOMEM;
514 }
515 #ifdef LOSCFG_DRIVERS_TZDRIVER
516 if ((elfPhdrTemp->flags & PF_R) && (elfPhdrTemp->flags & PF_X) && !(elfPhdrTemp->flags & PF_W)) {
517 SetVmmRegionCodeStart(vAddr + *loadBase, elfPhdrTemp->memSize);
518 }
519 #endif
520 mapSize = 0;
521
522 if (*elfLoadAddr == 0) {
523 *elfLoadAddr = mapAddr + ROUNDOFFSET(vAddr, PAGE_SIZE);
524 }
525
526 if ((*loadBase == 0) && (elfEhdr->elfType == LD_ET_DYN)) {
527 *loadBase = mapAddr;
528 }
529
530 if ((elfPhdrTemp->memSize > elfPhdrTemp->fileSize) && (elfPhdrTemp->flags & PF_W)) {
531 bssStart = mapAddr + ROUNDOFFSET(vAddr, PAGE_SIZE) + elfPhdrTemp->fileSize;
532 bssEnd = mapAddr + ROUNDOFFSET(vAddr, PAGE_SIZE) + elfPhdrTemp->memSize;
533 ret = OsSetBss(elfPhdrTemp, fd, bssStart, bssEnd, elfProt);
534 if (ret != LOS_OK) {
535 return ret;
536 }
537 }
538 }
539
540 return LOS_OK;
541 }
542
OsLoadInterpBinary(ELFLoadInfo * loadInfo,UINTPTR * interpMapBase)543 STATIC INT32 OsLoadInterpBinary(ELFLoadInfo *loadInfo, UINTPTR *interpMapBase)
544 {
545 UINTPTR loadBase = 0;
546 UINT32 mapSize;
547 INT32 ret;
548
549 mapSize = OsGetAllocSize(loadInfo->interpInfo.elfPhdr, loadInfo->interpInfo.elfEhdr.elfPhNum);
550 if (mapSize == 0) {
551 PRINT_ERR("%s[%d], Failed to get interp allocation size!\n", __FUNCTION__, __LINE__);
552 return -EINVAL;
553 }
554
555 ret = OsMmapELFFile(loadInfo->interpInfo.procfd, loadInfo->interpInfo.elfPhdr, &loadInfo->interpInfo.elfEhdr,
556 interpMapBase, mapSize, &loadBase);
557 if (ret != LOS_OK) {
558 PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__);
559 }
560
561 return ret;
562 }
563
OsGetParamPtr(CHAR * const * ptr,INT32 index)564 STATIC CHAR *OsGetParamPtr(CHAR * const *ptr, INT32 index)
565 {
566 UINTPTR userStrPtr = 0;
567 INT32 ret;
568
569 if (ptr == NULL) {
570 return NULL;
571 }
572
573 if (LOS_IsKernelAddress((UINTPTR)ptr)) {
574 return ptr[index];
575 }
576 ret = LOS_GetUser(&userStrPtr, (UINTPTR *)(ptr + index));
577 if (ret != LOS_OK) {
578 PRINT_ERR("%s[%d], %#x\n", __FUNCTION__, __LINE__, ptr);
579 return NULL;
580 }
581
582 return (CHAR *)userStrPtr;
583 }
584
OsPutUserArg(INT32 val,const UINTPTR * sp)585 STATIC INT32 OsPutUserArg(INT32 val, const UINTPTR *sp)
586 {
587 INT32 ret;
588
589 if (sp == NULL) {
590 return LOS_NOK;
591 }
592
593 ret = LOS_PutUser((INT32 *)&val, (INT32 *)sp);
594 if (ret != LOS_OK) {
595 PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__);
596 return -EFAULT;
597 }
598
599 return LOS_OK;
600 }
601
OsPutUserArgv(UINTPTR * strPtr,UINTPTR ** sp,INT32 count)602 STATIC INT32 OsPutUserArgv(UINTPTR *strPtr, UINTPTR **sp, INT32 count)
603 {
604 INT32 len;
605 INT32 i;
606 CHAR *ptr = NULL;
607
608 if ((strPtr == NULL) || (sp == NULL)) {
609 return LOS_NOK;
610 }
611
612 for (i = 0; i < count; ++i) {
613 /* put the addr of arg strings to user stack */
614 if (OsPutUserArg(*strPtr, *sp) != LOS_OK) {
615 return LOS_NOK;
616 }
617 ptr = OsGetParamPtr((CHAR **)strPtr, 0);
618 if (ptr == NULL) {
619 return LOS_NOK;
620 }
621 len = LOS_StrnlenUser(ptr, PATH_MAX);
622 if (len == 0) {
623 return LOS_NOK;
624 }
625 *strPtr += len;
626 ++(*sp);
627 }
628 /* put zero to end of argv */
629 if (OsPutUserArg(0, *sp) != LOS_OK) {
630 return LOS_NOK;
631 }
632 ++(*sp);
633
634 return LOS_OK;
635 }
636
OsCopyParams(ELFLoadInfo * loadInfo,INT32 argc,CHAR * const * argv)637 STATIC INT32 OsCopyParams(ELFLoadInfo *loadInfo, INT32 argc, CHAR *const *argv)
638 {
639 CHAR *strPtr = NULL;
640 UINT32 offset, strLen;
641 errno_t err;
642 INT32 ret, i;
643 vaddr_t kvaddr = 0;
644
645 if ((argc > 0) && (argv == NULL)) {
646 return -EINVAL;
647 }
648
649 ret = OsGetKernelVaddr(loadInfo->newSpace, loadInfo->stackParamBase, &kvaddr);
650 if (ret != LOS_OK) {
651 PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__);
652 return -EFAULT;
653 }
654
655 for (i = argc - 1; i >= 0; --i) {
656 strPtr = OsGetParamPtr(argv, i);
657 if (LOS_IsKernelAddress((VADDR_T)(UINTPTR)strPtr)) {
658 strLen = strlen(strPtr) + 1;
659 } else {
660 strLen = LOS_StrnlenUser(strPtr, PATH_MAX);
661 }
662 if (strLen < 1) {
663 continue;
664 }
665
666 offset = loadInfo->topOfMem - loadInfo->stackParamBase;
667 if (offset < strLen) {
668 PRINT_ERR("%s[%d], The size of param is out of limit: %#x bytes!\n", __FUNCTION__, __LINE__,
669 USER_PARAM_BYTE_MAX);
670 return -E2BIG;
671 }
672 loadInfo->topOfMem -= strLen;
673 offset -= strLen;
674
675 /* copy strings to user stack */
676 if (LOS_IsKernelAddress((VADDR_T)(UINTPTR)strPtr)) {
677 err = memcpy_s((VOID *)(UINTPTR)(kvaddr + offset), strLen, strPtr, strLen);
678 } else {
679 err = LOS_ArchCopyFromUser((VOID *)(UINTPTR)(kvaddr + offset), strPtr, strLen);
680 }
681
682 if (err != EOK) {
683 PRINT_ERR("%s[%d], copy strings failed! err: %d\n", __FUNCTION__, __LINE__, err);
684 return -EFAULT;
685 }
686 }
687
688 return LOS_OK;
689 }
690
OsGetParamNum(CHAR * const * argv)691 STATIC INT32 OsGetParamNum(CHAR *const *argv)
692 {
693 CHAR *argPtr = NULL;
694 INT32 count = 0;
695 INT32 ret;
696
697 if (argv == NULL) {
698 return count;
699 }
700
701 argPtr = OsGetParamPtr(argv, count);
702 while (argPtr != NULL) {
703 ret = LOS_StrnlenUser(argPtr, PATH_MAX);
704 if ((ret == 0) || (ret > PATH_MAX)) {
705 PRINT_ERR("%s[%d], the len of string of argv is invalid, index: %d, len: %d\n", __FUNCTION__,
706 __LINE__, count, ret);
707 break;
708 }
709 ++count;
710 if (count >= STRINGS_COUNT_MAX) {
711 break;
712 }
713 argPtr = OsGetParamPtr(argv, count);
714 }
715
716 return count;
717 }
718
OsGetRndOffset(INT32 randomDevFD)719 UINT32 OsGetRndOffset(INT32 randomDevFD)
720 {
721 UINT32 randomValue = 0;
722
723 #ifdef LOSCFG_ASLR
724 if (read(randomDevFD, &randomValue, sizeof(UINT32)) == sizeof(UINT32)) {
725 randomValue &= RANDOM_MASK;
726 } else {
727 randomValue = (UINT32)random() & RANDOM_MASK;
728 }
729 #else
730 (VOID)randomDevFD;
731 #endif
732
733 return ROUNDDOWN(randomValue, PAGE_SIZE);
734 }
735
OsGetStackProt(ELFLoadInfo * loadInfo)736 STATIC VOID OsGetStackProt(ELFLoadInfo *loadInfo)
737 {
738 LD_ELF_PHDR *elfPhdrTemp = loadInfo->execInfo.elfPhdr;
739 INT32 i;
740
741 for (i = 0; i < loadInfo->execInfo.elfEhdr.elfPhNum; ++i, ++elfPhdrTemp) {
742 if (elfPhdrTemp->type == LD_PT_GNU_STACK) {
743 loadInfo->stackProt = OsGetProt(elfPhdrTemp->flags);
744 }
745 }
746 }
747
OsStackAlloc(LosVmSpace * space,VADDR_T vaddr,UINT32 vsize,UINT32 psize,UINT32 regionFlags)748 STATIC UINT32 OsStackAlloc(LosVmSpace *space, VADDR_T vaddr, UINT32 vsize, UINT32 psize, UINT32 regionFlags)
749 {
750 LosVmPage *vmPage = NULL;
751 VADDR_T *kvaddr = NULL;
752 LosVmMapRegion *region = NULL;
753 VADDR_T vaddrTemp;
754 PADDR_T paddrTemp;
755 UINT32 len;
756
757 (VOID)LOS_MuxAcquire(&space->regionMux);
758 kvaddr = LOS_PhysPagesAllocContiguous(psize >> PAGE_SHIFT);
759 if (kvaddr == NULL) {
760 goto OUT;
761 }
762
763 region = LOS_RegionAlloc(space, vaddr, vsize, regionFlags | VM_MAP_REGION_FLAG_FIXED, 0);
764 if (region == NULL) {
765 goto PFREE;
766 }
767
768 len = psize;
769 vaddrTemp = region->range.base + vsize - psize;
770 paddrTemp = LOS_PaddrQuery(kvaddr);
771 while (len > 0) {
772 vmPage = LOS_VmPageGet(paddrTemp);
773 LOS_AtomicInc(&vmPage->refCounts);
774
775 (VOID)LOS_ArchMmuMap(&space->archMmu, vaddrTemp, paddrTemp, 1, region->regionFlags);
776
777 paddrTemp += PAGE_SIZE;
778 vaddrTemp += PAGE_SIZE;
779 len -= PAGE_SIZE;
780 }
781 (VOID)LOS_MuxRelease(&space->regionMux);
782 return LOS_OK;
783
784 PFREE:
785 (VOID)LOS_PhysPagesFreeContiguous(kvaddr, psize >> PAGE_SHIFT);
786 OUT:
787 (VOID)LOS_MuxRelease(&space->regionMux);
788 return LOS_NOK;
789 }
790
OsSetArgParams(ELFLoadInfo * loadInfo,CHAR * const * argv,CHAR * const * envp)791 STATIC INT32 OsSetArgParams(ELFLoadInfo *loadInfo, CHAR *const *argv, CHAR *const *envp)
792 {
793 UINT32 vmFlags;
794 INT32 ret;
795
796 loadInfo->randomDevFD = open("/dev/urandom", O_RDONLY);
797 if (loadInfo->randomDevFD < 0) {
798 if (!g_srandInit) {
799 srand((UINT32)time(NULL));
800 g_srandInit = TRUE;
801 }
802 }
803
804 (VOID)OsGetStackProt(loadInfo);
805 if (((UINT32)loadInfo->stackProt & (PROT_READ | PROT_WRITE)) != (PROT_READ | PROT_WRITE)) {
806 return -ENOEXEC;
807 }
808 loadInfo->stackTopMax = USER_STACK_TOP_MAX - OsGetRndOffset(loadInfo->randomDevFD);
809 loadInfo->stackBase = loadInfo->stackTopMax - USER_STACK_SIZE;
810 loadInfo->stackSize = USER_STACK_SIZE;
811 loadInfo->stackParamBase = loadInfo->stackTopMax - USER_PARAM_BYTE_MAX;
812 vmFlags = OsCvtProtFlagsToRegionFlags(loadInfo->stackProt, MAP_FIXED);
813 vmFlags |= VM_MAP_REGION_FLAG_STACK;
814 ret = OsStackAlloc((VOID *)loadInfo->newSpace, loadInfo->stackBase, USER_STACK_SIZE,
815 USER_PARAM_BYTE_MAX, vmFlags);
816 if (ret != LOS_OK) {
817 PRINT_ERR("%s[%d], Failed to alloc memory for user stack!\n", __FUNCTION__, __LINE__);
818 return -ENOMEM;
819 }
820 loadInfo->topOfMem = loadInfo->stackTopMax - sizeof(UINTPTR);
821
822 loadInfo->argc = OsGetParamNum(argv);
823 loadInfo->envc = OsGetParamNum(envp);
824 ret = OsCopyParams(loadInfo, 1, (CHAR *const *)&loadInfo->fileName);
825 if (ret != LOS_OK) {
826 PRINT_ERR("%s[%d], Failed to copy filename to user stack!\n", __FUNCTION__, __LINE__);
827 return ret;
828 }
829 loadInfo->execName = (CHAR *)loadInfo->topOfMem;
830
831 ret = OsCopyParams(loadInfo, loadInfo->envc, envp);
832 if (ret != LOS_OK) {
833 return ret;
834 }
835 ret = OsCopyParams(loadInfo, loadInfo->argc, argv);
836 if (ret != LOS_OK) {
837 return ret;
838 }
839 loadInfo->argStart = loadInfo->topOfMem;
840
841 return LOS_OK;
842 }
843
OsPutParamToStack(ELFLoadInfo * loadInfo,const UINTPTR * auxVecInfo,INT32 vecIndex)844 STATIC INT32 OsPutParamToStack(ELFLoadInfo *loadInfo, const UINTPTR *auxVecInfo, INT32 vecIndex)
845 {
846 UINTPTR *topMem = (UINTPTR *)ROUNDDOWN(loadInfo->topOfMem, sizeof(UINTPTR));
847 UINTPTR *argsPtr = NULL;
848 INT32 items = (loadInfo->argc + 1) + (loadInfo->envc + 1) + 1;
849 size_t size;
850
851 loadInfo->topOfMem = ROUNDDOWN((UINTPTR)(topMem - vecIndex - items), STACK_ALIGN_SIZE);
852 argsPtr = (UINTPTR *)loadInfo->topOfMem;
853 loadInfo->stackTop = (UINTPTR)argsPtr;
854
855 if ((loadInfo->stackTopMax - loadInfo->stackTop) > USER_PARAM_BYTE_MAX) {
856 return -E2BIG;
857 }
858
859 if (OsPutUserArg(loadInfo->argc, argsPtr)) {
860 PRINT_ERR("%s[%d], Failed to put argc to user stack!\n", __FUNCTION__, __LINE__);
861 return -EFAULT;
862 }
863
864 argsPtr++;
865
866 if ((OsPutUserArgv(&loadInfo->argStart, &argsPtr, loadInfo->argc) != LOS_OK) ||
867 (OsPutUserArgv(&loadInfo->argStart, &argsPtr, loadInfo->envc) != LOS_OK)) {
868 PRINT_ERR("%s[%d], Failed to put argv or envp to user stack!\n", __FUNCTION__, __LINE__);
869 return -EFAULT;
870 }
871
872 size = LOS_ArchCopyToUser(argsPtr, auxVecInfo, vecIndex * sizeof(UINTPTR));
873 if (size != 0) {
874 PRINT_ERR("%s[%d], Failed to copy strings! Bytes not copied: %d\n", __FUNCTION__, __LINE__, size);
875 return -EFAULT;
876 }
877
878 return LOS_OK;
879 }
880
OsGetRndNum(const ELFLoadInfo * loadInfo,UINT32 * rndVec,UINT32 vecSize)881 STATIC INT32 OsGetRndNum(const ELFLoadInfo *loadInfo, UINT32 *rndVec, UINT32 vecSize)
882 {
883 UINT32 randomValue = 0;
884 UINT32 i, ret;
885
886 for (i = 0; i < vecSize; ++i) {
887 ret = read(loadInfo->randomDevFD, &randomValue, sizeof(UINT32));
888 if (ret != sizeof(UINT32)) {
889 rndVec[i] = (UINT32)random();
890 continue;
891 }
892 rndVec[i] = randomValue;
893 }
894
895 return LOS_OK;
896 }
897
OsMakeArgsStack(ELFLoadInfo * loadInfo,UINTPTR interpMapBase)898 STATIC INT32 OsMakeArgsStack(ELFLoadInfo *loadInfo, UINTPTR interpMapBase)
899 {
900 UINTPTR auxVector[AUX_VECTOR_SIZE] = { 0 };
901 UINTPTR *auxVecInfo = (UINTPTR *)auxVector;
902 INT32 vecIndex = 0;
903 UINT32 rndVec[RANDOM_VECTOR_SIZE];
904 UINTPTR rndVecStart;
905 INT32 ret;
906 #ifdef LOSCFG_KERNEL_VDSO
907 vaddr_t vdsoLoadAddr;
908 #endif
909
910 ret = OsGetRndNum(loadInfo, rndVec, sizeof(rndVec));
911 if (ret != LOS_OK) {
912 return ret;
913 }
914 loadInfo->topOfMem -= sizeof(rndVec);
915 rndVecStart = loadInfo->topOfMem;
916
917 ret = LOS_ArchCopyToUser((VOID *)loadInfo->topOfMem, rndVec, sizeof(rndVec));
918 if (ret != 0) {
919 return -EFAULT;
920 }
921
922 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_PHDR, loadInfo->loadAddr + loadInfo->execInfo.elfEhdr.elfPhoff);
923 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_PHENT, sizeof(LD_ELF_PHDR));
924 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_PHNUM, loadInfo->execInfo.elfEhdr.elfPhNum);
925 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_PAGESZ, PAGE_SIZE);
926 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_BASE, interpMapBase);
927 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_FLAGS, 0);
928 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_ENTRY, loadInfo->execInfo.elfEhdr.elfEntry);
929 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_UID, 0);
930 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_EUID, 0);
931 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_GID, 0);
932 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_EGID, 0);
933 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_HWCAP, 0);
934 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_CLKTCK, 0);
935 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_SECURE, 0);
936 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_RANDOM, rndVecStart);
937 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_EXECFN, (UINTPTR)loadInfo->execName);
938
939 #ifdef LOSCFG_KERNEL_VDSO
940 vdsoLoadAddr = OsVdsoLoad(OsCurrProcessGet());
941 if (vdsoLoadAddr != 0) {
942 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_SYSINFO_EHDR, vdsoLoadAddr);
943 }
944 #endif
945 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_NULL, 0);
946
947 ret = OsPutParamToStack(loadInfo, auxVecInfo, vecIndex);
948 if (ret != LOS_OK) {
949 PRINT_ERR("%s[%d], Failed to put param to user stack\n", __FUNCTION__, __LINE__);
950 return ret;
951 }
952
953 return LOS_OK;
954 }
955
OsLoadELFSegment(ELFLoadInfo * loadInfo)956 STATIC INT32 OsLoadELFSegment(ELFLoadInfo *loadInfo)
957 {
958 LD_ELF_PHDR *elfPhdrTemp = loadInfo->execInfo.elfPhdr;
959 UINTPTR loadBase = 0;
960 UINTPTR interpMapBase = 0;
961 UINT32 mapSize = 0;
962 INT32 ret;
963 loadInfo->loadAddr = 0;
964
965 if (loadInfo->execInfo.elfEhdr.elfType == LD_ET_DYN) {
966 loadBase = EXEC_MMAP_BASE + OsGetRndOffset(loadInfo->randomDevFD);
967 mapSize = OsGetAllocSize(elfPhdrTemp, loadInfo->execInfo.elfEhdr.elfPhNum);
968 if (mapSize == 0) {
969 PRINT_ERR("%s[%d], Failed to get allocation size of file: %s!\n", __FUNCTION__, __LINE__,
970 loadInfo->fileName);
971 return -EINVAL;
972 }
973 }
974
975 ret = OsMmapELFFile(loadInfo->execInfo.procfd, loadInfo->execInfo.elfPhdr, &loadInfo->execInfo.elfEhdr,
976 &loadInfo->loadAddr, mapSize, &loadBase);
977 OsELFClose(loadInfo->execInfo.procfd);
978 loadInfo->execInfo.procfd = INVALID_FD;
979 if (ret != LOS_OK) {
980 PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__);
981 return ret;
982 }
983
984 if (loadInfo->interpInfo.procfd != INVALID_FD) {
985 ret = OsLoadInterpBinary(loadInfo, &interpMapBase);
986 OsELFClose(loadInfo->interpInfo.procfd);
987 loadInfo->interpInfo.procfd = INVALID_FD;
988 if (ret != LOS_OK) {
989 return ret;
990 }
991
992 loadInfo->elfEntry = loadInfo->interpInfo.elfEhdr.elfEntry + interpMapBase;
993 loadInfo->execInfo.elfEhdr.elfEntry = loadInfo->execInfo.elfEhdr.elfEntry + loadBase;
994 } else {
995 loadInfo->elfEntry = loadInfo->execInfo.elfEhdr.elfEntry;
996 }
997
998 ret = OsMakeArgsStack(loadInfo, interpMapBase);
999 if (ret != LOS_OK) {
1000 return ret;
1001 }
1002 if (!LOS_IsUserAddress((VADDR_T)loadInfo->stackTop)) {
1003 PRINT_ERR("%s[%d], StackTop is out of limit!\n", __FUNCTION__, __LINE__);
1004 return -EINVAL;
1005 }
1006
1007 return LOS_OK;
1008 }
1009
OsFlushAspace(ELFLoadInfo * loadInfo)1010 STATIC VOID OsFlushAspace(ELFLoadInfo *loadInfo)
1011 {
1012 loadInfo->oldSpace = OsExecProcessVmSpaceReplace(loadInfo->newSpace, loadInfo->stackBase, loadInfo->randomDevFD);
1013 }
1014
OsDeInitLoadInfo(ELFLoadInfo * loadInfo)1015 STATIC VOID OsDeInitLoadInfo(ELFLoadInfo *loadInfo)
1016 {
1017 (VOID)close(loadInfo->randomDevFD);
1018
1019 if (loadInfo->execInfo.elfPhdr != NULL) {
1020 (VOID)LOS_MemFree(m_aucSysMem0, loadInfo->execInfo.elfPhdr);
1021 }
1022
1023 if (loadInfo->interpInfo.elfPhdr != NULL) {
1024 (VOID)LOS_MemFree(m_aucSysMem0, loadInfo->interpInfo.elfPhdr);
1025 }
1026 }
1027
OsDeInitFiles(ELFLoadInfo * loadInfo)1028 STATIC VOID OsDeInitFiles(ELFLoadInfo *loadInfo)
1029 {
1030 if (loadInfo->execInfo.procfd != INVALID_FD) {
1031 (VOID)OsELFClose(loadInfo->execInfo.procfd);
1032 }
1033
1034 if (loadInfo->interpInfo.procfd != INVALID_FD) {
1035 (VOID)OsELFClose(loadInfo->interpInfo.procfd);
1036 }
1037 #ifdef LOSCFG_FS_VFS
1038 delete_files_snapshot((struct files_struct *)loadInfo->oldFiles);
1039 #endif
1040 }
1041
OsLoadELFFile(ELFLoadInfo * loadInfo)1042 INT32 OsLoadELFFile(ELFLoadInfo *loadInfo)
1043 {
1044 INT32 ret;
1045
1046 OsLoadInit(loadInfo);
1047
1048 ret = OsReadEhdr(loadInfo->fileName, &loadInfo->execInfo, TRUE);
1049 if (ret != LOS_OK) {
1050 goto OUT;
1051 }
1052
1053 ret = OsReadPhdrs(&loadInfo->execInfo, TRUE);
1054 if (ret != LOS_OK) {
1055 goto OUT;
1056 }
1057
1058 ret = OsReadInterpInfo(loadInfo);
1059 if (ret != LOS_OK) {
1060 goto OUT;
1061 }
1062
1063 ret = OsSetArgParams(loadInfo, loadInfo->argv, loadInfo->envp);
1064 if (ret != LOS_OK) {
1065 goto OUT;
1066 }
1067
1068 OsFlushAspace(loadInfo);
1069
1070 ret = OsLoadELFSegment(loadInfo);
1071 if (ret != LOS_OK) {
1072 OsExecProcessVmSpaceRestore(loadInfo->oldSpace);
1073 goto OUT;
1074 }
1075
1076 OsDeInitLoadInfo(loadInfo);
1077
1078 return LOS_OK;
1079
1080 OUT:
1081 OsDeInitFiles(loadInfo);
1082 (VOID)LOS_VmSpaceFree(loadInfo->newSpace);
1083 (VOID)OsDeInitLoadInfo(loadInfo);
1084 return ret;
1085 }
1086