[Spice-devel] [PATCH spice-common 2/3] Write a small test to test possible crash

Frediano Ziglio fziglio at redhat.com
Fri May 11 07:40:32 UTC 2018


> > 
> > On Mon, 2018-03-19 at 10:06 +0000, Frediano Ziglio wrote:
> > > This small test prove a that current generated demarshaller code
> > > is not safe to integer overflows leading to buffer overflows.
> > > Actually from a quick look at the protocol it seems that client
> > > can't cause these overflows but server can quite easily at
> > > demonstrated by this test.
> > > 
> > > Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
> > > ---
> > >  tests/Makefile.am     | 14 +++++++++
> > >  tests/test-overflow.c | 83
> > > +++++++++++++++++++++++++++++++++++++++++++++++++++
> > >  2 files changed, 97 insertions(+)
> > >  create mode 100644 tests/test-overflow.c
> > > 
> > > diff --git a/tests/Makefile.am b/tests/Makefile.am
> > > index 5abf239..d5ec1d7 100644
> > > --- a/tests/Makefile.am
> > > +++ b/tests/Makefile.am
> > > @@ -67,4 +67,18 @@ EXTRA_DIST =				\
> > >  	test-marshallers.proto		\
> > >  	$(NULL)
> > >  
> > > +TESTS += test_overflow
> > > +test_overflow_SOURCES = test-overflow.c
> > > +test_overflow_CFLAGS = \
> > > +	-I$(top_srcdir) \
> > > +	$(GLIB2_CFLAGS) \
> > > +	$(SPICE_COMMON_CFLAGS) \
> > > +	$(PROTOCOL_CFLAGS) \
> > > +	$(NULL)
> > > +test_overflow_LDADD = \
> > > +	$(top_builddir)/common/libspice-common.la \
> > > +	$(top_builddir)/common/libspice-common-server.la \
> > > +	$(top_builddir)/common/libspice-common-client.la \
> > > +	$(NULL)
> > > +
> > >  -include $(top_srcdir)/git.mk
> > > diff --git a/tests/test-overflow.c b/tests/test-overflow.c
> > > new file mode 100644
> > > index 0000000..0364df7
> > > --- /dev/null
> > > +++ b/tests/test-overflow.c
> > > @@ -0,0 +1,83 @@
> > > +/*
> > > +   Copyright (C) 2015 Red Hat, Inc.
> > > +
> > > +   This library is free software; you can redistribute it and/or
> > > +   modify it under the terms of the GNU Lesser General Public
> > > +   License as published by the Free Software Foundation; either
> > > +   version 2.1 of the License, or (at your option) any later
> > > version.
> > > +
> > > +   This library is distributed in the hope that it will be useful,
> > > +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> > > +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> > > +   Lesser General Public License for more details.
> > > +
> > > +   You should have received a copy of the GNU Lesser General Public
> > > +   License along with this library; if not, see <http://www.gnu.org/
> > > licenses/>.
> > > +*/
> > > +#ifdef HAVE_CONFIG_H
> > > +#include <config.h>
> > > +#endif
> > > +
> > > +#include <stdio.h>
> > > +#include <stdlib.h>
> > > +#include <string.h>
> > > +#include <assert.h>
> > > +
> > > +#include <common/marshaller.h>
> > > +#include <common/generated_server_marshallers.h>
> > > +#include <common/client_demarshallers.h>
> > > +
> > > +#define NUM_CHANNELS 3u
> > > +
> > > +int main(void)
> > > +{
> > > +    SpiceMarshaller *m;
> > > +    SpiceMsgChannels *msg;
> > > +    uint8_t *data, *out;
> > > +    size_t len;
> > > +    int to_free = 0;
> > > +    spice_parse_channel_func_t func;
> > > +    unsigned int max_message_type, n;
> > > +    message_destructor_t free_output;
> > > +
> > > +    m = spice_marshaller_new();
> > > +    assert(m);
> > > +
> > > +    msg = (SpiceMsgChannels *) malloc(sizeof(SpiceMsgChannels) +
> > > +          NUM_CHANNELS * sizeof(SpiceChannelId));
> > > +    assert(msg);
> > > +
> > > +    // build a message and marshal it
> > > +    msg->num_of_channels = NUM_CHANNELS;
> > > +    for (n = 0; n < NUM_CHANNELS; ++n) {
> > > +        msg->channels[n] = (SpiceChannelId) { n + 1, n * 7 };
> > > +    }
> > > +    spice_marshall_msg_main_channels_list(m, msg);
> > > +
> > > +    // get linear data
> > > +    data = spice_marshaller_linearize(m, 0, &len, &to_free);
> > > +    assert(data);
> > > +
> > > +    printf("output len %lu\n", (unsigned long) len);
> > > +
> > > +    // hack, try to core
> > > +    *((uint32_t *) data) = 0x80000002u;
> > 
> > I think this requires more explanation. something like
> > 
> > // hack: setting the number of channels in the marshalled message to a
> > value that will cause overflow while parsing the message to make sure
> > that the parser can handle this situation
> > 
> 
> Sounds perfect.
> 
> > Or something similar? (assuming my understanding of what you're doing
> > here is correct?)
> > 
> > > +
> > > +    // extract the message
> > > +    func = spice_get_server_channel_parser(1, &max_message_type);
> > 
> > 1? maybe use SPICE_CHANNEL_MAIN instead?
> > 
> 
> This is a specific test protocol, is in tests/test-marshallers.proto,
> I don't generate the enumerations so I don't have the mnemonic constant.
> 
> I could use a "#define SPICE_CHANNEL_MAIN 1" at the beginning of the C file.
> 

Ignore, done, was confused by the other test.

> > > +    assert(func);
> > > +    out = func(data, data+len, SPICE_MSG_MAIN_CHANNELS_LIST, 0,
> > > &len, &free_output);
> > > +    assert(out == NULL);
> > > +
> > > +    // cleanup
> > > +    if (to_free) {
> > > +        free(data);
> > > +    }
> > > +    if (out) {
> > > +        free_output(out);
> > > +    }
> > > +    free(msg);
> > > +
> > > +    return 0;
> > > +}
> > > +
> > 
> 

Frediano


More information about the Spice-devel mailing list