Module Name: src Committed By: kamil Date: Wed May 31 00:45:59 UTC 2017
Modified Files: src/sys/sys: event.h Log Message: Convert EV_SET from macro to static __inline function LLDB introduced support for kevent(2) and it contains the following function: Status MainLoop::RunImpl::Poll() { in_events.resize(loop.m_read_fds.size()); unsigned i = 0; for (auto &fd : loop.m_read_fds) EV_SET(&in_events[i++], fd.first, EVFILT_READ, EV_ADD, 0, 0, 0); num_events = kevent(loop.m_kqueue, in_events.data(), in_events.size(), out_events, llvm::array_lengthof(out_events), nullptr); if (num_events < 0) return Status("kevent() failed with error %d\n", num_events); return Status(); } It works on FreeBSD and MacOSX, however it broke on NetBSD. Culrpit line: EV_SET(&in_events[i++], fd.first, EVFILT_READ, EV_ADD, 0, 0, 0); FreeBSD defined EV_SET() as a macro this way: #define EV_SET(kevp_, a, b, c, d, e, f) do { \ struct kevent *kevp = (kevp_); \ (kevp)->ident = (a); \ (kevp)->filter = (b); \ (kevp)->flags = (c); \ (kevp)->fflags = (d); \ (kevp)->data = (e); \ (kevp)->udata = (f); \ } while(0) NetBSD version was different: #define EV_SET(kevp, a, b, c, d, e, f) \ do { \ (kevp)->ident = (a); \ (kevp)->filter = (b); \ (kevp)->flags = (c); \ (kevp)->fflags = (d); \ (kevp)->data = (e); \ (kevp)->udata = (f); \ } while (/* CONSTCOND */ 0) This resulted in heap damage, as keyp was incremented every time value was assigned to (keyp)->. As suggested by Joerg, convert this macro on NetBSD to static __inline function. Credit to <coypu> for asan+ubsan research wiki entry that helped to narrow down the bug. Credit to <joerg> for peer-review Sponsored by <The NetBSD Foundation> To generate a diff of this commit: cvs rdiff -u -r1.26 -r1.27 src/sys/sys/event.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/sys/event.h diff -u src/sys/sys/event.h:1.26 src/sys/sys/event.h:1.27 --- src/sys/sys/event.h:1.26 Sun Jan 31 04:40:01 2016 +++ src/sys/sys/event.h Wed May 31 00:45:59 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: event.h,v 1.26 2016/01/31 04:40:01 christos Exp $ */ +/* $NetBSD: event.h,v 1.27 2017/05/31 00:45:59 kamil Exp $ */ /*- * Copyright (c) 1999,2000,2001 Jonathan Lemon <jle...@freebsd.org> @@ -45,17 +45,6 @@ #define EVFILT_TIMER 6U /* arbitrary timer (in ms) */ #define EVFILT_SYSCOUNT 7U /* number of filters */ -#define EV_SET(kevp, a, b, c, d, e, f) \ -do { \ - (kevp)->ident = (a); \ - (kevp)->filter = (b); \ - (kevp)->flags = (c); \ - (kevp)->fflags = (d); \ - (kevp)->data = (e); \ - (kevp)->udata = (f); \ -} while (/* CONSTCOND */ 0) - - struct kevent { uintptr_t ident; /* identifier for this event */ uint32_t filter; /* filter for event */ @@ -65,6 +54,18 @@ struct kevent { intptr_t udata; /* opaque user data identifier */ }; +static __inline void +EV_SET(struct kevent *_kevp, uintptr_t _ident, uint32_t _filter, + uint32_t _flags, uint32_t _fflags, int64_t _data, intptr_t _udata) +{ + _kevp->ident = _ident; + _kevp->filter = _filter; + _kevp->flags = _flags; + _kevp->fflags = _fflags; + _kevp->data = _data; + _kevp->udata = _udata; +} + /* actions */ #define EV_ADD 0x0001U /* add event to kq (implies ENABLE) */ #define EV_DELETE 0x0002U /* delete event from kq */