• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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