[PATCH 2/5] xfs: check healthmon outbuffer space correctly
"Darrick J. Wong" <[email protected]>
| Newsgroups | org.kernel.vger.stable,org.kernel.vger.linux-xfs |
|---|---|
| Message-ID | <178760941123.944364.14413050986149192404.stgit@frogsfrogsfrogs> |
From: Darrick J. Wong <[email protected]> LOLLM notices that the outbuf space check in xfs_healthmon_format_pop isn't quite correct -- it checks that there's enough space to write a xfs_healthmon_event object, but the outbuffer is supposed to contain xfs_health_monitor_event objects. Fix this by adding a helper, and refactoring all three outbuf size checks to use it. Cc: <[email protected]> # v7.0 Fixes: b3a289a2a9397b ("xfs: create event queuing, formatting, and discovery infrastructure") Signed-off-by: "Darrick J. Wong" <[email protected]> Assisted-by: LOLLM # finding obvious bugs --- fs/xfs/xfs_healthmon.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/fs/xfs/xfs_healthmon.c b/fs/xfs/xfs_healthmon.c index 166ef0d5864486..a2ae15a262a510 100644 --- a/fs/xfs/xfs_healthmon.c +++ b/fs/xfs/xfs_healthmon.c @@ -739,6 +739,12 @@ static const unsigned int type_map[] = { [XFS_HEALTHMON_DATALOST] = XFS_HEALTH_MONITOR_TYPE_DATALOST, }; +static inline bool +xfs_healthmon_check_outbuffer_space(const struct xfs_healthmon *hm) +{ + return hm->bufhead + sizeof(struct xfs_health_monitor_event) <= hm->bufsize; +} + /* Render event as a V0 structure */ STATIC int xfs_healthmon_format_v0( @@ -805,10 +811,10 @@ xfs_healthmon_format_v0( break; } - ASSERT(hm->bufhead + sizeof(hme) <= hm->bufsize); + ASSERT(xfs_healthmon_check_outbuffer_space(hm)); /* copy formatted object to the outbuf */ - if (hm->bufhead + sizeof(hme) <= hm->bufsize) { + if (xfs_healthmon_check_outbuffer_space(hm)) { memcpy(hm->buffer + hm->bufhead, &hme, sizeof(hme)); hm->bufhead += sizeof(hme); } @@ -891,7 +897,11 @@ xfs_healthmon_format_pop( { struct xfs_healthmon_event *event; - if (hm->bufhead + sizeof(*event) > hm->bufsize) + /* + * Don't bother if there's not enough space to format even one event in + * the outbuffer. + */ + if (!xfs_healthmon_check_outbuffer_space(hm)) return NULL; mutex_lock(&hm->lock);