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