From d36a5c227099f3f74da27a730350b012b6e99cdd Mon Sep 17 00:00:00 2001 From: Christian Schoenebeck Date: Sat, 8 Feb 2020 09:24:19 +0100 Subject: [PATCH] 9pfs: validate count sent by client with T_readdir A good 9p client sends T_readdir with "count" parameter that's sufficiently smaller than client's initially negotiated msize (maximum message size). We perform a check for that though to avoid the server to be interrupted with a "Failed to encode VirtFS reply type 41" transport error message by bad clients. This count value constraint uses msize - 11, because 11 is the header size of R_readdir. Signed-off-by: Christian Schoenebeck Reviewed-by: Greg Kurz Message-Id: <3990d3891e8ae2074709b56449e96ab4b4b93b7d.1579567020.git.qemu_oss@crudebyte.com> [groug: added comment ] Signed-off-by: Greg Kurz --- hw/9pfs/9p.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c index c63f549f39..9e046f7acb 100644 --- a/hw/9pfs/9p.c +++ b/hw/9pfs/9p.c @@ -2434,6 +2434,7 @@ static void coroutine_fn v9fs_readdir(void *opaque) int32_t count; uint32_t max_count; V9fsPDU *pdu = opaque; + V9fsState *s = pdu->s; retval = pdu_unmarshal(pdu, offset, "dqd", &fid, &initial_offset, &max_count); @@ -2442,6 +2443,14 @@ static void coroutine_fn v9fs_readdir(void *opaque) } trace_v9fs_readdir(pdu->tag, pdu->id, fid, initial_offset, max_count); + /* Enough space for a R_readdir header: size[4] Rreaddir tag[2] count[4] */ + if (max_count > s->msize - 11) { + max_count = s->msize - 11; + warn_report_once( + "9p: bad client: T_readdir with count > msize - 11" + ); + } + fidp = get_fid(pdu, fid); if (fidp == NULL) { retval = -EINVAL;