qemu-block
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v2] nbd/client: Use smarter assert


From: Eric Blake
Subject: Re: [PATCH v2] nbd/client: Use smarter assert
Date: Mon, 31 Oct 2022 08:46:25 -0500
User-agent: NeoMutt/20220429

On Mon, Oct 24, 2022 at 02:59:48PM +0300, Vladimir Sementsov-Ogievskiy wrote:
> On 10/17/22 22:12, Eric Blake wrote:
> > Assigning strlen() to a uint32_t and then asserting that it isn't too
> > large doesn't catch the case of an input string 4G in length.
> > Thankfully, the incoming strings can never be that large: if the
> > export name or query is reflecting a string the client got from the
> > server, we already guarantee that we dropped the NBD connection if the
> > server sent more than 32M in a single reply to our NBD_OPT_* request;
> > if the export name is coming from qemu, nbd_receive_negotiate()
> > asserted that strlen(info->name) <= NBD_MAX_STRING_SIZE; and
> > similarly, a query string via x->dirty_bitmap coming from the user was
> > bounds-checked in either qemu-nbd or by the limitations of QMP.
> > Still, it doesn't hurt to be more explicit in how we write our
> > assertions to not have to analyze whether inadvertent wraparound is
> > possible.
> > 
> > Fixes: 93676c88 ("nbd: Don't send oversize strings", v4.2.0)
> > Reported-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> > Signed-off-by: Eric Blake <eblake@redhat.com>
> > ---
> > 
> > v2: update subject line and commit message to reflect file being
> > touched; adjust a second nearby assertion with the same issue
> > 
> >   nbd/client.c | 4 ++--
> >   1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/nbd/client.c b/nbd/client.c
> > index 30d5383cb1..90a6b7b38b 100644
> > --- a/nbd/client.c
> > +++ b/nbd/client.c
> > @@ -658,11 +658,11 @@ static int nbd_send_meta_query(QIOChannel *ioc, 
> > uint32_t opt,
> >       char *p;
> > 
> >       data_len = sizeof(export_len) + export_len + sizeof(queries);
> > -    assert(export_len <= NBD_MAX_STRING_SIZE);
> > +    assert(strlen(export) <= NBD_MAX_STRING_SIZE);
> >       if (query) {
> >           query_len = strlen(query);
> >           data_len += sizeof(query_len) + query_len;
> > -        assert(query_len <= NBD_MAX_STRING_SIZE);
> > +        assert(strlen(query) <= NBD_MAX_STRING_SIZE);
> >       } else {
> >           assert(opt == NBD_OPT_LIST_META_CONTEXT);
> >       }
> 
> I'm a bit late, and this should work as is.
> 
> Still, for me it's a bit strange: you point to the fact that we probably 
> overflow uint32_t variable. But we keep this fact hidden in the code. So, 
> everyone who read should guess "aha, this extra strlen here is because the 
> previous one may overflow the variable)".
> 
> Could we use strnlen() instead of strlen()? That would be also more effective.

Good idea.  As in:

assert(strnlen(query, NBD_MAX_STRING_SIZE + 1) <= NBD_MAX_STRING_SIZE);

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org




reply via email to

[Prev in Thread] Current Thread [Next in Thread]