Re: [PATCH libcacard v2 26/35] tests: Make sure we do not crash on bad data to sign

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

 



Hey,

On Tue, Aug 21, 2018 at 06:52:28PM +0200, Jakub Jelen wrote:
> On Tue, 2018-08-21 at 17:35 +0200, Christophe Fergeau wrote:
> > Hey,
> > 
> > On Thu, Aug 02, 2018 at 11:43:58AM +0200, Jakub Jelen wrote:
> > > diff --git a/tests/hwtests.c b/tests/hwtests.c
> > > index 7beebac..bd8e439 100644
> > > --- a/tests/hwtests.c
> > > +++ b/tests/hwtests.c
> > > @@ -268,6 +268,85 @@ static void test_get_response_hw(void) {
> > >      test_get_response();
> > >  }
> > >  
> > > +/* Try to pass bad formatted PKCS#1.5 data and make sure the
> > > libcacard does not
> > > + * crash while handling them
> > > + */
> > > +static void test_sign_bad_data_x509(void)
> > > +{
> > > +    VReader *reader = vreader_get_reader_by_id(0);
> > > +    VReaderStatus status;
> > > +    int dwRecvLength = APDUBufSize;
> > > +    uint8_t pbRecvBuffer[APDUBufSize];
> > > +    uint8_t sign[] = {
> > > +        /* VERIFY   [p1,p2=0 ]  [Lc            ] [2048b keys: 256
> > > bytes of non PKCS#1.5 data] */
> > > +        0x80, 0x42, 0x00, 0x00, 0x00, 0x01, 0x00,
> > > +0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > > 0xff, 0xff, 0xff, 0xff, 0xff,
> > > +/*      ^--- the second byte of data should be 0x01 for signatures
> > > */
> > > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > > 0xff, 0xff, 0xff, 0xff, 0xff,
> > > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > > 0xff, 0xff, 0xff, 0xff, 0xff,
> > > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > > 0xff, 0xff, 0xff, 0xff, 0xff,
> > > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > > 0xff, 0xff, 0xff, 0xff, 0xff,
> > > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > > 0xff, 0xff, 0xff, 0xff, 0xff,
> > > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > > 0xff, 0xff, 0xff, 0xff, 0xff,
> > > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > > 0xff, 0xff, 0xff, 0xff, 0xff,
> > > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > > 0xff, 0xff, 0xff, 0xff, 0xff,
> > > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > > 0xff, 0xff, 0xff, 0xff, 0xff,
> > > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > > 0xff, 0xff, 0xff, 0xff, 0xff,
> > > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > > 0xff, 0xff, 0xff, 0xff, 0xff,
> > > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > > 0xff, 0xff, 0xff, 0xff, 0xff,
> > > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > > 0xff, 0xff, 0xff, 0xff, 0xff,
> > > +0xff, 0xff, 0x00, 0x64, 0x61, 0x74, 0x61, 0x20, 0x74, 0x6f, 0x20,
> > > 0x73, 0x69, 0x67, 0x6e, 0x20,
> > > +0x28, 0x6d, 0x61, 0x78, 0x20, 0x31, 0x30, 0x30, 0x20, 0x62, 0x79,
> > > 0x74, 0x65, 0x73, 0x29, 0x0a,
> > > +0x00 /* <-- [Le] */
> > > +    };
> > > +    int sign_len = sizeof(sign);
> > > +    int key_bits = getBits();
> > > +
> > > +    g_assert_nonnull(reader);
> > > +
> > > +    /* Skip the HW tests without physical card */
> > > +    if (vreader_card_is_present(reader) != VREADER_OK) {
> > > +        vreader_free(reader);
> > > +        g_test_skip("No physical card found");
> > > +        return;
> > > +    }
> > > +
> > > +    /* run the actual test */
> > > +
> > > +    key_bits = getBits();
> > > +    /* Adjust the buffers to match the key lengths, if already
> > > retrieved */
> > > +    if (key_bits && key_bits < 2048) {
> > > +        sign[4] = key_bits/8; /* less than 2048b will fit the
> > > length into one byte */
> > > +        sign[5] = 0x00;
> > > +        /*sign[6] = 0x01; <- this should be 0x01 for PKCS#1.5
> > > signatures */
> > > +        memcpy(&sign[6], &sign[sign_len-key_bits/8 + 3],
> > > key_bits/8 - 1);
> > 
> > This memcpy is overflowing 'sign' and is causing make check with
> > -fsanitize=address to fail. We try to copy key_bits/8 - 1 bytes
> > starting
> > at offset sign_len-key_bits/8 + 3, which means we'll end up at offset
> > key_bits/8 - 1 + sign_len - key_bits/8 + 3, which computes to
> > sign_len +
> > 2, while the 'sign' array only has a size of 'sign_len'.
> > 
> > I'm replying to this email as I don't know what the right fix for
> > this
> > is.
> 
> Hello,
> thank you for noticing this. It looks like I increased the number here
> instead of decreasing as I should have. I agree that this test is a bit
> wild so I will try to explain what is going on there and where is the
> error:
> 
>  * The sign array is the while APDU.
>  * For payload of less than 256 bytes (for RSA keys of less than 2k),
> we fit Lc part in one byte (instead of 3 as in template), which means
> the "header" is only  5 bytes long. The Le value is adjusted on line
> 298.
>  * On the sixth byte (line 299), there already start PKCS#1.5-padded
> data [1]. This byte needs to be zero from [1]
>  * The line 300 marks where the error is -- we are trying to create bad
> PKCS#1.5 padding -- we overwrite it with 0xff padding later.
>  * The memcpy line is moving the tail of padded data by shrinking the
> padding in the middle
>  * The padding (for simplicity, 0xff bytes are used) starts on the 7th
> byte and spans before the next 0x00 byte.
>  * The memcpy, in theory, should copy data up to the end of the
> original, 256 bytes payload, but it can move also the last byte which
> specifies the Le (handled separately). This means, we are 3 bytes off.
>  * target (&sign[6]) -- this is the place where the padding starts in
> the new buffer
>  * length (key_bits/8 - 1) -- the length of payload is 128 bytes, but
> we already wrote the first byte (line 299).
>  * the source is wrong (&sign[sign_len-key_bits/8]) -- we need to find
> a place where to start copying data from to match the ends of payloads
> in the buffer (128 B and 256 B).
>  * The lines 302 and 303 adjust the buffer lengths and appends 0x01
> (Le) of APDU.
> 
> I tried to improve this part a bit with comments and local variable,
> but if the above helped you to understand the issue, you can improve
> the code and comments.

Yes, this is clearer with this explanation.. And the patch looks
good/fixes my -fsanitize=address issues. I'd change the memcpy to
memmove though. Feel free to push this with a commit log :)

Christophe


> 
> diff --git a/tests/hwtests.c b/tests/hwtests.c
> --- a/tests/hwtests.c
> +++ b/tests/hwtests.c
> @@ -295,11 +295,12 @@ static void test_sign_bad_data_x509(void)
>      key_bits = getBits();
>      /* Adjust the buffers to match the key lengths, if already
> retrieved */
>      if (key_bits && key_bits < 2048) {
> -        sign[4] = key_bits/8; /* less than 2048b will fit the length
> into one byte */
> -        sign[5] = 0x00;
> +        int payload_len = key_bits/8; /* RSA signature has the same
> length as the key */
> +        sign[4] = payload_len; /* less than 2048b will fit the length
> into one byte */
> +        sign[5] = 0x00; /* PKCS#1.5 padding first byte */
>          /*sign[6] = 0x01; <- this should be 0x01 for PKCS#1.5
> signatures */
> -        memcpy(&sign[6], &sign[sign_len-key_bits/8 + 3], key_bits/8 -
> 1);
> -        sign_len = 5 + key_bits/8 + 1;
> +        memcpy(&sign[6], &sign[sign_len - payload_len], payload_len -
> 1);
> +        sign_len = 5 /* [APDU header] */ + payload_len + 1 /* [Le] */;
>          sign[sign_len-1] = 0x00; /* [Le] */
>      }
> 
> 
> [1] https://tools.ietf.org/html/rfc2313#section-8.1
> 
> Thanks,
> -- 
> Jakub Jelen
> Software Engineer
> Security Technologies
> Red Hat, Inc.
> 

Attachment: signature.asc
Description: PGP signature

_______________________________________________
Spice-devel mailing list
Spice-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/spice-devel

[Index of Archives]     [Linux Virtualization]     [Linux Virtualization]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]     [Monitors]