Bug 23484 - __builtin___memcpy_chk miscompilation
Summary: __builtin___memcpy_chk miscompilation
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.1.0
: P2 normal
Target Milestone: 4.1.0
Assignee: Jakub Jelinek
URL: http://gcc.gnu.org/ml/gcc-patches/200...
Keywords: patch, wrong-code
Depends on:
Blocks:
 
Reported: 2005-08-19 16:38 UTC by Gwenole Beauchesne
Modified: 2005-08-29 12:38 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-08-22 14:53:32


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Gwenole Beauchesne 2005-08-19 16:38:16 UTC
Hi,

Compiling ruby on x86_64 with -D_FORTIFY_SOURCE=2 will cause failure in the
testsuite.

This can be reproduced with
GNU C version 4.1.0 20050819 (experimental) (x86_64-unknown-linux-gnu)

Here is a simplified testcase.

extern void abort (void);

#undef memcpy
#define memcpy(dst, src, len) \
  __builtin___memcpy_chk (dst, src, len, __builtin_object_size (dst, 0))

int
main (void)
{
  static const char data[] = { 0, 0x40, 0xe2, 0x01, 0x00, 0x01, 0x80, 0xc0, 0x1d };
  const char *s = &data[1];
  int natint = data[0];
  unsigned long tmp = 0;

  memcpy (&tmp, s, natint ? sizeof(tmp) : 4);
  if (sizeof(tmp) > 4 && (tmp >> 32) != 0) /* movq generated? */
    abort ();

  return 0;
}
Comment 1 Andrew Pinski 2005-08-19 18:54:35 UTC
Hmm, let look at the source:
  memcpy (&tmp, s, natint ? sizeof(tmp) : 4);


natint will be zero so we get 
Comment 2 Andrew Pinski 2005-08-19 18:55:22 UTC
(In reply to comment #1)
Ignore that comment, I am stupid.
Comment 3 Andrew Pinski 2005-08-19 19:00:29 UTC
It can be confirmed on x86 with:
extern void abort (void);

#undef memcpy
#define memcpy(dst, src, len) \
  __builtin___memcpy_chk (dst, src, len, __builtin_object_size (dst, 0))

int
main (void)
{
  static const char data[] = { 0, 0x40, 0xe2, 0x01, 0x00, 0x01, 0x80, 0xc0, 0x1d };
  const char *s = &data[1];
  int natint = data[0];
  unsigned long long tmp = 0;

  memcpy (&tmp, s, natint ? sizeof(tmp) : 4);
  if (sizeof(tmp) > 4 && (tmp>>32) != 0) /* movq generated? */
    abort ();

  return 0;
}

And here is a testcase for big endian:
extern void abort (void);

#undef memcpy
#define memcpy(dst, src, len) \
  __builtin___memcpy_chk (dst, src, len, __builtin_object_size (dst, 0))

int
main (void)
{
  static const char data[] = { 0, 0x40, 0xe2, 0x01, 0x00, 0x01, 0x80, 0xc0, 0x1d };
  const char *s = &data[1];
  int natint = data[0];
  unsigned long long tmp = 0;

  memcpy (&tmp, s, natint ? sizeof(tmp) : 4);
  printf("%llx\n", tmp);
  if (sizeof(tmp) > 4 && (tmp &0xFFFFFF) != 0) /* 64bit move generated? */
    abort ();

  return 0;
}
Comment 4 Jakub Jelinek 2005-08-19 19:16:25 UTC
I have a preliminary fix, will work on testcases now, then test it thoroughly.
Comment 5 CVS Commits 2005-08-29 08:40:55 UTC
Subject: Bug 23484

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	jakub@gcc.gnu.org	2005-08-29 08:40:48

Modified files:
	gcc            : ChangeLog builtins.c 
	gcc/testsuite  : ChangeLog 
Added files:
	gcc/testsuite/gcc.c-torture/execute/builtins: pr23484-chk-lib.c 
	                                              pr23484-chk.c 

Log message:
	PR middle-end/23484
	* builtins.c (fold_builtin_memory_chk, fold_builtin_stxcpy_chk,
	fold_builtin_strncpy_chk, fold_builtin_snprintf_chk): If len is
	not constant, but maxlen is, don't set len to maxlen, rather
	set maxlen to len if len is a constant.
	
	* gcc.c-torture/execute/builtins/pr23484-chk.c: New test.
	* gcc.c-torture/execute/builtins/pr23484-chk-lib.c: New file.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.9847&r2=2.9848
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/builtins.c.diff?cvsroot=gcc&r1=1.474&r2=1.475
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.5974&r2=1.5975
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.c-torture/execute/builtins/pr23484-chk-lib.c.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.c-torture/execute/builtins/pr23484-chk.c.diff?cvsroot=gcc&r1=NONE&r2=1.1

Comment 6 CVS Commits 2005-08-29 08:42:18 UTC
Subject: Bug 23484

CVSROOT:	/cvs/gcc
Module name:	gcc
Branch: 	gcc-4_0-rhl-branch
Changes by:	jakub@gcc.gnu.org	2005-08-29 08:42:09

Modified files:
	gcc            : ChangeLog builtins.c 
	gcc/testsuite  : ChangeLog 
Added files:
	gcc/testsuite/gcc.c-torture/execute/builtins: pr23484-chk.c 
	                                              pr23484-chk-lib.c 

Log message:
	PR middle-end/23484
	* builtins.c (fold_builtin_memory_chk, fold_builtin_stxcpy_chk,
	fold_builtin_strncpy_chk, fold_builtin_snprintf_chk): If len is
	not constant, but maxlen is, don't set len to maxlen, rather
	set maxlen to len if len is a constant.
	
	* gcc.c-torture/execute/builtins/pr23484-chk.c: New test.
	* gcc.c-torture/execute/builtins/pr23484-chk-lib.c: New file.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-4_0-rhl-branch&r1=2.7592.2.10.2.56&r2=2.7592.2.10.2.57
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/builtins.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-rhl-branch&r1=1.426.4.6&r2=1.426.4.7
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-4_0-rhl-branch&r1=1.5084.2.9.2.52&r2=1.5084.2.9.2.53
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.c-torture/execute/builtins/pr23484-chk.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-rhl-branch&r1=NONE&r2=1.1.2.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.c-torture/execute/builtins/pr23484-chk-lib.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-rhl-branch&r1=NONE&r2=1.1.2.1

Comment 7 Andrew Pinski 2005-08-29 12:38:16 UTC
Fixed.