int (*notify) ( resmgr_context_t *ctp, io_notify_t *msg, RESMGR_OCB_T *ocb )
struct _io_notify { uint16_t type; uint16_t combine_len; int32_t action; int32_t flags; struct __sigevent32 event; /* Following fields only valid if (flags & _NOTIFY_COND_EXTEN) */ int32_t mgr[2]; /* For use by manager */ int32_t flags_extra_mask; int32_t flags_exten; int32_t nfds; int32_t fd_first; int32_t nfds_ready; int64_t timo; /* struct pollfd fds[nfds]; */ }; struct _io_notify64 { uint16_t type; uint16_t combine_len; int32_t action; int32_t flags; struct __sigevent32 old_event; /* Following fields only valid if (flags & _NOTIFY_COND_EXTEN) */ int32_t mgr[2]; /* For use by manager */ int32_t flags_extra_mask; int32_t flags_exten; int32_t nfds; int32_t fd_first; int32_t nfds_ready; int64_t timo; union { struct __sigevent32 event32; struct __sigevent64 event64; }; /* struct pollfd fds[nfds]; */ }; struct _io_notify_reply { uint32_t zero; uint32_t flags; /* actions above */ int32_t flags2; /* flags above */ struct __sigevent32 event; /* Following fields only updated by new managers (if valid) */ int32_t mgr[2]; /* For use by manager */ int32_t flags_extra_mask; int32_t flags_exten; int32_t nfds; int32_t fd_first; int32_t nfds_ready; int64_t timo; /* struct pollfd fds[nfds]; */ }; struct _io_notify_reply64 { uint32_t zero; uint32_t flags; /* actions */ int32_t flags2; /* flags above */ struct __sigevent32 old_event; /* Following fields only updated by new managers (if valid) */ int32_t mgr[2]; /* For use by manager */ int32_t flags_extra_mask; int32_t flags_exten; int32_t nfds; int32_t fd_first; int32_t nfds_ready; int64_t timo; union { struct __sigevent32 event32; struct __sigevent64 event64; }; /* struct pollfd fds[nfds]; */ }; typedef union { struct _io_notify i; struct _io_notify64 i64; struct _io_notify_reply o; struct _io_notify_reply64 o64; } io_notify_t;
The iofunc_notify() helper function does not perform permission checking. However, if an OCB has not been opened for read, it should probably not be allowed to request notification of conditions occurring on that OCB that relate to reading data (e.g., the _NOTIFY_CONDE_RDNORM flag is set). Notifications that are not associated with reading or writing data (e.g., _NOTIFY_CONDE_HUP and _NOTIFY_CONDE_NVAL) do not need to be tied to read or write access. Although the information leakage is quite limited in this case, (e.g., learning when a file descriptor is ready for read or write or has out-of-band data available), it could potentially be used in various attacks such as race conditions. QNX recommends that you deny a notify() call to callers that have not opened the file descriptor for read or write. Thorough permission checking would apply an appropriate decision depending on the flags supplied to the notify() function.
For resource managers that deal with user input (e.g., a keyboard), be careful not to leak timing data through the delivery of notify messages. Attackers can use this timing data to build a profile of what the user is typing. Similarly, do not provide notification for process-specific characteristics such as CPU usage and changes in allocated memory.