From: Julian Seward Date: Thu, 23 May 2002 16:52:11 +0000 (+0000) Subject: sched_do_syscalls: properly handle invalid fd in read/write, rather X-Git-Tag: svn/VALGRIND_1_0_3~152 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f72f7e4d44db98658c502dccd9621f46435e9948;p=thirdparty%2Fvalgrind.git sched_do_syscalls: properly handle invalid fd in read/write, rather than dying with an assertion failure. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@314 --- diff --git a/coregrind/vg_scheduler.c b/coregrind/vg_scheduler.c index 5f023dae26..801502b916 100644 --- a/coregrind/vg_scheduler.c +++ b/coregrind/vg_scheduler.c @@ -601,6 +601,13 @@ Bool fd_is_blockful ( Int fd ) return (res & VKI_O_NONBLOCK) ? False : True; } +static +Bool fd_is_valid ( Int fd ) +{ + Int res = VG_(fcntl)( fd, VKI_F_GETFL, 0 ); + return VG_(is_kerror)(res) ? False : True; +} + /* Possibly do a for tid. Return values are: @@ -826,6 +833,22 @@ void sched_do_syscall ( ThreadId tid ) We later poll for I/O completion using select(). */ fd = VG_(threads)[tid].m_ebx /* arg1 */; + + /* Deal with error case immediately. */ + if (!fd_is_valid(fd)) { + VG_(message)(Vg_UserMsg, + "Warning: invalid file descriptor %d in syscall %s", + fd, syscall_no == __NR_read ? "read()" : "write()" ); + VG_(check_known_blocking_syscall)(tid, syscall_no, NULL /* PRE */); + KERNEL_DO_SYSCALL(tid, res); + VG_(check_known_blocking_syscall)(tid, syscall_no, &res /* POST */); + /* We're still runnable. */ + vg_assert(VG_(threads)[tid].status == VgTs_Runnable); + return; + } + + /* From here onwards we know that fd is valid. */ + orig_fd_blockness = fd_is_blockful(fd); set_fd_nonblocking(fd); vg_assert(!fd_is_blockful(fd)); diff --git a/vg_scheduler.c b/vg_scheduler.c index 5f023dae26..801502b916 100644 --- a/vg_scheduler.c +++ b/vg_scheduler.c @@ -601,6 +601,13 @@ Bool fd_is_blockful ( Int fd ) return (res & VKI_O_NONBLOCK) ? False : True; } +static +Bool fd_is_valid ( Int fd ) +{ + Int res = VG_(fcntl)( fd, VKI_F_GETFL, 0 ); + return VG_(is_kerror)(res) ? False : True; +} + /* Possibly do a for tid. Return values are: @@ -826,6 +833,22 @@ void sched_do_syscall ( ThreadId tid ) We later poll for I/O completion using select(). */ fd = VG_(threads)[tid].m_ebx /* arg1 */; + + /* Deal with error case immediately. */ + if (!fd_is_valid(fd)) { + VG_(message)(Vg_UserMsg, + "Warning: invalid file descriptor %d in syscall %s", + fd, syscall_no == __NR_read ? "read()" : "write()" ); + VG_(check_known_blocking_syscall)(tid, syscall_no, NULL /* PRE */); + KERNEL_DO_SYSCALL(tid, res); + VG_(check_known_blocking_syscall)(tid, syscall_no, &res /* POST */); + /* We're still runnable. */ + vg_assert(VG_(threads)[tid].status == VgTs_Runnable); + return; + } + + /* From here onwards we know that fd is valid. */ + orig_fd_blockness = fd_is_blockful(fd); set_fd_nonblocking(fd); vg_assert(!fd_is_blockful(fd));