From 4beecafa496f2f8c8b8a06f3dafb0d65855ea625 Mon Sep 17 00:00:00 2001 From: ligd Date: Wed, 16 Mar 2022 22:48:54 +0800 Subject: [PATCH] epoll: fix epoll close error, report by kasan VELAPLATFO-1942 -#9 0xf7abf899 in __asan::__asan_report_load2 (addr=4072681776) at ../../../../../src/libsanitizer/asan/asan_rtl.cc:117 -#10 0x5693f718 in inode_release (node=0xf2c03124) at inode/fs_inoderelease.c:69 -#11 0x568ea61b in file_close (filep=0xf55fedd0) at vfs/fs_close.c:79 -#12 0x568e7e56 in nx_close (fd=3) at inode/fs_files.c:528 -#13 0x568e7f0e in close (fd=3) at inode/fs_files.c:562 -#14 0x56e76c39 in epoll_close (epfd=3) at vfs/fs_epoll.c:252 -#15 0x56c33829 in sensor_service_delete (ctrl=0x578b8540 ) at src/common.c:439 -#16 0x56a0561e in sensor_middle_service_main (argc=1, argv=0xf55de820) at sensor_main.c:118 -#17 0x56878675 in nxtask_startup (entrypt=0x56a054cc , argc=1, argv=0xf55de820) at sched/task_startup.c:70 -#18 0x5684427a in nxtask_start () at task/task_start.c:133 -#19 0xdeadbeef in ?? () reason: epoll_close -> close -> epoll_do_close (free inode) -> inode_release (reuse inode, crash) fix: use the global inode to match the fd which will return to user. like the g_sock_inode in fs/socket/socket.c Change-Id: I0096ac691ce9cf4169d1fb8bfa6d27a8c1ee7d52 Signed-off-by: ligd --- fs/vfs/fs_epoll.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/fs/vfs/fs_epoll.c b/fs/vfs/fs_epoll.c index c73731483a324..539fc38312af4 100644 --- a/fs/vfs/fs_epoll.c +++ b/fs/vfs/fs_epoll.c @@ -83,6 +83,16 @@ static const struct file_operations g_epoll_ops = #endif }; +static struct inode g_epoll_inode = +{ + .i_crefs = 1, + .i_flags = FSNODEFLAG_TYPE_DRIVER, + .u = + { + .i_ops = &g_epoll_ops, + }, +}; + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -109,12 +119,12 @@ static FAR struct epoll_head *epoll_head_from_fd(int fd) return NULL; } - return (FAR struct epoll_head *)filep->f_inode->i_private; + return (FAR struct epoll_head *)filep->f_priv; } static int epoll_do_open(FAR struct file *filep) { - FAR struct epoll_head *eph = filep->f_inode->i_private; + FAR struct epoll_head *eph = filep->f_priv; int ret; ret = nxsem_wait(&eph->sem); @@ -130,7 +140,7 @@ static int epoll_do_open(FAR struct file *filep) static int epoll_do_close(FAR struct file *filep) { - FAR struct epoll_head *eph = filep->f_inode->i_private; + FAR struct epoll_head *eph = filep->f_priv; int ret; ret = nxsem_wait(&eph->sem); @@ -187,7 +197,7 @@ static int epoll_do_create(int size, int flags) /* Alloc the file descriptor */ - fd = files_allocate(&eph->in, flags, 0, eph, 0); + fd = files_allocate(&g_epoll_inode, flags, 0, eph, 0); if (fd < 0) { nxsem_destroy(&eph->sem); @@ -196,6 +206,7 @@ static int epoll_do_create(int size, int flags) return -1; } + inode_addref(&g_epoll_inode); nxsem_post(&eph->sem); return fd; }