From 27dca4d857ef8de6b4bb9302e0dd435be7e3284f Mon Sep 17 00:00:00 2001 From: Guangyao Ma Date: Thu, 3 Jun 2021 17:28:16 +0800 Subject: [PATCH] =?UTF-8?q?feat(vfs):=20vfs=E6=94=AF=E6=8C=81FD=5FCLOEXEC?= =?UTF-8?q?=E6=A0=87=E8=AE=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 首先,POSIX规范规定文件描述符需要支持close-on-exec属性,修改前的vfs不支持close-on-exec,当exec系列函数执行时,进程所有的文件将会被关闭(0,1,2也重新被打开)。但是,系统有些时候是不能在exec时关闭全部文件的,例如在执行exec之前,就需要重定向进程的某些文件描述符时(使用dup2),就希望该文件不被关闭,继续保持重定向属性,shell执行进程并重定向其标准输出到文件,这是我们经常做的事情。 BREAKING CHANGE: 执行exec类函数后,进程拥有的文件描述符情况发生变化:修改前,默认关闭所有的进程文件描述符,0,1,2重新打开;修改后,除非文件描述符拥有FD_CLOEXEC标记,否则该描述符不会被关闭。 re #I3U81W Change-Id: I54e841ac88e9835ec23e97de0cbc906c4e11f5a4 Signed-off-by: Guangyao Ma --- fs/include/fs/fd_table.h | 9 +- fs/include/fs/fs_operation.h | 22 ++++ fs/proc/os_adapt/fd_proc.c | 4 +- fs/vfs/BUILD.gn | 28 ++--- .../operation/{fs_chattr.c => vfs_chattr.c} | 0 fs/vfs/operation/{fs_check.c => vfs_check.c} | 0 fs/vfs/operation/vfs_cloexec.c | 97 ++++++++++++++++ .../{fs_fallocate.c => vfs_fallocate.c} | 0 .../{fs_fallocate64.c => vfs_fallocate64.c} | 0 fs/vfs/operation/vfs_fcntl.c | 104 ++++++++++++++++++ .../{fs_file_mapping.c => vfs_file_mapping.c} | 0 fs/vfs/operation/{fs_init.c => vfs_init.c} | 0 fs/vfs/operation/{fs_other.c => vfs_other.c} | 0 .../operation/{fs_preadv.c => vfs_preadv.c} | 0 fs/vfs/operation/{fs_file.c => vfs_procfd.c} | 8 +- .../operation/{fs_pwritev.c => vfs_pwritev.c} | 0 fs/vfs/operation/{fs_readv.c => vfs_readv.c} | 0 fs/vfs/operation/{fs_utime.c => vfs_utime.c} | 0 .../operation/{fs_writev.c => vfs_writev.c} | 0 fs/vfs/vnode.c | 1 - kernel/base/core/los_process.c | 7 +- kernel/extended/dynload/src/los_exec_elf.c | 1 - kernel/extended/dynload/src/los_load_elf.c | 7 +- syscall/fs_syscall.c | 77 +++++-------- 24 files changed, 292 insertions(+), 73 deletions(-) rename fs/vfs/operation/{fs_chattr.c => vfs_chattr.c} (100%) rename fs/vfs/operation/{fs_check.c => vfs_check.c} (100%) create mode 100644 fs/vfs/operation/vfs_cloexec.c rename fs/vfs/operation/{fs_fallocate.c => vfs_fallocate.c} (100%) rename fs/vfs/operation/{fs_fallocate64.c => vfs_fallocate64.c} (100%) create mode 100644 fs/vfs/operation/vfs_fcntl.c rename fs/vfs/operation/{fs_file_mapping.c => vfs_file_mapping.c} (100%) rename fs/vfs/operation/{fs_init.c => vfs_init.c} (100%) rename fs/vfs/operation/{fs_other.c => vfs_other.c} (100%) rename fs/vfs/operation/{fs_preadv.c => vfs_preadv.c} (100%) rename fs/vfs/operation/{fs_file.c => vfs_procfd.c} (98%) rename fs/vfs/operation/{fs_pwritev.c => vfs_pwritev.c} (100%) rename fs/vfs/operation/{fs_readv.c => vfs_readv.c} (100%) rename fs/vfs/operation/{fs_utime.c => vfs_utime.c} (100%) rename fs/vfs/operation/{fs_writev.c => vfs_writev.c} (100%) diff --git a/fs/include/fs/fd_table.h b/fs/include/fs/fd_table.h index 6d8a7eac..2f2db323 100644 --- a/fs/include/fs/fd_table.h +++ b/fs/include/fs/fd_table.h @@ -46,6 +46,7 @@ struct fd_table_s { unsigned int max_fds; struct file_table_s *ft_fds; /* process fd array associate with system fd */ fd_set *proc_fds; + fd_set *cloexec_fds; sem_t ft_sem; /* manage access to the file table */ }; @@ -70,7 +71,7 @@ struct files_struct *dup_fd(struct files_struct *oldf); struct files_struct *alloc_files(void); -void delete_files(LosProcessCB *processCB, struct files_struct *files); +void delete_files(struct files_struct *files); struct files_struct *create_files_snapshot(const struct files_struct *oldf); @@ -79,4 +80,10 @@ void delete_files_snapshot(struct files_struct *files); int alloc_fd(int minfd); void alloc_std_fd(struct fd_table_s *fdt); + +void FileTableLock(struct fd_table_s *fdt); + +void FileTableUnLock(struct fd_table_s *fdt); + +struct fd_table_s *GetFdTable(void); #endif diff --git a/fs/include/fs/fs_operation.h b/fs/include/fs/fs_operation.h index fec8cfa6..2b99cb0b 100644 --- a/fs/include/fs/fs_operation.h +++ b/fs/include/fs/fs_operation.h @@ -33,6 +33,7 @@ #define FS_OPERATION_H #include "fs/file.h" +#include "fs/fd_table.h" #ifdef __cplusplus #if __cplusplus @@ -137,6 +138,11 @@ extern int update_file_path(const char *old_path, const char *new_path); void los_vfs_init(void); +void CloseOnExec(struct files_struct *files); +void SetCloexecFlag(int procFd); +bool CheckCloexecFlag(int procFd); +void ClearCloexecFlag(int procFd); + void clear_fd(int fd); /** @@ -304,7 +310,23 @@ extern int los_set_systime_status(BOOL b_status); struct IATTR; extern int chattr(const char *pathname, struct IATTR *attr); +#define CONTINE_NUTTX_FCNTL 0XFF0F +/** + * @ingroup fs + * + * @par Description: + * The VfsFcntl function shall manipulate file descriptor. + * + * @retval #0 On success. + * @retval #-1 On failure with errno set. + * @retval CONTINE_NUTTX_FCNTL doesn't support some cmds in VfsFcntl, needs to continue going through Nuttx vfs operation. + * + * @par Dependency: + * + * @see None + */ +extern int VfsFcntl(int fd, int cmd, ...); /** * @ingroup fs * diff --git a/fs/proc/os_adapt/fd_proc.c b/fs/proc/os_adapt/fd_proc.c index 5914a324..b0ff2ba4 100644 --- a/fs/proc/os_adapt/fd_proc.c +++ b/fs/proc/os_adapt/fd_proc.c @@ -75,7 +75,7 @@ static void FillFdInfo(struct SeqBuf *seqBuf, struct filelist *fileList, unsigne } if (hasPrivilege) { - (void)LosBufPrintf(seqBuf, "%u\t%d\t%d\t%s\n", pid, fd, sysFd, name); + (void)LosBufPrintf(seqBuf, "%u\t%d\t%6d <%d>\t%s\n", pid, fd, sysFd, filp->f_refcount, name); } else { (void)LosBufPrintf(seqBuf, "%u\t%d\t%s\n", pid, fd, name); } @@ -101,7 +101,7 @@ static int FdProcFill(struct SeqBuf *seqBuf, void *v) } pidNum = LOS_GetUsedPIDList(pidList, pidMaxNum); hasPrivilege = true; - (void)LosBufPrintf(seqBuf, "Pid\tFd\tSysFd\tName\n"); + (void)LosBufPrintf(seqBuf, "%s\t%s\t%6s %s\t%s\n", "Pid", "Fd", "SysFd", "", "Name"); } else { pidNum = 1; pidList = (unsigned int *)malloc(pidNum * sizeof(unsigned int)); diff --git a/fs/vfs/BUILD.gn b/fs/vfs/BUILD.gn index 1cd4859e..441b907a 100644 --- a/fs/vfs/BUILD.gn +++ b/fs/vfs/BUILD.gn @@ -33,20 +33,22 @@ module_switch = defined(LOSCFG_FS_VFS) module_name = get_path_info(rebase_path("."), "name") kernel_module(module_name) { sources = [ - "operation/fs_chattr.c", - "operation/fs_check.c", - "operation/fs_fallocate.c", - "operation/fs_fallocate64.c", - "operation/fs_file.c", - "operation/fs_file_mapping.c", - "operation/fs_init.c", - "operation/fs_other.c", - "operation/fs_preadv.c", - "operation/fs_pwritev.c", - "operation/fs_readv.c", - "operation/fs_utime.c", - "operation/fs_writev.c", "operation/fullpath.c", + "operation/vfs_chattr.c", + "operation/vfs_check.c", + "operation/vfs_cloexec.c", + "operation/vfs_fallocate.c", + "operation/vfs_fallocate64.c", + "operation/vfs_fcntl.c", + "operation/vfs_file_mapping.c", + "operation/vfs_init.c", + "operation/vfs_other.c", + "operation/vfs_preadv.c", + "operation/vfs_procfd.c", + "operation/vfs_pwritev.c", + "operation/vfs_readv.c", + "operation/vfs_utime.c", + "operation/vfs_writev.c", "vfs_cmd/vfs_shellcmd.c", ] diff --git a/fs/vfs/operation/fs_chattr.c b/fs/vfs/operation/vfs_chattr.c similarity index 100% rename from fs/vfs/operation/fs_chattr.c rename to fs/vfs/operation/vfs_chattr.c diff --git a/fs/vfs/operation/fs_check.c b/fs/vfs/operation/vfs_check.c similarity index 100% rename from fs/vfs/operation/fs_check.c rename to fs/vfs/operation/vfs_check.c diff --git a/fs/vfs/operation/vfs_cloexec.c b/fs/vfs/operation/vfs_cloexec.c new file mode 100644 index 00000000..0943aa7a --- /dev/null +++ b/fs/vfs/operation/vfs_cloexec.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include "fs/file.h" +#include "fs/fs_operation.h" +#include "fs/fd_table.h" +#include "unistd.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +void CloseOnExec(struct files_struct *files) +{ + int sysFd; + if ((files == NULL) || (files->fdt == NULL)) { + return; + } + + for (int i = 0; i < files->fdt->max_fds; i++) { + if (FD_ISSET(i, files->fdt->proc_fds) && + FD_ISSET(i, files->fdt->cloexec_fds)) { + sysFd = DisassociateProcessFd(i); + close(sysFd); + FreeProcessFd(i); + } + } +} + +void SetCloexecFlag(int procFd) +{ + struct fd_table_s *fdt = GetFdTable(); + if (fdt == NULL) { + return; + } + + FileTableLock(fdt); + FD_SET(procFd, fdt->cloexec_fds); + FileTableUnLock(fdt); + return; +} + +bool CheckCloexecFlag(int procFd) +{ + bool isCloexec = 0; + struct fd_table_s *fdt = GetFdTable(); + if (fdt == NULL) { + return false; + } + + FileTableLock(fdt); + isCloexec = FD_ISSET(procFd, fdt->cloexec_fds); + FileTableUnLock(fdt); + return isCloexec; +} + +void ClearCloexecFlag(int procFd) +{ + struct fd_table_s *fdt = GetFdTable(); + if (fdt == NULL) { + return; + } + + FileTableLock(fdt); + FD_CLR(procFd, fdt->cloexec_fds); + FileTableUnLock(fdt); + return; +} diff --git a/fs/vfs/operation/fs_fallocate.c b/fs/vfs/operation/vfs_fallocate.c similarity index 100% rename from fs/vfs/operation/fs_fallocate.c rename to fs/vfs/operation/vfs_fallocate.c diff --git a/fs/vfs/operation/fs_fallocate64.c b/fs/vfs/operation/vfs_fallocate64.c similarity index 100% rename from fs/vfs/operation/fs_fallocate64.c rename to fs/vfs/operation/vfs_fallocate64.c diff --git a/fs/vfs/operation/vfs_fcntl.c b/fs/vfs/operation/vfs_fcntl.c new file mode 100644 index 00000000..11ec6b7a --- /dev/null +++ b/fs/vfs/operation/vfs_fcntl.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include "fs/file.h" +#include "fs/fd_table.h" +#include "fs/fs_operation.h" +#include "sys/types.h" +#include "sys/uio.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +static int FcntlDupFd(int procfd, int leastFd) +{ + int sysfd = GetAssociatedSystemFd(procfd); + if ((sysfd < 0) || (sysfd >= CONFIG_NFILE_DESCRIPTORS)) { + return -EBADF; + } + + if (CheckProcessFd(leastFd) != OK) { + return -EINVAL; + } + + int dupFd = AllocLowestProcessFd(leastFd); + if (dupFd < 0) { + return -EMFILE; + } + + files_refer(sysfd); + AssociateSystemFd(dupFd, sysfd); + + return dupFd; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +int VfsFcntl(int procfd, int cmd, ...) +{ + va_list ap; + int ret = 0; + + va_start(ap, cmd); + switch (cmd) { + case F_DUPFD: + { + int arg = va_arg(ap, int); + ret = FcntlDupFd(procfd, arg); + } + break; + case F_GETFD: + { + bool isCloexec = CheckCloexecFlag(procfd); + ret = isCloexec ? FD_CLOEXEC : 0; + } + break; + case F_SETFD: + { + int oflags = va_arg(ap, int); + if (oflags & FD_CLOEXEC) { + SetCloexecFlag(procfd); + } else { + ClearCloexecFlag(procfd); + } + } + break; + default: + ret = CONTINE_NUTTX_FCNTL; + break; + } + + va_end(ap); + return ret; +} diff --git a/fs/vfs/operation/fs_file_mapping.c b/fs/vfs/operation/vfs_file_mapping.c similarity index 100% rename from fs/vfs/operation/fs_file_mapping.c rename to fs/vfs/operation/vfs_file_mapping.c diff --git a/fs/vfs/operation/fs_init.c b/fs/vfs/operation/vfs_init.c similarity index 100% rename from fs/vfs/operation/fs_init.c rename to fs/vfs/operation/vfs_init.c diff --git a/fs/vfs/operation/fs_other.c b/fs/vfs/operation/vfs_other.c similarity index 100% rename from fs/vfs/operation/fs_other.c rename to fs/vfs/operation/vfs_other.c diff --git a/fs/vfs/operation/fs_preadv.c b/fs/vfs/operation/vfs_preadv.c similarity index 100% rename from fs/vfs/operation/fs_preadv.c rename to fs/vfs/operation/vfs_preadv.c diff --git a/fs/vfs/operation/fs_file.c b/fs/vfs/operation/vfs_procfd.c similarity index 98% rename from fs/vfs/operation/fs_file.c rename to fs/vfs/operation/vfs_procfd.c index 1e600bbb..a8d4c3ed 100644 --- a/fs/vfs/operation/fs_file.c +++ b/fs/vfs/operation/vfs_procfd.c @@ -37,7 +37,7 @@ #include "lwip/sockets.h" #endif -static void FileTableLock(struct fd_table_s *fdt) +void FileTableLock(struct fd_table_s *fdt) { /* Take the semaphore (perhaps waiting) */ while (sem_wait(&fdt->ft_sem) != 0) { @@ -49,7 +49,7 @@ static void FileTableLock(struct fd_table_s *fdt) } } -static void FileTableUnLock(struct fd_table_s *fdt) +void FileTableUnLock(struct fd_table_s *fdt) { int ret = sem_post(&fdt->ft_sem); if (ret == -1) { @@ -78,7 +78,7 @@ static int AssignProcessFd(const struct fd_table_s *fdt, int minFd) return VFS_ERROR; } -static struct fd_table_s *GetFdTable(void) +struct fd_table_s *GetFdTable(void) { struct fd_table_s *fdt = NULL; struct files_struct *procFiles = OsCurrProcessGet()->files; @@ -197,6 +197,7 @@ void FreeProcessFd(int procFd) FileTableLock(fdt); FD_CLR(procFd, fdt->proc_fds); + FD_CLR(procFd, fdt->cloexec_fds); fdt->ft_fds[procFd].sysFd = -1; FileTableUnLock(fdt); } @@ -467,6 +468,7 @@ int CloseProcFd(int procFd, unsigned int targetPid) /* clean the fd set */ FD_CLR(procFd, fdt->proc_fds); + FD_CLR(procFd, fdt->cloexec_fds); fdt->ft_fds[procFd].sysFd = -1; if (sem_post(&semId) == -1) { PRINTK("sem_post error, errno %d \n", get_errno()); diff --git a/fs/vfs/operation/fs_pwritev.c b/fs/vfs/operation/vfs_pwritev.c similarity index 100% rename from fs/vfs/operation/fs_pwritev.c rename to fs/vfs/operation/vfs_pwritev.c diff --git a/fs/vfs/operation/fs_readv.c b/fs/vfs/operation/vfs_readv.c similarity index 100% rename from fs/vfs/operation/fs_readv.c rename to fs/vfs/operation/vfs_readv.c diff --git a/fs/vfs/operation/fs_utime.c b/fs/vfs/operation/vfs_utime.c similarity index 100% rename from fs/vfs/operation/fs_utime.c rename to fs/vfs/operation/vfs_utime.c diff --git a/fs/vfs/operation/fs_writev.c b/fs/vfs/operation/vfs_writev.c similarity index 100% rename from fs/vfs/operation/fs_writev.c rename to fs/vfs/operation/vfs_writev.c diff --git a/fs/vfs/vnode.c b/fs/vfs/vnode.c index 3adc7245..ae00e893 100644 --- a/fs/vfs/vnode.c +++ b/fs/vfs/vnode.c @@ -367,7 +367,6 @@ int VnodeLookup(const char *path, struct Vnode **result, uint32_t flags) int ret = PreProcess(path, &startVnode, &normalizedPath); if (ret != LOS_OK) { - PRINT_ERR("[VFS]lookup failed, invalid path=%s err = %d\n", path, ret); goto OUT_FREE_PATH; } diff --git a/kernel/base/core/los_process.c b/kernel/base/core/los_process.c index a4bf395c..4664ac07 100644 --- a/kernel/base/core/los_process.c +++ b/kernel/base/core/los_process.c @@ -39,6 +39,7 @@ #include "asm/page.h" #ifdef LOSCFG_FS_VFS #include "fs/fd_table.h" +#include "fs/fs_operation.h" #endif #include "time.h" #include "user_copy.h" @@ -290,7 +291,7 @@ LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB) #ifdef LOSCFG_FS_VFS if (OsProcessIsUserMode(processCB)) { - delete_files(processCB, processCB->files); + delete_files(processCB->files); } processCB->files = NULL; #endif @@ -1306,8 +1307,8 @@ LITE_OS_SEC_TEXT UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR LOS_VmSpaceFree(oldSpace); #ifdef LOSCFG_FS_VFS - delete_files(OsCurrProcessGet(), (struct files_struct *)oldFiles); - alloc_std_fd(OsCurrProcessGet()->files->fdt); + CloseOnExec((struct files_struct *)oldFiles); + delete_files_snapshot((struct files_struct *)oldFiles); #endif OsSwtmrRecycle(processCB->processID); diff --git a/kernel/extended/dynload/src/los_exec_elf.c b/kernel/extended/dynload/src/los_exec_elf.c index 44b34395..8a776fc6 100644 --- a/kernel/extended/dynload/src/los_exec_elf.c +++ b/kernel/extended/dynload/src/los_exec_elf.c @@ -82,7 +82,6 @@ STATIC INT32 OsGetRealPath(const CHAR *fileName, CHAR *buf, UINT32 maxLen) return LOS_OK; ERR_FILE: - PRINT_ERR("No such file or directory: %s\n", fileName); return -ENOENT; } #endif diff --git a/kernel/extended/dynload/src/los_load_elf.c b/kernel/extended/dynload/src/los_load_elf.c index a6133eb4..ee287ce7 100644 --- a/kernel/extended/dynload/src/los_load_elf.c +++ b/kernel/extended/dynload/src/los_load_elf.c @@ -33,6 +33,7 @@ #include "fcntl.h" #include "fs/fd_table.h" #include "fs/file.h" +#include "fs/fs_operation.h" #include "los_config.h" #include "los_vm_map.h" #include "los_vm_syscall.h" @@ -55,6 +56,10 @@ static int OsELFOpen(const CHAR *fileName, INT32 oflags) return -EMFILE; } + if (oflags & O_CLOEXEC) { + SetCloexecFlag(procFd); + } + ret = open(fileName, oflags); if (ret < 0) { FreeProcessFd(procFd); @@ -185,7 +190,7 @@ STATIC INT32 OsReadEhdr(const CHAR *fileName, ELFInfo *elfInfo, BOOL isExecFile) return -ENOENT; } - ret = OsELFOpen(fileName, O_RDONLY | O_EXECVE); + ret = OsELFOpen(fileName, O_RDONLY | O_EXECVE | O_CLOEXEC); if (ret < 0) { PRINT_ERR("%s[%d], Failed to open ELF file: %s!\n", __FUNCTION__, __LINE__, fileName); return ret; diff --git a/syscall/fs_syscall.c b/syscall/fs_syscall.c index 676402a5..7f7c2471 100644 --- a/syscall/fs_syscall.c +++ b/syscall/fs_syscall.c @@ -52,7 +52,6 @@ #include "los_vm_map.h" #include "los_memory.h" #include "los_strncpy_from_user.h" -#include "fs/file.h" #include "capability_type.h" #include "capability_api.h" #include "sys/statfs.h" @@ -229,29 +228,6 @@ static int UserPoll(struct pollfd *fds, nfds_t nfds, int timeout) return ret; } -static int FcntlDupFd(int sysfd, void *arg) -{ - int leastFd = (intptr_t)arg; - - if ((sysfd < 0) || (sysfd >= CONFIG_NFILE_DESCRIPTORS)) { - return -EBADF; - } - - if (CheckProcessFd(leastFd) != OK) { - return -EINVAL; - } - - int procFd = AllocLowestProcessFd(leastFd); - if (procFd < 0) { - return -EMFILE; - } - - files_refer(sysfd); - AssociateSystemFd(procFd, sysfd); - - return procFd; -} - int SysClose(int fd) { int ret; @@ -303,9 +279,8 @@ ssize_t SysWrite(int fd, const void *buf, size_t nbytes) } /* Process fd convert to system global fd */ - fd = GetAssociatedSystemFd(fd); - - ret = write(fd, buf, nbytes); + int sysfd = GetAssociatedSystemFd(fd); + ret = write(sysfd, buf, nbytes); if (ret < 0) { return -get_errno(); } @@ -322,7 +297,7 @@ int SysOpen(const char *path, int oflags, ...) if (path != NULL) { ret = UserPathCopy(path, &pathRet); if (ret != 0) { - goto ERROUT_PATH_FREE; + return ret; } } @@ -332,6 +307,10 @@ int SysOpen(const char *path, int oflags, ...) goto ERROUT; } + if (oflags & O_CLOEXEC) { + SetCloexecFlag(procFd); + } + if ((unsigned int)oflags & O_DIRECTORY) { ret = do_opendir(pathRet, oflags); } else { @@ -357,17 +336,12 @@ int SysOpen(const char *path, int oflags, ...) return procFd; ERROUT: - if (ret >= 0) { - AssociateSystemFd(procFd, ret); - ret = procFd; - } else { + if (pathRet != NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + if (procFd >= 0) { FreeProcessFd(procFd); } -ERROUT_PATH_FREE: - if (pathRet != NULL) { - LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); - } - return ret; } @@ -922,13 +896,13 @@ int SysIoctl(int fd, int req, void *arg) int SysFcntl(int fd, int cmd, void *arg) { /* Process fd convert to system global fd */ - fd = GetAssociatedSystemFd(fd); + int sysfd = GetAssociatedSystemFd(fd); - if (cmd == F_DUPFD) { - return FcntlDupFd(fd, arg); + int ret = VfsFcntl(fd, cmd, arg); + if (ret == CONTINE_NUTTX_FCNTL) { + ret = fcntl(sysfd, cmd, arg); } - int ret = fcntl(fd, cmd, arg); if (ret < 0) { return -get_errno(); } @@ -1010,6 +984,9 @@ int SysDup2(int fd1, int fd2) files_refer(sysfd1); AssociateSystemFd(fd2, sysfd1); + + /* if fd1 is not equal to fd2, the FD_CLOEXEC flag associated with fd2 shall be cleared */ + ClearCloexecFlag(fd2); return fd2; } @@ -1421,9 +1398,9 @@ ssize_t SysWritev(int fd, const struct iovec *iov, int iovcnt) struct iovec *iovRet = NULL; /* Process fd convert to system global fd */ - fd = GetAssociatedSystemFd(fd); + int sysfd = GetAssociatedSystemFd(fd); if ((iov == NULL) || (iovcnt <= 0) || (iovcnt > IOV_MAX)) { - ret = writev(fd, iov, iovcnt); + ret = writev(sysfd, iov, iovcnt); return -get_errno(); } @@ -1437,7 +1414,7 @@ ssize_t SysWritev(int fd, const struct iovec *iov, int iovcnt) goto OUT_FREE; } - ret = writev(fd, iovRet, valid_iovcnt); + ret = writev(sysfd, iovRet, valid_iovcnt); if (ret < 0) { ret = -get_errno(); } @@ -1700,6 +1677,10 @@ int SysOpenat(int dirfd, const char *path, int oflags, ...) goto ERROUT; } + if (oflags & O_CLOEXEC) { + SetCloexecFlag(procFd); + } + if (dirfd != AT_FDCWD) { /* Process fd convert to system global fd */ dirfd = GetAssociatedSystemFd(dirfd); @@ -2094,13 +2075,13 @@ int SysFstat64(int fd, struct stat64 *buf) int SysFcntl64(int fd, int cmd, void *arg) { /* Process fd convert to system global fd */ - fd = GetAssociatedSystemFd(fd); + int sysfd = GetAssociatedSystemFd(fd); - if (cmd == F_DUPFD) { - return FcntlDupFd(fd, arg); + int ret = VfsFcntl(fd, cmd, arg); + if (ret == CONTINE_NUTTX_FCNTL) { + ret = fcntl64(sysfd, cmd, arg); } - int ret = fcntl64(fd, cmd, arg); if (ret < 0) { return -get_errno(); }