Bug 93454 - [10 Regression] buffer overflow in fold_array_ctor_reference since r10-1882
Summary: [10 Regression] buffer overflow in fold_array_ctor_reference since r10-1882
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 10.0
: P1 normal
Target Milestone: 10.0
Assignee: Jakub Jelinek
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-01-27 14:32 UTC by Jakub Jelinek
Modified: 2020-01-28 07:47 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2020-01-27 00:00:00


Attachments
gcc10-pr93454.patch (1.09 KB, patch)
2020-01-27 15:09 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jakub Jelinek 2020-01-27 14:32:21 UTC
#define A(n) n, n + 0x01010101, n + 0x02020202, n + 0x03030303
#define B(n) A (n), A (n + 0x04040404), A (n + 0x08080808), A (n + 0x0c0c0c0c)
#define C(n) B (n), B (n + 0x10101010), B (n + 0x20202020), B (n + 0x30303030)
#define D(n) C (n), C (n + 0x40404040), C (n + 0x80808080U), C (n + 0xc0c0c0c0U)
const unsigned int a[64] = { C (0) };
const unsigned int b[256] = { D (0) };

void
foo (void)
{
  const unsigned char *s = ((const unsigned char *)a) + 1;
  const unsigned char *t = ((const unsigned char *)b) + 1;
}

with -O2 -g overflows the buf array in fold_array_ctor_reference (overwrites 3 bytes at the end of buf) on both x86_64-linux where the buf array has 256 bytes and on aarch64-linux where it has 1024 bytes.  Shouldn't be hard to construct testcases for other targets that can have yet different MAX_BITSIZE_MODE_ANY_MODE values.
Started with r10-1882-g831e688af50c5f77a2daa3cd3bfd0f27d54d5d72
Comment 1 Jakub Jelinek 2020-01-27 14:32:48 UTC
Looking at it.
Comment 2 Jakub Jelinek 2020-01-27 15:09:01 UTC
Created attachment 47715 [details]
gcc10-pr93454.patch

Untested fix.
Comment 3 GCC Commits 2020-01-28 07:46:29 UTC
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:3c076c9642fd8877def0a0597ec7e4adfb5aa3b3

commit r10-6272-g3c076c9642fd8877def0a0597ec7e4adfb5aa3b3
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Tue Jan 28 08:44:07 2020 +0100

    gimple-fold: Fix buffer overflow in fold_array_ctor_reference [PR93454]
    
    libgcrypt FAILs to build on aarch64-linux with
    *** stack smashing detected ***: terminated
    when gcc is compiled with -D_FORTIFY_SOURCE=2.  The problem is if
    fold_array_ctor_reference is called with size equal to or very close to
    MAX_BITSIZE_MODE_ANY_MODE bits and non-zero inner_offset.
    The first native_encode_expr is called with that inner_offset and bufoff 0,
    the subsequent ones with offset of 0, and bufoff elt_size - inner_offset,
    2 * elt_size - inner_offset etc.  So, e.g. on the testcase where we start
    with inner_offset 1 and size is e.g. 256 bytes and elt_size 4 bytes
    we then call native_encode_expr at bufoff 251 and then 255, but that one
    overwrites 3 bytes beyond the buf array.
    The following patch fixes that.  In addition, it avoids calling
    elt_size.to_uhwi () all the time, and punts if elt_sz would be too large.
    
    2020-01-28  Jakub Jelinek  <jakub@redhat.com>
    
    	PR tree-optimization/93454
    	* gimple-fold.c (fold_array_ctor_reference): Perform
    	elt_size.to_uhwi () just once, instead of calling it in every
    	iteration.  Punt if that value is above size of the temporary
    	buffer.  Decrease third native_encode_expr argument when
    	bufoff + elt_sz is above size of buf.
    
    	* gcc.dg/pr93454.c: New test.
Comment 4 Jakub Jelinek 2020-01-28 07:47:55 UTC
Fixed.