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

Jonathon Jongsma jjongsma at redhat.com
Fri May 11 13:47:08 UTC 2018


Acked-by: Jonathon Jongsma <jjongsma at redhat.com>

On Fri, 2018-05-11 at 08:39 +0100, 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 | 86
> +++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 100 insertions(+)
>  create mode 100644 tests/test-overflow.c
> 
> Changes since last version:
> - extend a comment;
> - use SPICE_CHANNEL_MAIN mnemonic instead of 1.
> 
> 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..0a5bdd2
> --- /dev/null
> +++ b/tests/test-overflow.c
> @@ -0,0 +1,86 @@
> +/*
> +   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 <spice/enums.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: 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
> +    *((uint32_t *) data) = 0x80000002u;
> +
> +    // extract the message
> +    func = spice_get_server_channel_parser(SPICE_CHANNEL_MAIN,
> &max_message_type);
> +    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;
> +}
> +


More information about the Spice-devel mailing list