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 "syscall_pub.h"
33 #ifdef LOSCFG_FS_VFS
34 #include "errno.h"
35 #include "unistd.h"
36 #include "fs/fd_table.h"
37 #include "fs/file.h"
38 #include "fs/fs.h"
39 #include "fs/fs_operation.h"
40 #include "sys/mount.h"
41 #include "los_task_pri.h"
42 #include "sys/utsname.h"
43 #include "sys/uio.h"
44 #include "poll.h"
45 #include "sys/prctl.h"
46 #include "epoll.h"
47 #ifdef LOSCFG_KERNEL_DYNLOAD
48 #include "los_exec_elf.h"
49 #endif
50 #include "los_syscall.h"
51 #include "dirent.h"
52 #include "user_copy.h"
53 #include "los_vm_map.h"
54 #include "los_memory.h"
55 #include "los_strncpy_from_user.h"
56 #include "capability_type.h"
57 #include "capability_api.h"
58 #include "sys/statfs.h"
59
60 #define HIGH_SHIFT_BIT 32
61 #define TIMESPEC_TIMES_NUM 2
62 #define EPOLL_DEFAULT_SIZE 100
63
CheckNewAttrTime(struct IATTR * attr,struct timespec times[TIMESPEC_TIMES_NUM])64 static int CheckNewAttrTime(struct IATTR *attr, struct timespec times[TIMESPEC_TIMES_NUM])
65 {
66 int ret = ENOERR;
67 struct timespec stp = {0};
68
69 if (times) {
70 if (times[0].tv_nsec == UTIME_OMIT) {
71 attr->attr_chg_valid &= ~CHG_ATIME;
72 } else if (times[0].tv_nsec == UTIME_NOW) {
73 ret = clock_gettime(CLOCK_REALTIME, &stp);
74 if (ret < 0) {
75 return -get_errno();
76 }
77 attr->attr_chg_atime = (unsigned int)stp.tv_sec;
78 attr->attr_chg_valid |= CHG_ATIME;
79 } else {
80 attr->attr_chg_atime = (unsigned int)times[0].tv_sec;
81 attr->attr_chg_valid |= CHG_ATIME;
82 }
83
84 if (times[1].tv_nsec == UTIME_OMIT) {
85 attr->attr_chg_valid &= ~CHG_MTIME;
86 } else if (times[1].tv_nsec == UTIME_NOW) {
87 ret = clock_gettime(CLOCK_REALTIME, &stp);
88 if (ret < 0) {
89 return -get_errno();
90 }
91 attr->attr_chg_mtime = (unsigned int)stp.tv_sec;
92 attr->attr_chg_valid |= CHG_MTIME;
93 } else {
94 attr->attr_chg_mtime = (unsigned int)times[1].tv_sec;
95 attr->attr_chg_valid |= CHG_MTIME;
96 }
97 } else {
98 ret = clock_gettime(CLOCK_REALTIME, &stp);
99 if (ret < 0) {
100 return -get_errno();
101 }
102 attr->attr_chg_atime = (unsigned int)stp.tv_sec;
103 attr->attr_chg_mtime = (unsigned int)stp.tv_sec;
104 attr->attr_chg_valid |= CHG_ATIME;
105 attr->attr_chg_valid |= CHG_MTIME;
106 }
107
108 return ret;
109 }
110
GetFullpathNull(int fd,const char * path,char ** filePath)111 static int GetFullpathNull(int fd, const char *path, char **filePath)
112 {
113 int ret;
114 char *fullPath = NULL;
115 struct file *file = NULL;
116
117 if ((fd != AT_FDCWD) && (path == NULL)) {
118 fd = GetAssociatedSystemFd(fd);
119 ret = fs_getfilep(fd, &file);
120 if (ret < 0) {
121 return -get_errno();
122 }
123 fullPath = strdup(file->f_path);
124 if (fullPath == NULL) {
125 ret = -ENOMEM;
126 }
127 } else {
128 ret = GetFullpath(fd, path, &fullPath);
129 if (ret < 0) {
130 return ret;
131 }
132 }
133
134 *filePath = fullPath;
135 return ret;
136 }
137
UserIovItemCheck(const struct iovec * iov,const int iovcnt)138 static int UserIovItemCheck(const struct iovec *iov, const int iovcnt)
139 {
140 int i;
141 for (i = 0; i < iovcnt; ++i) {
142 if (iov[i].iov_len == 0) {
143 continue;
144 }
145
146 if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)iov[i].iov_base, iov[i].iov_len)) {
147 return i;
148 }
149 }
150 return iovcnt;
151 }
152
UserIovCopy(struct iovec ** iovBuf,const struct iovec * iov,const int iovcnt,int * valid_iovcnt)153 static int UserIovCopy(struct iovec **iovBuf, const struct iovec *iov, const int iovcnt, int *valid_iovcnt)
154 {
155 int ret;
156 int bufLen = iovcnt * sizeof(struct iovec);
157 if (bufLen < 0) {
158 return -EINVAL;
159 }
160
161 *iovBuf = (struct iovec*)LOS_MemAlloc(OS_SYS_MEM_ADDR, bufLen);
162 if (*iovBuf == NULL) {
163 return -ENOMEM;
164 }
165
166 if (LOS_ArchCopyFromUser(*iovBuf, iov, bufLen) != 0) {
167 (void)LOS_MemFree(OS_SYS_MEM_ADDR, *iovBuf);
168 return -EFAULT;
169 }
170
171 ret = UserIovItemCheck(*iovBuf, iovcnt);
172 if (ret == 0) {
173 (void)LOS_MemFree(OS_SYS_MEM_ADDR, *iovBuf);
174 return -EFAULT;
175 }
176
177 *valid_iovcnt = ret;
178 return 0;
179 }
180
PollfdToSystem(struct pollfd * fds,nfds_t nfds,int ** pollFdsBak)181 static int PollfdToSystem(struct pollfd *fds, nfds_t nfds, int **pollFdsBak)
182 {
183 if ((nfds != 0 && fds == NULL) || (pollFdsBak == NULL)) {
184 set_errno(EINVAL);
185 return -1;
186 }
187 if (nfds == 0) {
188 return 0;
189 }
190 int *pollFds = (int *)malloc(sizeof(int) * nfds);
191 if (pollFds == NULL) {
192 set_errno(ENOMEM);
193 return -1;
194 }
195 for (int i = 0; i < nfds; ++i) {
196 struct pollfd *p_fds = &fds[i];
197 pollFds[i] = p_fds->fd;
198 if (p_fds->fd < 0) {
199 set_errno(EBADF);
200 free(pollFds);
201 return -1;
202 }
203 p_fds->fd = GetAssociatedSystemFd(p_fds->fd);
204 }
205 *pollFdsBak = pollFds;
206 return 0;
207 }
208
RestorePollfd(struct pollfd * fds,nfds_t nfds,const int * pollFds)209 static void RestorePollfd(struct pollfd *fds, nfds_t nfds, const int *pollFds)
210 {
211 if ((fds == NULL) || (pollFds == NULL)) {
212 return;
213 }
214 for (int i = 0; i < nfds; ++i) {
215 struct pollfd *p_fds = &fds[i];
216 p_fds->fd = pollFds[i];
217 }
218 }
219
UserPoll(struct pollfd * fds,nfds_t nfds,int timeout)220 static int UserPoll(struct pollfd *fds, nfds_t nfds, int timeout)
221 {
222 int *pollFds = NULL;
223 int ret = PollfdToSystem(fds, nfds, &pollFds);
224 if (ret < 0) {
225 return -1;
226 }
227
228 ret = poll(fds, nfds, timeout);
229
230 RestorePollfd(fds, nfds, pollFds);
231
232 free(pollFds);
233 return ret;
234 }
235
SysClose(int fd)236 int SysClose(int fd)
237 {
238 int ret;
239
240 /* Process fd convert to system global fd */
241 int sysfd = DisassociateProcessFd(fd);
242
243 ret = close(sysfd);
244 if (ret < 0) {
245 AssociateSystemFd(fd, sysfd);
246 return -get_errno();
247 }
248 FreeProcessFd(fd);
249 return ret;
250 }
251
SysRead(int fd,void * buf,size_t nbytes)252 ssize_t SysRead(int fd, void *buf, size_t nbytes)
253 {
254 int ret;
255
256 if (nbytes == 0) {
257 return 0;
258 }
259
260 if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)buf, nbytes)) {
261 return -EFAULT;
262 }
263
264 /* Process fd convert to system global fd */
265 fd = GetAssociatedSystemFd(fd);
266
267 ret = read(fd, buf, nbytes);
268 if (ret < 0) {
269 return -get_errno();
270 }
271 return ret;
272 }
273
SysWrite(int fd,const void * buf,size_t nbytes)274 ssize_t SysWrite(int fd, const void *buf, size_t nbytes)
275 {
276 int ret;
277
278 if (nbytes == 0) {
279 return 0;
280 }
281
282 if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)buf, nbytes)) {
283 return -EFAULT;
284 }
285
286 /* Process fd convert to system global fd */
287 int sysfd = GetAssociatedSystemFd(fd);
288 ret = write(sysfd, buf, nbytes);
289 if (ret < 0) {
290 return -get_errno();
291 }
292 return ret;
293 }
294
295 // int vfs_normalize_path(const char *directory, const char *filename, char **pathname)
296 #ifdef LOSCFG_PID_CONTAINER
297 #ifdef LOSCFG_PROC_PROCESS_DIR
298 #define PROCESS_DIR_ROOT "/proc"
NextName(char * pos,uint8_t * len)299 static char *NextName(char *pos, uint8_t *len)
300 {
301 char *name = NULL;
302 while (*pos != 0 && *pos == '/') {
303 pos++;
304 }
305 if (*pos == '\0') {
306 return NULL;
307 }
308 name = (char *)pos;
309 while (*pos != '\0' && *pos != '/') {
310 pos++;
311 }
312 *len = pos - name;
313 return name;
314 }
315
ProcRealProcessIDGet(unsigned int pid)316 static unsigned int ProcRealProcessIDGet(unsigned int pid)
317 {
318 unsigned int intSave;
319 if (OS_PID_CHECK_INVALID(pid)) {
320 return 0;
321 }
322
323 SCHEDULER_LOCK(intSave);
324 LosProcessCB *pcb = OsGetPCBFromVpid(pid);
325 if (OsProcessIsInactive(pcb)) {
326 SCHEDULER_UNLOCK(intSave);
327 return 0;
328 }
329
330 int rootPid = OsGetRootPid(pcb);
331 SCHEDULER_UNLOCK(intSave);
332 if ((rootPid == OS_INVALID_VALUE) || (rootPid == pid)) {
333 return 0;
334 }
335
336 return rootPid;
337 }
338
ProcRealProcessDirGet(char * path)339 static int ProcRealProcessDirGet(char *path)
340 {
341 char pidBuf[PATH_MAX] = {0};
342 char *fullPath = NULL;
343 uint8_t strLen = 0;
344 int pid, rootPid;
345 int ret = vfs_normalize_path(NULL, path, &fullPath);
346 if (ret < 0) {
347 return ret;
348 }
349
350 int procLen = strlen(PROCESS_DIR_ROOT);
351 if (strncmp(fullPath, PROCESS_DIR_ROOT, procLen) != 0) {
352 free(fullPath);
353 return 0;
354 }
355
356 char *pidStr = NextName(fullPath + procLen, &strLen);
357 if (pidStr == NULL) {
358 free(fullPath);
359 return 0;
360 }
361
362 if ((*pidStr <= '0') || (*pidStr > '9')) {
363 free(fullPath);
364 return 0;
365 }
366
367 if (memcpy_s(pidBuf, PATH_MAX, pidStr, strLen) != EOK) {
368 free(fullPath);
369 return 0;
370 }
371 pidBuf[strLen] = '\0';
372
373 pid = atoi(pidBuf);
374 if (pid == 0) {
375 free(fullPath);
376 return 0;
377 }
378
379 rootPid = ProcRealProcessIDGet((unsigned)pid);
380 if (rootPid == 0) {
381 free(fullPath);
382 return 0;
383 }
384
385 if (snprintf_s(path, PATH_MAX + 1, PATH_MAX, "/proc/%d%s", rootPid, (pidStr + strLen)) < 0) {
386 free(fullPath);
387 return -EFAULT;
388 }
389
390 free(fullPath);
391 return 0;
392 }
393 #endif
394 #endif
395
GetPath(const char * path,char ** pathRet)396 static int GetPath(const char *path, char **pathRet)
397 {
398 int ret = UserPathCopy(path, pathRet);
399 if (ret != 0) {
400 return ret;
401 }
402 #ifdef LOSCFG_PID_CONTAINER
403 #ifdef LOSCFG_PROC_PROCESS_DIR
404 ret = ProcRealProcessDirGet(*pathRet);
405 if (ret != 0) {
406 return ret;
407 }
408 #endif
409 #endif
410 return 0;
411 }
412
SysOpen(const char * path,int oflags,...)413 int SysOpen(const char *path, int oflags, ...)
414 {
415 int ret;
416 int procFd = -1;
417 mode_t mode = DEFAULT_FILE_MODE; /* 0666: File read-write properties. */
418 char *pathRet = NULL;
419
420 if (path != NULL) {
421 ret = GetPath(path, &pathRet);
422 if (ret != 0) {
423 goto ERROUT;
424 }
425 }
426
427 procFd = AllocProcessFd();
428 if (procFd < 0) {
429 ret = -EMFILE;
430 goto ERROUT;
431 }
432
433 if (oflags & O_CLOEXEC) {
434 SetCloexecFlag(procFd);
435 }
436
437 if ((unsigned int)oflags & O_DIRECTORY) {
438 ret = do_opendir(pathRet, oflags);
439 } else {
440 #ifdef LOSCFG_FILE_MODE
441 va_list ap;
442 va_start(ap, oflags);
443 mode = va_arg(ap, int);
444 va_end(ap);
445 #endif
446
447 ret = do_open(AT_FDCWD, pathRet, oflags, mode);
448 }
449
450 if (ret < 0) {
451 ret = -get_errno();
452 goto ERROUT;
453 }
454
455 AssociateSystemFd(procFd, ret);
456 if (pathRet != NULL) {
457 LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
458 }
459 return procFd;
460
461 ERROUT:
462 if (pathRet != NULL) {
463 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
464 }
465 if (procFd >= 0) {
466 FreeProcessFd(procFd);
467 }
468 return ret;
469 }
470
SysCreat(const char * pathname,mode_t mode)471 int SysCreat(const char *pathname, mode_t mode)
472 {
473 int ret = 0;
474 char *pathRet = NULL;
475
476 if (pathname != NULL) {
477 ret = UserPathCopy(pathname, &pathRet);
478 if (ret != 0) {
479 goto OUT;
480 }
481 }
482
483 int procFd = AllocProcessFd();
484 if (procFd < 0) {
485 ret = -EMFILE;
486 goto OUT;
487 }
488
489 ret = open((pathname ? pathRet : NULL), O_CREAT | O_TRUNC | O_WRONLY, mode);
490 if (ret < 0) {
491 FreeProcessFd(procFd);
492 ret = -get_errno();
493 } else {
494 AssociateSystemFd(procFd, ret);
495 ret = procFd;
496 }
497
498 OUT:
499 if (pathRet != NULL) {
500 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
501 }
502 return ret;
503 }
504
SysLink(const char * oldpath,const char * newpath)505 int SysLink(const char *oldpath, const char *newpath)
506 {
507 int ret;
508 char *oldpathRet = NULL;
509 char *newpathRet = NULL;
510
511 if (oldpath != NULL) {
512 ret = UserPathCopy(oldpath, &oldpathRet);
513 if (ret != 0) {
514 goto OUT;
515 }
516 }
517
518 if (newpath != NULL) {
519 ret = UserPathCopy(newpath, &newpathRet);
520 if (ret != 0) {
521 goto OUT;
522 }
523 }
524
525 ret = link(oldpathRet, newpathRet);
526 if (ret < 0) {
527 ret = -get_errno();
528 }
529
530 OUT:
531 if (oldpathRet != NULL) {
532 (void)LOS_MemFree(OS_SYS_MEM_ADDR, oldpathRet);
533 }
534 if (newpathRet != NULL) {
535 (void)LOS_MemFree(OS_SYS_MEM_ADDR, newpathRet);
536 }
537 return ret;
538 }
539
SysReadlink(const char * pathname,char * buf,size_t bufsize)540 ssize_t SysReadlink(const char *pathname, char *buf, size_t bufsize)
541 {
542 ssize_t ret;
543 char *pathRet = NULL;
544
545 if (bufsize == 0) {
546 return -EINVAL;
547 }
548
549 if (pathname != NULL) {
550 ret = UserPathCopy(pathname, &pathRet);
551 if (ret != 0) {
552 goto OUT;
553 }
554
555 #ifdef LOSCFG_PID_CONTAINER
556 #ifdef LOSCFG_PROC_PROCESS_DIR
557 ret = ProcRealProcessDirGet(pathRet);
558 if (ret != 0) {
559 goto OUT;
560 }
561 #endif
562 #endif
563 }
564
565 if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)buf, bufsize)) {
566 ret = -EFAULT;
567 goto OUT;
568 }
569
570 ret = readlink(pathRet, buf, bufsize);
571 if (ret < 0) {
572 ret = -get_errno();
573 }
574
575 OUT:
576 if (pathRet != NULL) {
577 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
578 }
579 return ret;
580 }
581
SysSymlink(const char * target,const char * linkpath)582 int SysSymlink(const char *target, const char *linkpath)
583 {
584 int ret;
585 char *targetRet = NULL;
586 char *pathRet = NULL;
587
588 if (target != NULL) {
589 ret = UserPathCopy(target, &targetRet);
590 if (ret != 0) {
591 goto OUT;
592 }
593 }
594
595 if (linkpath != NULL) {
596 ret = UserPathCopy(linkpath, &pathRet);
597 if (ret != 0) {
598 goto OUT;
599 }
600 }
601
602 ret = symlink(targetRet, pathRet);
603 if (ret < 0) {
604 ret = -get_errno();
605 }
606
607 OUT:
608 if (pathRet != NULL) {
609 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
610 }
611
612 if (targetRet != NULL) {
613 (void)LOS_MemFree(OS_SYS_MEM_ADDR, targetRet);
614 }
615 return ret;
616 }
617
SysUnlink(const char * pathname)618 int SysUnlink(const char *pathname)
619 {
620 int ret;
621 char *pathRet = NULL;
622
623 if (pathname != NULL) {
624 ret = UserPathCopy(pathname, &pathRet);
625 if (ret != 0) {
626 goto OUT;
627 }
628 }
629
630 ret = do_unlink(AT_FDCWD, (pathname ? pathRet : NULL));
631 if (ret < 0) {
632 ret = -get_errno();
633 }
634
635 OUT:
636 if (pathRet != NULL) {
637 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
638 }
639 return ret;
640 }
641
642 #ifdef LOSCFG_KERNEL_DYNLOAD
SysExecve(const char * fileName,char * const * argv,char * const * envp)643 int SysExecve(const char *fileName, char *const *argv, char *const *envp)
644 {
645 return LOS_DoExecveFile(fileName, argv, envp);
646 }
647 #endif
648
SysFchdir(int fd)649 int SysFchdir(int fd)
650 {
651 int ret;
652 int sysFd;
653 struct file *file = NULL;
654
655 sysFd = GetAssociatedSystemFd(fd);
656 if (sysFd < 0) {
657 return -EBADF;
658 }
659
660 ret = fs_getfilep(sysFd, &file);
661 if (ret < 0) {
662 return -get_errno();
663 }
664
665 ret = chdir(file->f_path);
666 if (ret < 0) {
667 ret = -get_errno();
668 }
669
670 return ret;
671 }
672
SysChdir(const char * path)673 int SysChdir(const char *path)
674 {
675 int ret;
676 char *pathRet = NULL;
677
678 if (path != NULL) {
679 ret = UserPathCopy(path, &pathRet);
680 if (ret != 0) {
681 goto OUT;
682 }
683 }
684
685 ret = chdir(path ? pathRet : NULL);
686 if (ret < 0) {
687 ret = -get_errno();
688 }
689
690 OUT:
691 if (pathRet != NULL) {
692 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
693 }
694 return ret;
695 }
696
SysLseek(int fd,off_t offset,int whence)697 off_t SysLseek(int fd, off_t offset, int whence)
698 {
699 /* Process fd convert to system global fd */
700 fd = GetAssociatedSystemFd(fd);
701
702 return _lseek(fd, offset, whence);
703 }
704
SysLseek64(int fd,int offsetHigh,int offsetLow,off64_t * result,int whence)705 off64_t SysLseek64(int fd, int offsetHigh, int offsetLow, off64_t *result, int whence)
706 {
707 off64_t ret;
708 off64_t res;
709 int retVal;
710
711 /* Process fd convert to system global fd */
712 fd = GetAssociatedSystemFd(fd);
713
714 ret = _lseek64(fd, offsetHigh, offsetLow, &res, whence);
715 if (ret != 0) {
716 return ret;
717 }
718
719 retVal = LOS_ArchCopyToUser(result, &res, sizeof(off64_t));
720 if (retVal != 0) {
721 return -EFAULT;
722 }
723
724 return 0;
725 }
726
727 #ifdef LOSCFG_FS_NFS
728 static int NfsMountRef(const char *serverIpAndPath, const char *mountPath,
729 unsigned int uid, unsigned int gid) __attribute__((weakref("nfs_mount")));
730
NfsMount(const char * serverIpAndPath,const char * mountPath,unsigned int uid,unsigned int gid)731 static int NfsMount(const char *serverIpAndPath, const char *mountPath,
732 unsigned int uid, unsigned int gid)
733 {
734 int ret;
735
736 if ((serverIpAndPath == NULL) || (mountPath == NULL)) {
737 return -EINVAL;
738 }
739 ret = NfsMountRef(serverIpAndPath, mountPath, uid, gid);
740 if (ret < 0) {
741 ret = -get_errno();
742 }
743 return ret;
744 }
745 #endif
746
SysMount(const char * source,const char * target,const char * filesystemtype,unsigned long mountflags,const void * data)747 int SysMount(const char *source, const char *target, const char *filesystemtype, unsigned long mountflags,
748 const void *data)
749 {
750 int ret;
751 char *sourceRet = NULL;
752 char *targetRet = NULL;
753 char *dataRet = NULL;
754 char fstypeRet[FILESYSTEM_TYPE_MAX + 1] = {0};
755
756 if (!IsCapPermit(CAP_FS_MOUNT)) {
757 return -EPERM;
758 }
759
760 if (target != NULL) {
761 ret = UserPathCopy(target, &targetRet);
762 if (ret != 0) {
763 goto OUT;
764 }
765 }
766
767 if (filesystemtype != NULL) {
768 ret = LOS_StrncpyFromUser(fstypeRet, filesystemtype, FILESYSTEM_TYPE_MAX + 1);
769 if (ret < 0) {
770 goto OUT;
771 } else if (ret > FILESYSTEM_TYPE_MAX) {
772 ret = -ENODEV;
773 goto OUT;
774 }
775
776 if (strcmp(fstypeRet, "ramfs") && (source != NULL)) {
777 ret = UserPathCopy(source, &sourceRet);
778 if (ret != 0) {
779 goto OUT;
780 }
781 }
782 #ifdef LOSCFG_FS_NFS
783 if (strcmp(fstypeRet, "nfs") == 0) {
784 ret = NfsMount(sourceRet, targetRet, 0, 0);
785 goto OUT;
786 }
787 #endif
788 }
789
790 if (data != NULL) {
791 ret = UserPathCopy(data, &dataRet);
792 if (ret != 0) {
793 goto OUT;
794 }
795 }
796
797 ret = mount(sourceRet, targetRet, (filesystemtype ? fstypeRet : NULL), mountflags, dataRet);
798 if (ret < 0) {
799 ret = -get_errno();
800 }
801
802 OUT:
803 if (sourceRet != NULL) {
804 (void)LOS_MemFree(OS_SYS_MEM_ADDR, sourceRet);
805 }
806 if (targetRet != NULL) {
807 (void)LOS_MemFree(OS_SYS_MEM_ADDR, targetRet);
808 }
809 if (dataRet != NULL) {
810 (void)LOS_MemFree(OS_SYS_MEM_ADDR, dataRet);
811 }
812 return ret;
813 }
814
SysUmount(const char * target)815 int SysUmount(const char *target)
816 {
817 int ret;
818 char *pathRet = NULL;
819
820 if (!IsCapPermit(CAP_FS_MOUNT)) {
821 return -EPERM;
822 }
823
824 if (target != NULL) {
825 ret = UserPathCopy(target, &pathRet);
826 if (ret != 0) {
827 goto OUT;
828 }
829 }
830
831 ret = umount(target ? pathRet : NULL);
832 if (ret < 0) {
833 ret = -get_errno();
834 }
835
836 OUT:
837 if (pathRet != NULL) {
838 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
839 }
840 return ret;
841 }
842
SysAccess(const char * path,int amode)843 int SysAccess(const char *path, int amode)
844 {
845 int ret;
846 char *pathRet = NULL;
847
848 if (path != NULL) {
849 ret = UserPathCopy(path, &pathRet);
850 if (ret != 0) {
851 goto OUT;
852 }
853 }
854
855 ret = access(pathRet, amode);
856 if (ret < 0) {
857 ret = -get_errno();
858 }
859
860 OUT:
861 if (pathRet != NULL) {
862 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
863 }
864
865 return ret;
866 }
867
SysRename(const char * oldpath,const char * newpath)868 int SysRename(const char *oldpath, const char *newpath)
869 {
870 int ret;
871 char *pathOldRet = NULL;
872 char *pathNewRet = NULL;
873
874 if (oldpath != NULL) {
875 ret = UserPathCopy(oldpath, &pathOldRet);
876 if (ret != 0) {
877 goto OUT;
878 }
879 }
880
881 if (newpath != NULL) {
882 ret = UserPathCopy(newpath, &pathNewRet);
883 if (ret != 0) {
884 goto OUT;
885 }
886 }
887
888 ret = do_rename(AT_FDCWD, (oldpath ? pathOldRet : NULL), AT_FDCWD,
889 (newpath ? pathNewRet : NULL));
890 if (ret < 0) {
891 ret = -get_errno();
892 }
893
894 OUT:
895 if (pathOldRet != NULL) {
896 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathOldRet);
897 }
898 if (pathNewRet != NULL) {
899 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathNewRet);
900 }
901 return ret;
902 }
903
SysMkdir(const char * pathname,mode_t mode)904 int SysMkdir(const char *pathname, mode_t mode)
905 {
906 int ret;
907 char *pathRet = NULL;
908
909 if (pathname != NULL) {
910 ret = UserPathCopy(pathname, &pathRet);
911 if (ret != 0) {
912 goto OUT;
913 }
914 }
915
916 ret = do_mkdir(AT_FDCWD, (pathname ? pathRet : NULL), mode);
917 if (ret < 0) {
918 ret = -get_errno();
919 }
920
921 OUT:
922 if (pathRet != NULL) {
923 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
924 }
925 return ret;
926 }
927
SysRmdir(const char * pathname)928 int SysRmdir(const char *pathname)
929 {
930 int ret;
931 char *pathRet = NULL;
932
933 if (pathname != NULL) {
934 ret = UserPathCopy(pathname, &pathRet);
935 if (ret != 0) {
936 goto OUT;
937 }
938 }
939
940 ret = do_rmdir(AT_FDCWD, (pathname ? pathRet : NULL));
941 if (ret < 0) {
942 ret = -get_errno();
943 }
944
945 OUT:
946 if (pathRet != NULL) {
947 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
948 }
949 return ret;
950 }
951
SysDup(int fd)952 int SysDup(int fd)
953 {
954 int sysfd = GetAssociatedSystemFd(fd);
955 /* Check if the param is valid, note that: socket fd is not support dup2 */
956 if ((sysfd < 0) || (sysfd >= CONFIG_NFILE_DESCRIPTORS)) {
957 return -EBADF;
958 }
959
960 int dupfd = AllocProcessFd();
961 if (dupfd < 0) {
962 return -EMFILE;
963 }
964
965 files_refer(sysfd);
966 AssociateSystemFd(dupfd, sysfd);
967 return dupfd;
968 }
969
SysSync(void)970 void SysSync(void)
971 {
972 sync();
973 }
974
SysUmount2(const char * target,int flags)975 int SysUmount2(const char *target, int flags)
976 {
977 if (flags != 0) {
978 return -EINVAL;
979 }
980 return SysUmount(target);
981 }
982
SysIoctl(int fd,int req,void * arg)983 int SysIoctl(int fd, int req, void *arg)
984 {
985 int ret;
986 unsigned int size = _IOC_SIZE((unsigned int)req);
987 unsigned int dir = _IOC_DIR((unsigned int)req);
988 if ((size == 0) && (dir != _IOC_NONE)) {
989 return -EINVAL;
990 }
991
992 if ((dir != _IOC_NONE) && (((void *)(uintptr_t)arg) == NULL)) {
993 return -EINVAL;
994 }
995
996 if ((dir & _IOC_READ) || (dir & _IOC_WRITE)) {
997 if (!LOS_IsUserAddressRange((uintptr_t)arg, size)) {
998 return -EFAULT;
999 }
1000 }
1001
1002 /* Process fd convert to system global fd */
1003 fd = GetAssociatedSystemFd(fd);
1004
1005 ret = ioctl(fd, req, arg);
1006 if (ret < 0) {
1007 return -get_errno();
1008 }
1009 return ret;
1010 }
1011
SysFcntl(int fd,int cmd,void * arg)1012 int SysFcntl(int fd, int cmd, void *arg)
1013 {
1014 /* Process fd convert to system global fd */
1015 int sysfd = GetAssociatedSystemFd(fd);
1016
1017 int ret = VfsFcntl(fd, cmd, arg);
1018 if (ret == CONTINE_NUTTX_FCNTL) {
1019 ret = fcntl(sysfd, cmd, arg);
1020 }
1021
1022 if (ret < 0) {
1023 return -get_errno();
1024 }
1025 return ret;
1026 }
1027
1028 #ifdef LOSCFG_KERNEL_PIPE
SysPipe(int pipefd[2])1029 int SysPipe(int pipefd[2]) /* 2 : pipe fds for read and write */
1030 {
1031 int ret;
1032 int pipeFdIntr[2] = {0}; /* 2 : pipe fds for read and write */
1033
1034 int procFd0 = AllocProcessFd();
1035 if (procFd0 < 0) {
1036 return -EMFILE;
1037 }
1038 int procFd1 = AllocProcessFd();
1039 if (procFd1 < 0) {
1040 FreeProcessFd(procFd0);
1041 return -EMFILE;
1042 }
1043
1044 ret = pipe(pipeFdIntr);
1045 if (ret < 0) {
1046 FreeProcessFd(procFd0);
1047 FreeProcessFd(procFd1);
1048 return -get_errno();
1049 }
1050 int sysPipeFd0 = pipeFdIntr[0];
1051 int sysPipeFd1 = pipeFdIntr[1];
1052
1053 AssociateSystemFd(procFd0, sysPipeFd0);
1054 AssociateSystemFd(procFd1, sysPipeFd1);
1055
1056 pipeFdIntr[0] = procFd0;
1057 pipeFdIntr[1] = procFd1;
1058
1059 ret = LOS_ArchCopyToUser(pipefd, pipeFdIntr, sizeof(pipeFdIntr));
1060 if (ret != 0) {
1061 FreeProcessFd(procFd0);
1062 FreeProcessFd(procFd1);
1063 close(sysPipeFd0);
1064 close(sysPipeFd1);
1065 return -EFAULT;
1066 }
1067 return ret;
1068 }
1069 #endif
1070
SysDup2(int fd1,int fd2)1071 int SysDup2(int fd1, int fd2)
1072 {
1073 int ret;
1074 int sysfd1 = GetAssociatedSystemFd(fd1);
1075 int sysfd2 = GetAssociatedSystemFd(fd2);
1076
1077 /* Check if the param is valid, note that: socket fd is not support dup2 */
1078 if ((sysfd1 < 0) || (sysfd1 >= CONFIG_NFILE_DESCRIPTORS) || (CheckProcessFd(fd2) != OK)) {
1079 return -EBADF;
1080 }
1081
1082 /* Handle special circumstances */
1083 if (fd1 == fd2) {
1084 return fd2;
1085 }
1086
1087 ret = AllocSpecifiedProcessFd(fd2);
1088 if (ret != OK) {
1089 return ret;
1090 }
1091
1092 /* close the sysfd2 in need */
1093 if (sysfd2 >= 0) {
1094 ret = close(sysfd2);
1095 if (ret < 0) {
1096 AssociateSystemFd(fd2, sysfd2);
1097 return -get_errno();
1098 }
1099 }
1100
1101 files_refer(sysfd1);
1102 AssociateSystemFd(fd2, sysfd1);
1103
1104 /* if fd1 is not equal to fd2, the FD_CLOEXEC flag associated with fd2 shall be cleared */
1105 ClearCloexecFlag(fd2);
1106 return fd2;
1107 }
1108
SelectParamCheckCopy(fd_set * readfds,fd_set * writefds,fd_set * exceptfds,fd_set ** fdsBuf)1109 static int SelectParamCheckCopy(fd_set *readfds, fd_set *writefds, fd_set *exceptfds, fd_set **fdsBuf)
1110 {
1111 fd_set *readfdsRet = NULL;
1112 fd_set *writefdsRet = NULL;
1113 fd_set *exceptfdsRet = NULL;
1114
1115 *fdsBuf = (fd_set *)LOS_MemAlloc(OS_SYS_MEM_ADDR, sizeof(fd_set) * 3); /* 3: three param need check and copy */
1116 if (*fdsBuf == NULL) {
1117 return -ENOMEM;
1118 }
1119
1120 readfdsRet = *fdsBuf; /* LOS_MemAlloc 3 sizeof(fd_set) space,first use for readfds */
1121 writefdsRet = *fdsBuf + 1; /* 1: LOS_MemAlloc 3 sizeof(fd_set) space,second use for writefds */
1122 exceptfdsRet = *fdsBuf + 2; /* 2: LOS_MemAlloc 3 sizeof(fd_set) space,thired use for exceptfds */
1123
1124 if (readfds != NULL) {
1125 if (LOS_ArchCopyFromUser(readfdsRet, readfds, sizeof(fd_set)) != 0) {
1126 (void)LOS_MemFree(OS_SYS_MEM_ADDR, *fdsBuf);
1127 return -EFAULT;
1128 }
1129 }
1130
1131 if (writefds != NULL) {
1132 if (LOS_ArchCopyFromUser(writefdsRet, writefds, sizeof(fd_set)) != 0) {
1133 (void)LOS_MemFree(OS_SYS_MEM_ADDR, *fdsBuf);
1134 return -EFAULT;
1135 }
1136 }
1137
1138 if (exceptfds != NULL) {
1139 if (LOS_ArchCopyFromUser(exceptfdsRet, exceptfds, sizeof(fd_set)) != 0) {
1140 (void)LOS_MemFree(OS_SYS_MEM_ADDR, *fdsBuf);
1141 return -EFAULT;
1142 }
1143 }
1144
1145 return 0;
1146 }
1147
SysSelect(int nfds,fd_set * readfds,fd_set * writefds,fd_set * exceptfds,struct timeval * timeout)1148 int SysSelect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
1149 {
1150 int ret;
1151 fd_set *fdsRet = NULL;
1152 fd_set *readfdsRet = NULL;
1153 fd_set *writefdsRet = NULL;
1154 fd_set *exceptfdsRet = NULL;
1155 struct timeval timeoutRet = {0};
1156
1157 ret = SelectParamCheckCopy(readfds, writefds, exceptfds, &fdsRet);
1158 if (ret != 0) {
1159 return ret;
1160 }
1161
1162 readfdsRet = fdsRet; /* LOS_MemAlloc 3 sizeof(fd_set) space,first use for readfds */
1163 writefdsRet = fdsRet + 1; /* 1: LOS_MemAlloc 3 sizeof(fd_set) space,second use for writefds */
1164 exceptfdsRet = fdsRet + 2; /* 2: LOS_MemAlloc 3 sizeof(fd_set) space,thired use for exceptfds */
1165
1166 if (timeout != NULL) {
1167 if (LOS_ArchCopyFromUser(&timeoutRet, timeout, sizeof(struct timeval)) != 0) {
1168 goto ERROUT;
1169 }
1170 }
1171
1172 ret = do_select(nfds, (readfds ? readfdsRet : NULL), (writefds ? writefdsRet : NULL),
1173 (exceptfds ? exceptfdsRet : NULL), (timeout ? (&timeoutRet) : NULL), UserPoll);
1174 if (ret < 0) {
1175 (void)LOS_MemFree(OS_SYS_MEM_ADDR, fdsRet);
1176 return -get_errno();
1177 }
1178
1179 if (readfds != NULL) {
1180 if (LOS_ArchCopyToUser(readfds, readfdsRet, sizeof(fd_set)) != 0) {
1181 goto ERROUT;
1182 }
1183 }
1184
1185 if (writefds != NULL) {
1186 if (LOS_ArchCopyToUser(writefds, writefdsRet, sizeof(fd_set)) != 0) {
1187 goto ERROUT;
1188 }
1189 }
1190
1191 if (exceptfds != 0) {
1192 if (LOS_ArchCopyToUser(exceptfds, exceptfdsRet, sizeof(fd_set)) != 0) {
1193 goto ERROUT;
1194 }
1195 }
1196
1197 (void)LOS_MemFree(OS_SYS_MEM_ADDR, fdsRet);
1198 return ret;
1199
1200 ERROUT:
1201 (void)LOS_MemFree(OS_SYS_MEM_ADDR, fdsRet);
1202 return -EFAULT;
1203 }
1204
SysTruncate(const char * path,off_t length)1205 int SysTruncate(const char *path, off_t length)
1206 {
1207 int ret;
1208 int fd = -1;
1209 char *pathRet = NULL;
1210
1211 if (path != NULL) {
1212 ret = UserPathCopy(path, &pathRet);
1213 if (ret != 0) {
1214 goto OUT;
1215 }
1216 }
1217
1218 fd = open((path ? pathRet : NULL), O_RDWR);
1219 if (fd < 0) {
1220 /* The errno value has already been set */
1221 ret = -get_errno();
1222 goto OUT;
1223 }
1224
1225 ret = ftruncate(fd, length);
1226 close(fd);
1227 if (ret < 0) {
1228 ret = -get_errno();
1229 }
1230
1231 OUT:
1232 if (pathRet != NULL) {
1233 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1234 }
1235 return ret;
1236 }
1237
SysTruncate64(const char * path,off64_t length)1238 int SysTruncate64(const char *path, off64_t length)
1239 {
1240 int ret;
1241 int fd = -1;
1242 char *pathRet = NULL;
1243
1244 if (path != NULL) {
1245 ret = UserPathCopy(path, &pathRet);
1246 if (ret != 0) {
1247 goto OUT;
1248 }
1249 }
1250
1251 fd = open((path ? pathRet : NULL), O_RDWR);
1252 if (fd < 0) {
1253 /* The errno value has already been set */
1254 ret = -get_errno();
1255 goto OUT;
1256 }
1257
1258 ret = ftruncate64(fd, length);
1259 close(fd);
1260 if (ret < 0) {
1261 ret = -get_errno();
1262 }
1263
1264 OUT:
1265 if (pathRet != NULL) {
1266 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1267 }
1268 return ret;
1269 }
1270
SysFtruncate(int fd,off_t length)1271 int SysFtruncate(int fd, off_t length)
1272 {
1273 int ret;
1274
1275 /* Process fd convert to system global fd */
1276 fd = GetAssociatedSystemFd(fd);
1277
1278 ret = ftruncate(fd, length);
1279 if (ret < 0) {
1280 return -get_errno();
1281 }
1282 return ret;
1283 }
1284
SysStatfs(const char * path,struct statfs * buf)1285 int SysStatfs(const char *path, struct statfs *buf)
1286 {
1287 int ret;
1288 char *pathRet = NULL;
1289 struct statfs bufRet = {0};
1290
1291 if (path != NULL) {
1292 ret = UserPathCopy(path, &pathRet);
1293 if (ret != 0) {
1294 goto OUT;
1295 }
1296 }
1297
1298 ret = statfs((path ? pathRet : NULL), (buf ? (&bufRet) : NULL));
1299 if (ret < 0) {
1300 ret = -get_errno();
1301 goto OUT;
1302 }
1303
1304 ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct statfs));
1305 if (ret != 0) {
1306 ret = -EFAULT;
1307 }
1308
1309 OUT:
1310 if (pathRet != NULL) {
1311 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1312 }
1313 return ret;
1314 }
1315
SysStatfs64(const char * path,size_t sz,struct statfs * buf)1316 int SysStatfs64(const char *path, size_t sz, struct statfs *buf)
1317 {
1318 int ret;
1319 char *pathRet = NULL;
1320 struct statfs bufRet = {0};
1321
1322 if (path != NULL) {
1323 ret = UserPathCopy(path, &pathRet);
1324 if (ret != 0) {
1325 goto OUT;
1326 }
1327 }
1328
1329 if (sz != sizeof(*buf)) {
1330 ret = -EINVAL;
1331 goto OUT;
1332 }
1333
1334 ret = statfs((path ? pathRet : NULL), (buf ? (&bufRet) : NULL));
1335 if (ret < 0) {
1336 ret = -get_errno();
1337 goto OUT;
1338 }
1339
1340 ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct statfs));
1341 if (ret != 0) {
1342 ret = -EFAULT;
1343 }
1344
1345 OUT:
1346 if (pathRet != NULL) {
1347 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1348 }
1349 return ret;
1350 }
1351
SysStat(const char * path,struct kstat * buf)1352 int SysStat(const char *path, struct kstat *buf)
1353 {
1354 int ret;
1355 char *pathRet = NULL;
1356 struct stat bufRet = {0};
1357
1358 if (path != NULL) {
1359 ret = UserPathCopy(path, &pathRet);
1360 if (ret != 0) {
1361 goto OUT;
1362 }
1363 }
1364
1365 ret = stat((path ? pathRet : NULL), (buf ? (&bufRet) : NULL));
1366 if (ret < 0) {
1367 ret = -get_errno();
1368 goto OUT;
1369 }
1370
1371 ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct kstat));
1372 if (ret != 0) {
1373 ret = -EFAULT;
1374 }
1375
1376 OUT:
1377 if (pathRet != NULL) {
1378 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1379 }
1380 return ret;
1381 }
1382
SysLstat(const char * path,struct kstat * buffer)1383 int SysLstat(const char *path, struct kstat *buffer)
1384 {
1385 int ret;
1386 char *pathRet = NULL;
1387 struct stat bufRet = {0};
1388
1389 if (path != NULL) {
1390 ret = UserPathCopy(path, &pathRet);
1391 if (ret != 0) {
1392 goto OUT;
1393 }
1394 }
1395
1396 ret = stat((path ? pathRet : NULL), (buffer ? (&bufRet) : NULL));
1397 if (ret < 0) {
1398 ret = -get_errno();
1399 goto OUT;
1400 }
1401
1402 ret = LOS_ArchCopyToUser(buffer, &bufRet, sizeof(struct kstat));
1403 if (ret != 0) {
1404 ret = -EFAULT;
1405 }
1406
1407 OUT:
1408 if (pathRet != NULL) {
1409 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1410 }
1411 return ret;
1412 }
1413
SysFstat(int fd,struct kstat * buf)1414 int SysFstat(int fd, struct kstat *buf)
1415 {
1416 int ret;
1417 struct stat bufRet = {0};
1418 struct file *filep = NULL;
1419
1420 /* Process fd convert to system global fd */
1421 fd = GetAssociatedSystemFd(fd);
1422
1423 ret = fs_getfilep(fd, &filep);
1424 if (ret < 0) {
1425 return -get_errno();
1426 }
1427
1428 if (filep->f_oflags & O_DIRECTORY) {
1429 return -EBADF;
1430 }
1431
1432 ret = stat(filep->f_path, (buf ? (&bufRet) : NULL));
1433 if (ret < 0) {
1434 return -get_errno();
1435 }
1436
1437 ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct kstat));
1438 if (ret != 0) {
1439 return -EFAULT;
1440 }
1441
1442 return ret;
1443 }
1444
SysStatx(int fd,const char * restrict path,int flag,unsigned mask,struct statx * restrict stx)1445 int SysStatx(int fd, const char *restrict path, int flag, unsigned mask, struct statx *restrict stx)
1446 {
1447 return -ENOSYS;
1448 }
1449
SysFsync(int fd)1450 int SysFsync(int fd)
1451 {
1452 int ret;
1453 struct file *filep = NULL;
1454
1455 /* Process fd convert to system global fd */
1456 fd = GetAssociatedSystemFd(fd);
1457
1458 /* Get the file structure corresponding to the file descriptor. */
1459 ret = fs_getfilep(fd, &filep);
1460 if (ret < 0) {
1461 /* The errno value has already been set */
1462 return -get_errno();
1463 }
1464
1465 if (filep->f_oflags & O_DIRECTORY) {
1466 return -EBADF;
1467 }
1468
1469 /* Perform the fsync operation */
1470 ret = file_fsync(filep);
1471 if (ret < 0) {
1472 return -get_errno();
1473 }
1474 return ret;
1475 }
1476
SysReadv(int fd,const struct iovec * iov,int iovcnt)1477 ssize_t SysReadv(int fd, const struct iovec *iov, int iovcnt)
1478 {
1479 int ret;
1480 int valid_iovcnt = -1;
1481 struct iovec *iovRet = NULL;
1482
1483 /* Process fd convert to system global fd */
1484 fd = GetAssociatedSystemFd(fd);
1485 if ((iov == NULL) || (iovcnt < 0) || (iovcnt > IOV_MAX)) {
1486 return -EINVAL;
1487 }
1488
1489 if (iovcnt == 0) {
1490 return 0;
1491 }
1492
1493 ret = UserIovCopy(&iovRet, iov, iovcnt, &valid_iovcnt);
1494 if (ret != 0) {
1495 return ret;
1496 }
1497
1498 if (valid_iovcnt <= 0) {
1499 ret = -EFAULT;
1500 goto OUT;
1501 }
1502
1503 ret = vfs_readv(fd, iovRet, valid_iovcnt, NULL);
1504 if (ret < 0) {
1505 ret = -get_errno();
1506 }
1507
1508 OUT:
1509 (void)LOS_MemFree(OS_SYS_MEM_ADDR, iovRet);
1510 return ret;
1511 }
1512
SysWritev(int fd,const struct iovec * iov,int iovcnt)1513 ssize_t SysWritev(int fd, const struct iovec *iov, int iovcnt)
1514 {
1515 int ret;
1516 int valid_iovcnt = -1;
1517 struct iovec *iovRet = NULL;
1518
1519 /* Process fd convert to system global fd */
1520 int sysfd = GetAssociatedSystemFd(fd);
1521 if ((iovcnt < 0) || (iovcnt > IOV_MAX)) {
1522 return -EINVAL;
1523 }
1524
1525 if (iovcnt == 0) {
1526 return 0;
1527 }
1528
1529 if (iov == NULL) {
1530 return -EFAULT;
1531 }
1532
1533 ret = UserIovCopy(&iovRet, iov, iovcnt, &valid_iovcnt);
1534 if (ret != 0) {
1535 return ret;
1536 }
1537
1538 if (valid_iovcnt != iovcnt) {
1539 ret = -EFAULT;
1540 goto OUT_FREE;
1541 }
1542
1543 ret = writev(sysfd, iovRet, valid_iovcnt);
1544 if (ret < 0) {
1545 ret = -get_errno();
1546 }
1547
1548 OUT_FREE:
1549 (void)LOS_MemFree(OS_SYS_MEM_ADDR, iovRet);
1550 return ret;
1551 }
1552
SysPoll(struct pollfd * fds,nfds_t nfds,int timeout)1553 int SysPoll(struct pollfd *fds, nfds_t nfds, int timeout)
1554 {
1555 int ret;
1556 struct pollfd *kfds = NULL;
1557
1558 if ((nfds >= MAX_POLL_NFDS) || (nfds == 0) || (fds == NULL)) {
1559 return -EINVAL;
1560 }
1561
1562 kfds = (struct pollfd *)malloc(sizeof(struct pollfd) * nfds);
1563 if (kfds != NULL) {
1564 if (LOS_ArchCopyFromUser(kfds, fds, sizeof(struct pollfd) * nfds) != 0) {
1565 ret = -EFAULT;
1566 goto OUT_KFD;
1567 }
1568 }
1569
1570 int *pollFds = NULL;
1571 ret = PollfdToSystem(kfds, nfds, &pollFds);
1572 if (ret < 0) {
1573 ret = -get_errno();
1574 goto OUT_KFD;
1575 }
1576
1577 ret = poll(kfds, nfds, timeout);
1578 if (ret < 0) {
1579 ret = -get_errno();
1580 goto OUT;
1581 }
1582
1583 if (kfds != NULL) {
1584 RestorePollfd(kfds, nfds, pollFds);
1585 if (LOS_ArchCopyToUser(fds, kfds, sizeof(struct pollfd) * nfds) != 0) {
1586 ret = -EFAULT;
1587 goto OUT;
1588 }
1589 }
1590
1591 OUT:
1592 free(pollFds);
1593 OUT_KFD:
1594 free(kfds);
1595 return ret;
1596 }
1597
SysPrctl(int option,...)1598 int SysPrctl(int option, ...)
1599 {
1600 unsigned long name;
1601 va_list ap;
1602 errno_t err;
1603
1604 va_start(ap, option);
1605 if (option != PR_SET_NAME) {
1606 PRINT_ERR("%s: %d, no support option : 0x%x\n", __FUNCTION__, __LINE__, option);
1607 err = EOPNOTSUPP;
1608 goto ERROR;
1609 }
1610
1611 name = va_arg(ap, unsigned long);
1612 if (!LOS_IsUserAddress(name)) {
1613 err = EFAULT;
1614 goto ERROR;
1615 }
1616
1617 err = OsSetTaskName(OsCurrTaskGet(), (const char *)(uintptr_t)name, TRUE);
1618 if (err != LOS_OK) {
1619 goto ERROR;
1620 }
1621
1622 va_end(ap);
1623 return ENOERR;
1624
1625 ERROR:
1626 va_end(ap);
1627 return -err;
1628 }
1629
SysPread64(int fd,void * buf,size_t nbytes,off64_t offset)1630 ssize_t SysPread64(int fd, void *buf, size_t nbytes, off64_t offset)
1631 {
1632 int ret, retVal;
1633 char *bufRet = NULL;
1634
1635 /* Process fd convert to system global fd */
1636 fd = GetAssociatedSystemFd(fd);
1637
1638 if (nbytes == 0) {
1639 ret = pread64(fd, buf, nbytes, offset);
1640 if (ret < 0) {
1641 return -get_errno();
1642 } else {
1643 return ret;
1644 }
1645 }
1646
1647 bufRet = (char *)LOS_MemAlloc(OS_SYS_MEM_ADDR, nbytes);
1648 if (bufRet == NULL) {
1649 return -ENOMEM;
1650 }
1651 (void)memset_s(bufRet, nbytes, 0, nbytes);
1652 ret = pread64(fd, (buf ? bufRet : NULL), nbytes, offset);
1653 if (ret < 0) {
1654 (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet);
1655 return -get_errno();
1656 }
1657
1658 retVal = LOS_ArchCopyToUser(buf, bufRet, ret);
1659 if (retVal != 0) {
1660 (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet);
1661 return -EFAULT;
1662 }
1663
1664 (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet);
1665 return ret;
1666 }
1667
SysPwrite64(int fd,const void * buf,size_t nbytes,off64_t offset)1668 ssize_t SysPwrite64(int fd, const void *buf, size_t nbytes, off64_t offset)
1669 {
1670 int ret;
1671 char *bufRet = NULL;
1672
1673 /* Process fd convert to system global fd */
1674 fd = GetAssociatedSystemFd(fd);
1675
1676 if (nbytes == 0) {
1677 ret = pwrite64(fd, buf, nbytes, offset);
1678 if (ret < 0) {
1679 return -get_errno();
1680 }
1681 return ret;
1682 }
1683
1684 bufRet = (char *)LOS_MemAlloc(OS_SYS_MEM_ADDR, nbytes);
1685 if (bufRet == NULL) {
1686 return -ENOMEM;
1687 }
1688
1689 if (buf != NULL) {
1690 ret = LOS_ArchCopyFromUser(bufRet, buf, nbytes);
1691 if (ret != 0) {
1692 (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet);
1693 return -EFAULT;
1694 }
1695 }
1696
1697 ret = pwrite64(fd, (buf ? bufRet : NULL), nbytes, offset);
1698 if (ret < 0) {
1699 (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet);
1700 return -get_errno();
1701 }
1702
1703 (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet);
1704 return ret;
1705 }
1706
SysGetcwd(char * buf,size_t n)1707 char *SysGetcwd(char *buf, size_t n)
1708 {
1709 char *ret = NULL;
1710 char *bufRet = NULL;
1711 size_t bufLen = n;
1712 int retVal;
1713
1714 if (bufLen > PATH_MAX) {
1715 bufLen = PATH_MAX;
1716 }
1717
1718 bufRet = (char *)LOS_MemAlloc(OS_SYS_MEM_ADDR, bufLen);
1719 if (bufRet == NULL) {
1720 return (char *)(intptr_t)-ENOMEM;
1721 }
1722 (void)memset_s(bufRet, bufLen, 0, bufLen);
1723
1724 ret = getcwd((buf ? bufRet : NULL), bufLen);
1725 if (ret == NULL) {
1726 (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet);
1727 return (char *)(intptr_t)-get_errno();
1728 }
1729
1730 retVal = LOS_ArchCopyToUser(buf, bufRet, bufLen);
1731 if (retVal != 0) {
1732 (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet);
1733 return (char *)(intptr_t)-EFAULT;
1734 }
1735 ret = buf;
1736
1737 (void)LOS_MemFree(OS_SYS_MEM_ADDR, bufRet);
1738 return ret;
1739 }
1740
SysSendFile(int outfd,int infd,off_t * offset,size_t count)1741 ssize_t SysSendFile(int outfd, int infd, off_t *offset, size_t count)
1742 {
1743 int ret, retVal;
1744 off_t offsetRet;
1745
1746 retVal = LOS_ArchCopyFromUser(&offsetRet, offset, sizeof(off_t));
1747 if (retVal != 0) {
1748 return -EFAULT;
1749 }
1750
1751 /* Process fd convert to system global fd */
1752 outfd = GetAssociatedSystemFd(outfd);
1753 infd = GetAssociatedSystemFd(infd);
1754
1755 ret = sendfile(outfd, infd, (offset ? (&offsetRet) : NULL), count);
1756 if (ret < 0) {
1757 return -get_errno();
1758 }
1759
1760 retVal = LOS_ArchCopyToUser(offset, &offsetRet, sizeof(off_t));
1761 if (retVal != 0) {
1762 return -EFAULT;
1763 }
1764
1765 return ret;
1766 }
1767
SysFtruncate64(int fd,off64_t length)1768 int SysFtruncate64(int fd, off64_t length)
1769 {
1770 int ret;
1771
1772 /* Process fd convert to system global fd */
1773 fd = GetAssociatedSystemFd(fd);
1774
1775 ret = ftruncate64(fd, length);
1776 if (ret < 0) {
1777 return -get_errno();
1778 }
1779 return ret;
1780 }
1781
SysOpenat(int dirfd,const char * path,int oflags,...)1782 int SysOpenat(int dirfd, const char *path, int oflags, ...)
1783 {
1784 int ret;
1785 int procFd;
1786 char *pathRet = NULL;
1787 mode_t mode;
1788 #ifdef LOSCFG_FILE_MODE
1789 va_list ap;
1790
1791 va_start(ap, oflags);
1792 mode = va_arg(ap, int);
1793 va_end(ap);
1794 #else
1795 mode = 0666; /* 0666: File read-write properties. */
1796 #endif
1797
1798 if (path != NULL) {
1799 ret = UserPathCopy(path, &pathRet);
1800 if (ret != 0) {
1801 return ret;
1802 }
1803 }
1804
1805 procFd = AllocProcessFd();
1806 if (procFd < 0) {
1807 ret = -EMFILE;
1808 goto ERROUT;
1809 }
1810
1811 if (oflags & O_CLOEXEC) {
1812 SetCloexecFlag(procFd);
1813 }
1814
1815 if (dirfd != AT_FDCWD) {
1816 /* Process fd convert to system global fd */
1817 dirfd = GetAssociatedSystemFd(dirfd);
1818 }
1819
1820 ret = do_open(dirfd, (path ? pathRet : NULL), oflags, mode);
1821 if (ret < 0) {
1822 ret = -get_errno();
1823 goto ERROUT;
1824 }
1825
1826 AssociateSystemFd(procFd, ret);
1827 if (pathRet != NULL) {
1828 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1829 }
1830 return procFd;
1831
1832 ERROUT:
1833 if (pathRet != NULL) {
1834 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1835 }
1836 if (procFd >= 0) {
1837 FreeProcessFd(procFd);
1838 }
1839 return ret;
1840 }
1841
SysMkdirat(int dirfd,const char * pathname,mode_t mode)1842 int SysMkdirat(int dirfd, const char *pathname, mode_t mode)
1843 {
1844 int ret;
1845 char *pathRet = NULL;
1846
1847 if (pathname != NULL) {
1848 ret = UserPathCopy(pathname, &pathRet);
1849 if (ret != 0) {
1850 goto OUT;
1851 }
1852 }
1853
1854 if (dirfd != AT_FDCWD) {
1855 /* Process fd convert to system global fd */
1856 dirfd = GetAssociatedSystemFd(dirfd);
1857 }
1858
1859 ret = do_mkdir(dirfd, (pathname ? pathRet : NULL), mode);
1860 if (ret < 0) {
1861 ret = -get_errno();
1862 }
1863
1864 OUT:
1865 if (pathRet != NULL) {
1866 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1867 }
1868 return ret;
1869 }
1870
SysLinkat(int olddirfd,const char * oldpath,int newdirfd,const char * newpath,int flags)1871 int SysLinkat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath, int flags)
1872 {
1873 int ret;
1874 char *oldpathRet = NULL;
1875 char *newpathRet = NULL;
1876
1877 if (oldpath != NULL) {
1878 ret = UserPathCopy(oldpath, &oldpathRet);
1879 if (ret != 0) {
1880 goto OUT;
1881 }
1882 }
1883
1884 if (newpath != NULL) {
1885 ret = UserPathCopy(newpath, &newpathRet);
1886 if (ret != 0) {
1887 goto OUT;
1888 }
1889 }
1890
1891 if (olddirfd != AT_FDCWD) {
1892 /* Process fd convert to system global fd */
1893 olddirfd = GetAssociatedSystemFd(olddirfd);
1894 }
1895
1896 if (newdirfd != AT_FDCWD) {
1897 /* Process fd convert to system global fd */
1898 newdirfd = GetAssociatedSystemFd(newdirfd);
1899 }
1900
1901 ret = linkat(olddirfd, oldpathRet, newdirfd, newpathRet, flags);
1902 if (ret < 0) {
1903 ret = -get_errno();
1904 }
1905
1906 OUT:
1907 if (oldpathRet != NULL) {
1908 (void)LOS_MemFree(OS_SYS_MEM_ADDR, oldpathRet);
1909 }
1910 if (newpathRet != NULL) {
1911 (void)LOS_MemFree(OS_SYS_MEM_ADDR, newpathRet);
1912 }
1913 return ret;
1914 }
1915
SysSymlinkat(const char * target,int dirfd,const char * linkpath)1916 int SysSymlinkat(const char *target, int dirfd, const char *linkpath)
1917 {
1918 int ret;
1919 char *pathRet = NULL;
1920 char *targetRet = NULL;
1921
1922 if (target != NULL) {
1923 ret = UserPathCopy(target, &targetRet);
1924 if (ret != 0) {
1925 goto OUT;
1926 }
1927 }
1928
1929 if (linkpath != NULL) {
1930 ret = UserPathCopy(linkpath, &pathRet);
1931 if (ret != 0) {
1932 goto OUT;
1933 }
1934 }
1935
1936 if (dirfd != AT_FDCWD) {
1937 /* Process fd convert to system global fd */
1938 dirfd = GetAssociatedSystemFd(dirfd);
1939 }
1940
1941 ret = symlinkat(targetRet, dirfd, pathRet);
1942 if (ret < 0) {
1943 ret = -get_errno();
1944 }
1945
1946 OUT:
1947 if (pathRet != NULL) {
1948 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
1949 }
1950
1951 if (targetRet != NULL) {
1952 (void)LOS_MemFree(OS_SYS_MEM_ADDR, targetRet);
1953 }
1954 return ret;
1955 }
1956
SysReadlinkat(int dirfd,const char * pathname,char * buf,size_t bufsize)1957 ssize_t SysReadlinkat(int dirfd, const char *pathname, char *buf, size_t bufsize)
1958 {
1959 ssize_t ret;
1960 char *pathRet = NULL;
1961
1962 if (bufsize == 0) {
1963 return -EINVAL;
1964 }
1965
1966 if (pathname != NULL) {
1967 ret = UserPathCopy(pathname, &pathRet);
1968 if (ret != 0) {
1969 goto OUT;
1970 }
1971
1972 #ifdef LOSCFG_PID_CONTAINER
1973 #ifdef LOSCFG_PROC_PROCESS_DIR
1974 ret = ProcRealProcessDirGet(pathRet);
1975 if (ret != 0) {
1976 goto OUT;
1977 }
1978 #endif
1979 #endif
1980 }
1981
1982 if (dirfd != AT_FDCWD) {
1983 /* Process fd convert to system global fd */
1984 dirfd = GetAssociatedSystemFd(dirfd);
1985 }
1986
1987 if (!LOS_IsUserAddressRange((vaddr_t)(UINTPTR)buf, bufsize)) {
1988 ret = -EFAULT;
1989 goto OUT;
1990 }
1991
1992 ret = readlinkat(dirfd, pathRet, buf, bufsize);
1993 if (ret < 0) {
1994 ret = -get_errno();
1995 }
1996
1997 OUT:
1998 if (pathRet != NULL) {
1999 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
2000 }
2001 return ret;
2002 }
2003
SysUnlinkat(int dirfd,const char * pathname,int flag)2004 int SysUnlinkat(int dirfd, const char *pathname, int flag)
2005 {
2006 int ret;
2007 char *pathRet = NULL;
2008
2009 if (pathname != NULL) {
2010 ret = UserPathCopy(pathname, &pathRet);
2011 if (ret != 0) {
2012 goto OUT;
2013 }
2014 }
2015
2016 if (dirfd != AT_FDCWD) {
2017 /* Process fd convert to system global fd */
2018 dirfd = GetAssociatedSystemFd(dirfd);
2019 }
2020
2021 ret = unlinkat(dirfd, (pathname ? pathRet : NULL), flag);
2022 if (ret < 0) {
2023 ret = -get_errno();
2024 }
2025
2026 OUT:
2027 if (pathRet != NULL) {
2028 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
2029 }
2030 return ret;
2031 }
2032
SysRenameat(int oldfd,const char * oldpath,int newdfd,const char * newpath)2033 int SysRenameat(int oldfd, const char *oldpath, int newdfd, const char *newpath)
2034 {
2035 int ret;
2036 char *pathOldRet = NULL;
2037 char *pathNewRet = NULL;
2038
2039 if (oldpath != NULL) {
2040 ret = UserPathCopy(oldpath, &pathOldRet);
2041 if (ret != 0) {
2042 goto OUT;
2043 }
2044 }
2045
2046 if (newpath != NULL) {
2047 ret = UserPathCopy(newpath, &pathNewRet);
2048 if (ret != 0) {
2049 goto OUT;
2050 }
2051 }
2052
2053 if (oldfd != AT_FDCWD) {
2054 /* Process fd convert to system global fd */
2055 oldfd = GetAssociatedSystemFd(oldfd);
2056 }
2057 if (newdfd != AT_FDCWD) {
2058 /* Process fd convert to system global fd */
2059 newdfd = GetAssociatedSystemFd(newdfd);
2060 }
2061
2062 ret = do_rename(oldfd, (oldpath ? pathOldRet : NULL), newdfd, (newpath ? pathNewRet : NULL));
2063 if (ret < 0) {
2064 ret = -get_errno();
2065 }
2066
2067 OUT:
2068 if (pathOldRet != NULL) {
2069 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathOldRet);
2070 }
2071 if (pathNewRet != NULL) {
2072 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathNewRet);
2073 }
2074 return ret;
2075 }
2076
SysFallocate(int fd,int mode,off_t offset,off_t len)2077 int SysFallocate(int fd, int mode, off_t offset, off_t len)
2078 {
2079 int ret;
2080
2081 /* Process fd convert to system global fd */
2082 fd = GetAssociatedSystemFd(fd);
2083
2084 ret = fallocate(fd, mode, offset, len);
2085 if (ret < 0) {
2086 return -get_errno();
2087 }
2088 return ret;
2089 }
2090
SysFallocate64(int fd,int mode,off64_t offset,off64_t len)2091 int SysFallocate64(int fd, int mode, off64_t offset, off64_t len)
2092 {
2093 int ret;
2094
2095 /* Process fd convert to system global fd */
2096 fd = GetAssociatedSystemFd(fd);
2097
2098 ret = fallocate64(fd, mode, offset, len);
2099 if (ret < 0) {
2100 return -get_errno();
2101 }
2102 return ret;
2103 }
2104
SysPreadv(int fd,const struct iovec * iov,int iovcnt,long loffset,long hoffset)2105 ssize_t SysPreadv(int fd, const struct iovec *iov, int iovcnt, long loffset, long hoffset)
2106 {
2107 off_t offsetflag;
2108 offsetflag = (off_t)((unsigned long long)loffset | (((unsigned long long)hoffset) << HIGH_SHIFT_BIT));
2109
2110 int ret;
2111 int valid_iovcnt = -1;
2112 struct iovec *iovRet = NULL;
2113
2114 /* Process fd convert to system global fd */
2115 fd = GetAssociatedSystemFd(fd);
2116 if ((iov == NULL) || (iovcnt < 0) || (iovcnt > IOV_MAX)) {
2117 return -EINVAL;
2118 }
2119
2120 if (iovcnt == 0) {
2121 return 0;
2122 }
2123
2124 ret = UserIovCopy(&iovRet, iov, iovcnt, &valid_iovcnt);
2125 if (ret != 0) {
2126 return ret;
2127 }
2128
2129 if (valid_iovcnt <= 0) {
2130 ret = -EFAULT;
2131 goto OUT_FREE;
2132 }
2133
2134 ret = preadv(fd, iovRet, valid_iovcnt, offsetflag);
2135 if (ret < 0) {
2136 ret = -get_errno();
2137 }
2138
2139 OUT_FREE:
2140 (void)(void)LOS_MemFree(OS_SYS_MEM_ADDR, iovRet);
2141 return ret;
2142 }
2143
SysPwritev(int fd,const struct iovec * iov,int iovcnt,long loffset,long hoffset)2144 ssize_t SysPwritev(int fd, const struct iovec *iov, int iovcnt, long loffset, long hoffset)
2145 {
2146 off_t offsetflag;
2147 offsetflag = (off_t)((unsigned long long)loffset | (((unsigned long long)hoffset) << HIGH_SHIFT_BIT));
2148 int ret;
2149 int valid_iovcnt = -1;
2150 struct iovec *iovRet = NULL;
2151
2152 /* Process fd convert to system global fd */
2153 fd = GetAssociatedSystemFd(fd);
2154 if ((iov == NULL) || (iovcnt < 0) || (iovcnt > IOV_MAX)) {
2155 return -EINVAL;
2156 }
2157
2158 if (iovcnt == 0) {
2159 return 0;
2160 }
2161
2162 ret = UserIovCopy(&iovRet, iov, iovcnt, &valid_iovcnt);
2163 if (ret != 0) {
2164 return ret;
2165 }
2166
2167 if (valid_iovcnt != iovcnt) {
2168 ret = -EFAULT;
2169 goto OUT_FREE;
2170 }
2171
2172 ret = pwritev(fd, iovRet, valid_iovcnt, offsetflag);
2173 if (ret < 0) {
2174 ret = -get_errno();
2175 }
2176
2177 OUT_FREE:
2178 (void)LOS_MemFree(OS_SYS_MEM_ADDR, iovRet);
2179 return ret;
2180 }
2181
2182 #ifdef LOSCFG_FS_FAT
SysFormat(const char * dev,int sectors,int option)2183 int SysFormat(const char *dev, int sectors, int option)
2184 {
2185 int ret;
2186 char *devRet = NULL;
2187
2188 if (!IsCapPermit(CAP_FS_FORMAT)) {
2189 return -EPERM;
2190 }
2191
2192 if (dev != NULL) {
2193 ret = UserPathCopy(dev, &devRet);
2194 if (ret != 0) {
2195 goto OUT;
2196 }
2197 }
2198
2199 ret = format((dev ? devRet : NULL), sectors, option);
2200 if (ret < 0) {
2201 ret = -get_errno();
2202 }
2203
2204 OUT:
2205 if (devRet != NULL) {
2206 (void)LOS_MemFree(OS_SYS_MEM_ADDR, devRet);
2207 }
2208 return ret;
2209 }
2210 #endif
2211
SysFstat64(int fd,struct kstat * buf)2212 int SysFstat64(int fd, struct kstat *buf)
2213 {
2214 int ret;
2215 struct stat64 bufRet = {0};
2216
2217 /* Process fd convert to system global fd */
2218 fd = GetAssociatedSystemFd(fd);
2219
2220 ret = fstat64(fd, (buf ? (&bufRet) : NULL));
2221 if (ret < 0) {
2222 return -get_errno();
2223 }
2224
2225 ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct kstat));
2226 if (ret != 0) {
2227 return -EFAULT;
2228 }
2229
2230 return ret;
2231 }
2232
SysFcntl64(int fd,int cmd,void * arg)2233 int SysFcntl64(int fd, int cmd, void *arg)
2234 {
2235 /* Process fd convert to system global fd */
2236 int sysfd = GetAssociatedSystemFd(fd);
2237
2238 int ret = VfsFcntl(fd, cmd, arg);
2239 if (ret == CONTINE_NUTTX_FCNTL) {
2240 ret = fcntl64(sysfd, cmd, arg);
2241 }
2242
2243 if (ret < 0) {
2244 return -get_errno();
2245 }
2246 return ret;
2247 }
2248
SysGetdents64(int fd,struct dirent * de_user,unsigned int count)2249 int SysGetdents64(int fd, struct dirent *de_user, unsigned int count)
2250 {
2251 if (!LOS_IsUserAddressRange((VADDR_T)(UINTPTR)de_user, count)) {
2252 return -EFAULT;
2253 }
2254
2255 struct dirent *de_knl = NULL;
2256
2257 /* Process fd convert to system global fd */
2258 fd = GetAssociatedSystemFd(fd);
2259
2260 int ret = do_readdir(fd, &de_knl, count);
2261 if (ret < 0) {
2262 return ret;
2263 }
2264 if (de_knl != NULL) {
2265 int cpy_ret = LOS_ArchCopyToUser(de_user, de_knl, ret);
2266 if (cpy_ret != 0)
2267 {
2268 return -EFAULT;
2269 }
2270 }
2271 return ret;
2272 }
2273
SysRealpath(const char * path,char * resolved_path)2274 char *SysRealpath(const char *path, char *resolved_path)
2275 {
2276 char *pathRet = NULL;
2277 char *resolved_pathRet = NULL;
2278 char *result = NULL;
2279 int ret;
2280
2281 if (resolved_path == NULL) {
2282 return (char *)(intptr_t)-EINVAL;
2283 }
2284
2285 if (path != NULL) {
2286 ret = UserPathCopy(path, &pathRet);
2287 if (ret != 0) {
2288 result = (char *)(intptr_t)ret;
2289 goto OUT;
2290 }
2291 }
2292
2293 resolved_pathRet = realpath((path ? pathRet : NULL), NULL);
2294 if (resolved_pathRet == NULL) {
2295 result = (char *)(intptr_t)-get_errno();
2296 goto OUT;
2297 }
2298
2299 ret = LOS_ArchCopyToUser(resolved_path, resolved_pathRet, strlen(resolved_pathRet) + 1);
2300 if (ret != 0) {
2301 result = (char *)(intptr_t)-EFAULT;
2302 goto OUT;
2303 }
2304 result = resolved_path;
2305
2306 OUT:
2307 if (pathRet != NULL) {
2308 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
2309 }
2310 if (resolved_pathRet != NULL) {
2311 (void)LOS_MemFree(OS_SYS_MEM_ADDR, resolved_pathRet);
2312 }
2313 return result;
2314 }
2315
SysUtimensat(int fd,const char * path,struct timespec times[TIMESPEC_TIMES_NUM],int flag)2316 int SysUtimensat(int fd, const char *path, struct timespec times[TIMESPEC_TIMES_NUM], int flag)
2317 {
2318 int ret;
2319 int timeLen;
2320 struct IATTR attr = {0};
2321 char *filePath = NULL;
2322
2323 timeLen = TIMESPEC_TIMES_NUM * sizeof(struct timespec);
2324 CHECK_ASPACE(times, timeLen);
2325 DUP_FROM_USER(times, timeLen);
2326 ret = CheckNewAttrTime(&attr, times);
2327 FREE_DUP(times);
2328 if (ret < 0) {
2329 goto OUT;
2330 }
2331
2332 ret = GetFullpathNull(fd, path, &filePath);
2333 if (ret < 0) {
2334 goto OUT;
2335 }
2336
2337 ret = chattr(filePath, &attr);
2338 if (ret < 0) {
2339 ret = -get_errno();
2340 }
2341
2342 OUT:
2343 PointerFree(filePath);
2344 return ret;
2345 }
2346
SysChmod(const char * pathname,mode_t mode)2347 int SysChmod(const char *pathname, mode_t mode)
2348 {
2349 int ret;
2350 char *pathRet = NULL;
2351
2352 if (pathname != NULL) {
2353 ret = UserPathCopy(pathname, &pathRet);
2354 if (ret != 0) {
2355 goto OUT;
2356 }
2357 }
2358
2359 ret = chmod(pathRet, mode);
2360 if (ret < 0) {
2361 ret = -get_errno();
2362 }
2363
2364 OUT:
2365 if (pathRet != NULL) {
2366 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
2367 }
2368 return ret;
2369 }
2370
SysFchmodat(int fd,const char * path,mode_t mode,int flag)2371 int SysFchmodat(int fd, const char *path, mode_t mode, int flag)
2372 {
2373 int ret;
2374 char *pathRet = NULL;
2375 char *fullpath = NULL;
2376 struct IATTR attr = {
2377 .attr_chg_mode = mode,
2378 .attr_chg_valid = CHG_MODE,
2379 };
2380
2381 if (path != NULL) {
2382 ret = UserPathCopy(path, &pathRet);
2383 if (ret != 0) {
2384 goto OUT;
2385 }
2386 }
2387
2388 if (fd != AT_FDCWD) {
2389 /* Process fd convert to system global fd */
2390 fd = GetAssociatedSystemFd(fd);
2391 }
2392
2393 ret = vfs_normalize_pathat(fd, pathRet, &fullpath);
2394 if (ret < 0) {
2395 goto OUT;
2396 }
2397
2398 ret = chattr(fullpath, &attr);
2399 if (ret < 0) {
2400 ret = -get_errno();
2401 }
2402
2403 OUT:
2404 PointerFree(pathRet);
2405 PointerFree(fullpath);
2406
2407 return ret;
2408 }
2409
SysFchmod(int fd,mode_t mode)2410 int SysFchmod(int fd, mode_t mode)
2411 {
2412 int ret;
2413 int sysFd;
2414 struct IATTR attr = {
2415 .attr_chg_mode = mode,
2416 .attr_chg_valid = CHG_MODE, /* change mode */
2417 };
2418 struct file *file = NULL;
2419
2420 sysFd = GetAssociatedSystemFd(fd);
2421 if (sysFd < 0) {
2422 return -EBADF;
2423 }
2424
2425 ret = fs_getfilep(sysFd, &file);
2426 if (ret < 0) {
2427 return -get_errno();
2428 }
2429
2430 ret = chattr(file->f_path, &attr);
2431 if (ret < 0) {
2432 return -get_errno();
2433 }
2434
2435 return ret;
2436 }
2437
SysFchownat(int fd,const char * path,uid_t owner,gid_t group,int flag)2438 int SysFchownat(int fd, const char *path, uid_t owner, gid_t group, int flag)
2439 {
2440 int ret;
2441 char *fullpath = NULL;
2442 struct IATTR attr = {
2443 .attr_chg_valid = 0,
2444 };
2445
2446 ret = GetFullpath(fd, path, &fullpath);
2447 if (ret < 0) {
2448 goto OUT;
2449 }
2450
2451 if (owner != (uid_t)-1) {
2452 attr.attr_chg_uid = owner;
2453 attr.attr_chg_valid |= CHG_UID;
2454 }
2455 if (group != (gid_t)-1) {
2456 attr.attr_chg_gid = group;
2457 attr.attr_chg_valid |= CHG_GID;
2458 }
2459
2460 ret = chattr(fullpath, &attr);
2461 if (ret < 0) {
2462 ret = -get_errno();
2463 }
2464
2465 OUT:
2466 PointerFree(fullpath);
2467
2468 return ret;
2469 }
2470
SysFchown(int fd,uid_t owner,gid_t group)2471 int SysFchown(int fd, uid_t owner, gid_t group)
2472 {
2473 int ret;
2474 int sysFd;
2475 struct IATTR attr = {0};
2476 attr.attr_chg_valid = 0;
2477 struct file *file = NULL;
2478
2479 sysFd = GetAssociatedSystemFd(fd);
2480 if (sysFd < 0) {
2481 return -EBADF;
2482 }
2483
2484 ret = fs_getfilep(sysFd, &file);
2485 if (ret < 0) {
2486 return -get_errno();
2487 }
2488
2489 if (owner != (uid_t)-1) {
2490 attr.attr_chg_uid = owner;
2491 attr.attr_chg_valid |= CHG_UID;
2492 }
2493 if (group != (gid_t)-1) {
2494 attr.attr_chg_gid = group;
2495 attr.attr_chg_valid |= CHG_GID;
2496 }
2497 ret = chattr(file->f_path, &attr);
2498 if (ret < 0) {
2499 ret = -get_errno();
2500 }
2501
2502 return ret;
2503 }
2504
SysChown(const char * pathname,uid_t owner,gid_t group)2505 int SysChown(const char *pathname, uid_t owner, gid_t group)
2506 {
2507 int ret;
2508 char *pathRet = NULL;
2509
2510 if (pathname != NULL) {
2511 ret = UserPathCopy(pathname, &pathRet);
2512 if (ret != 0) {
2513 goto OUT;
2514 }
2515 }
2516
2517 ret = chown(pathRet, owner, group);
2518 if (ret < 0) {
2519 ret = -get_errno();
2520 }
2521
2522 OUT:
2523 if (pathRet != NULL) {
2524 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
2525 }
2526 return ret;
2527 }
2528
SysFstatat64(int dirfd,const char * restrict path,struct kstat * restrict buf,int flag)2529 int SysFstatat64(int dirfd, const char *restrict path, struct kstat *restrict buf, int flag)
2530 {
2531 int ret;
2532 struct stat bufRet = {0};
2533 char *pathRet = NULL;
2534 char *fullpath = NULL;
2535
2536 if (path != NULL) {
2537 ret = UserPathCopy(path, &pathRet);
2538 if (ret != 0) {
2539 goto OUT;
2540 }
2541 }
2542
2543 if (dirfd != AT_FDCWD) {
2544 /* Process fd convert to system global fd */
2545 dirfd = GetAssociatedSystemFd(dirfd);
2546 }
2547
2548 ret = vfs_normalize_pathat(dirfd, pathRet, &fullpath);
2549 if (ret < 0) {
2550 goto OUT;
2551 }
2552
2553 ret = stat(fullpath, &bufRet);
2554 if (ret < 0) {
2555 ret = -get_errno();
2556 goto OUT;
2557 }
2558
2559 ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct kstat));
2560 if (ret != 0) {
2561 ret = -EFAULT;
2562 goto OUT;
2563 }
2564
2565 OUT:
2566 if (pathRet != NULL) {
2567 LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
2568 }
2569
2570 if (fullpath != NULL) {
2571 free(fullpath);
2572 }
2573 return ret;
2574 }
2575
SysFaccessat(int fd,const char * filename,int amode,int flag)2576 int SysFaccessat(int fd, const char *filename, int amode, int flag)
2577 {
2578 int ret;
2579 struct stat buf;
2580 struct statfs fsBuf;
2581 char *fullDirectory = NULL;
2582
2583 ret = GetFullpath(fd, filename, &fullDirectory);
2584 if (ret < 0) {
2585 goto OUT;
2586 }
2587
2588 ret = statfs(fullDirectory, &fsBuf);
2589 if (ret != 0) {
2590 ret = -get_errno();
2591 goto OUT;
2592 }
2593
2594 if ((fsBuf.f_flags & MS_RDONLY) && ((unsigned int)amode & W_OK)) {
2595 ret = -EROFS;
2596 goto OUT;
2597 }
2598
2599 ret = stat(fullDirectory, &buf);
2600 if (ret != 0) {
2601 ret = -get_errno();
2602 goto OUT;
2603 }
2604
2605 if (VfsPermissionCheck(buf.st_uid, buf.st_gid, buf.st_mode, amode)) {
2606 ret = -EACCES;
2607 }
2608
2609 OUT:
2610 PointerFree(fullDirectory);
2611
2612 return ret;
2613 }
2614
SysFstatfs(int fd,struct statfs * buf)2615 int SysFstatfs(int fd, struct statfs *buf)
2616 {
2617 int ret;
2618 struct file *filep = NULL;
2619 struct statfs bufRet = {0};
2620
2621 /* Process fd convert to system global fd */
2622 fd = GetAssociatedSystemFd(fd);
2623
2624 ret = fs_getfilep(fd, &filep);
2625 if (ret < 0) {
2626 ret = -get_errno();
2627 return ret;
2628 }
2629
2630 ret = statfs(filep->f_path, &bufRet);
2631 if (ret < 0) {
2632 ret = -get_errno();
2633 return ret;
2634 }
2635
2636 ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct statfs));
2637 if (ret != 0) {
2638 ret = -EFAULT;
2639 }
2640
2641 return ret;
2642 }
2643
SysFstatfs64(int fd,size_t sz,struct statfs * buf)2644 int SysFstatfs64(int fd, size_t sz, struct statfs *buf)
2645 {
2646 int ret;
2647
2648 if (sz != sizeof(struct statfs)) {
2649 ret = -EINVAL;
2650 return ret;
2651 }
2652
2653 ret = SysFstatfs(fd, buf);
2654
2655 return ret;
2656 }
2657
SysPpoll(struct pollfd * fds,nfds_t nfds,const struct timespec * tmo_p,const sigset_t * sigMask,int nsig)2658 int SysPpoll(struct pollfd *fds, nfds_t nfds, const struct timespec *tmo_p, const sigset_t *sigMask, int nsig)
2659 {
2660 int timeout, retVal;
2661 sigset_t_l origMask = {0};
2662 sigset_t_l set = {0};
2663
2664 CHECK_ASPACE(tmo_p, sizeof(struct timespec));
2665 CPY_FROM_USER(tmo_p);
2666
2667 if (tmo_p != NULL) {
2668 timeout = tmo_p->tv_sec * OS_SYS_US_PER_MS + tmo_p->tv_nsec / OS_SYS_NS_PER_MS;
2669 if (timeout < 0) {
2670 return -EINVAL;
2671 }
2672 } else {
2673 timeout = -1;
2674 }
2675
2676 if (sigMask != NULL) {
2677 retVal = LOS_ArchCopyFromUser(&set, sigMask, sizeof(sigset_t));
2678 if (retVal != 0) {
2679 return -EFAULT;
2680 }
2681 (VOID)OsSigprocMask(SIG_SETMASK, &set, &origMask);
2682 } else {
2683 (VOID)OsSigprocMask(SIG_SETMASK, NULL, &origMask);
2684 }
2685
2686 retVal = SysPoll(fds, nfds, timeout);
2687 (VOID)OsSigprocMask(SIG_SETMASK, &origMask, NULL);
2688
2689 return retVal;
2690 }
2691
SysPselect6(int nfds,fd_set * readfds,fd_set * writefds,fd_set * exceptfds,const struct timespec * timeout,const long data[2])2692 int SysPselect6(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
2693 const struct timespec *timeout, const long data[2])
2694 {
2695 int ret;
2696 int retVal;
2697 sigset_t_l origMask;
2698 sigset_t_l setl;
2699
2700 CHECK_ASPACE(readfds, sizeof(fd_set));
2701 CHECK_ASPACE(writefds, sizeof(fd_set));
2702 CHECK_ASPACE(exceptfds, sizeof(fd_set));
2703 CHECK_ASPACE(timeout, sizeof(struct timeval));
2704
2705 CPY_FROM_USER(readfds);
2706 CPY_FROM_USER(writefds);
2707 CPY_FROM_USER(exceptfds);
2708 DUP_FROM_USER(timeout, sizeof(struct timeval));
2709
2710 if (timeout != NULL) {
2711 ((struct timeval *)timeout)->tv_usec = timeout->tv_nsec / 1000; /* 1000, convert ns to us */
2712 }
2713
2714 if (data != NULL) {
2715 retVal = LOS_ArchCopyFromUser(&(setl.sig[0]), (int *)((UINTPTR)data[0]), sizeof(sigset_t));
2716 if (retVal != 0) {
2717 ret = -EFAULT;
2718 FREE_DUP(timeout);
2719 return ret;
2720 }
2721 }
2722
2723 OsSigprocMask(SIG_SETMASK, &setl, &origMask);
2724 ret = do_select(nfds, readfds, writefds, exceptfds, (struct timeval *)timeout, UserPoll);
2725 if (ret < 0) {
2726 /* do not copy parameter back to user mode if do_select failed */
2727 ret = -get_errno();
2728 FREE_DUP(timeout);
2729 return ret;
2730 }
2731 OsSigprocMask(SIG_SETMASK, &origMask, NULL);
2732
2733 CPY_TO_USER(readfds);
2734 CPY_TO_USER(writefds);
2735 CPY_TO_USER(exceptfds);
2736 FREE_DUP(timeout);
2737
2738 return ret;
2739 }
2740
DoEpollCreate1(int flags)2741 static int DoEpollCreate1(int flags)
2742 {
2743 int ret;
2744 int procFd;
2745
2746 ret = epoll_create1(flags);
2747 if (ret < 0) {
2748 ret = -get_errno();
2749 return ret;
2750 }
2751
2752 procFd = AllocAndAssocProcessFd((INTPTR)(ret), MIN_START_FD);
2753 if (procFd == -1) {
2754 epoll_close(ret);
2755 return -EMFILE;
2756 }
2757
2758 return procFd;
2759 }
2760
SysEpollCreate(int size)2761 int SysEpollCreate(int size)
2762 {
2763 (void)size;
2764 return DoEpollCreate1(0);
2765 }
2766
SysEpollCreate1(int flags)2767 int SysEpollCreate1(int flags)
2768 {
2769 return DoEpollCreate1(flags);
2770 }
2771
SysEpollCtl(int epfd,int op,int fd,struct epoll_event * ev)2772 int SysEpollCtl(int epfd, int op, int fd, struct epoll_event *ev)
2773 {
2774 int ret;
2775
2776 CHECK_ASPACE(ev, sizeof(struct epoll_event));
2777 CPY_FROM_USER(ev);
2778
2779 fd = GetAssociatedSystemFd(fd);
2780 epfd = GetAssociatedSystemFd(epfd);
2781 if ((fd < 0) || (epfd < 0)) {
2782 ret = -EBADF;
2783 goto OUT;
2784 }
2785
2786 ret = epoll_ctl(epfd, op, fd, ev);
2787 if (ret < 0) {
2788 ret = -EBADF;
2789 goto OUT;
2790 }
2791
2792 CPY_TO_USER(ev);
2793 OUT:
2794 return (ret == -1) ? -get_errno() : ret;
2795 }
2796
SysEpollWait(int epfd,struct epoll_event * evs,int maxevents,int timeout)2797 int SysEpollWait(int epfd, struct epoll_event *evs, int maxevents, int timeout)
2798 {
2799 int ret = 0;
2800
2801 if ((maxevents <= 0) || (maxevents > EPOLL_DEFAULT_SIZE)) {
2802 ret = -EINVAL;
2803 goto OUT;
2804 }
2805
2806 CHECK_ASPACE(evs, sizeof(struct epoll_event) * maxevents);
2807 DUP_FROM_USER_NOCOPY(evs, sizeof(struct epoll_event) * maxevents);
2808
2809 epfd = GetAssociatedSystemFd(epfd);
2810 if (epfd < 0) {
2811 ret = -EBADF;
2812 goto OUT;
2813 }
2814
2815 ret = epoll_wait(epfd, evs, maxevents, timeout);
2816 if (ret < 0) {
2817 ret = -get_errno();
2818 }
2819
2820 DUP_TO_USER(evs, sizeof(struct epoll_event) * ret);
2821 FREE_DUP(evs);
2822 OUT:
2823 return (ret == -1) ? -get_errno() : ret;
2824 }
2825
SysEpollPwait(int epfd,struct epoll_event * evs,int maxevents,int timeout,const sigset_t * mask)2826 int SysEpollPwait(int epfd, struct epoll_event *evs, int maxevents, int timeout, const sigset_t *mask)
2827 {
2828 sigset_t_l origMask;
2829 sigset_t_l setl;
2830 int ret = 0;
2831
2832 if ((maxevents <= 0) || (maxevents > EPOLL_DEFAULT_SIZE)) {
2833 ret = -EINVAL;
2834 goto OUT;
2835 }
2836
2837 CHECK_ASPACE(mask, sizeof(sigset_t));
2838
2839 if (mask != NULL) {
2840 ret = LOS_ArchCopyFromUser(&setl, mask, sizeof(sigset_t));
2841 if (ret != 0) {
2842 return -EFAULT;
2843 }
2844 }
2845
2846 CHECK_ASPACE(evs, sizeof(struct epoll_event) * maxevents);
2847 DUP_FROM_USER_NOCOPY(evs, sizeof(struct epoll_event) * maxevents);
2848
2849 epfd = GetAssociatedSystemFd(epfd);
2850 if (epfd < 0) {
2851 ret = -EBADF;
2852 goto OUT;
2853 }
2854
2855 OsSigprocMask(SIG_SETMASK, &setl, &origMask);
2856 ret = epoll_wait(epfd, evs, maxevents, timeout);
2857 if (ret < 0) {
2858 ret = -get_errno();
2859 }
2860
2861 OsSigprocMask(SIG_SETMASK, &origMask, NULL);
2862
2863 DUP_TO_USER(evs, sizeof(struct epoll_event) * ret);
2864 FREE_DUP(evs);
2865 OUT:
2866 return (ret == -1) ? -get_errno() : ret;
2867 }
2868
2869 #ifdef LOSCFG_CHROOT
SysChroot(const char * path)2870 int SysChroot(const char *path)
2871 {
2872 int ret;
2873 char *pathRet = NULL;
2874
2875 if (path != NULL) {
2876 ret = UserPathCopy(path, &pathRet);
2877 if (ret != 0) {
2878 goto OUT;
2879 }
2880 }
2881
2882 ret = chroot(path ? pathRet : NULL);
2883 if (ret < 0) {
2884 ret = -get_errno();
2885 }
2886 OUT:
2887 if (pathRet != NULL) {
2888 (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
2889 }
2890 return ret;
2891 }
2892 #endif
2893 #endif
2894