From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5177 invoked by alias); 30 Oct 2002 16:46:06 -0000 Mailing-List: contact gcc-prs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-prs-owner@gcc.gnu.org Received: (qmail 5074 invoked by uid 71); 30 Oct 2002 16:46:04 -0000 Resent-Date: 30 Oct 2002 16:46:04 -0000 Resent-Message-ID: <20021030164604.5073.qmail@sources.redhat.com> Resent-From: gcc-gnats@gcc.gnu.org (GNATS Filer) Resent-Cc: gcc-prs@gcc.gnu.org, gcc-bugs@gcc.gnu.org Resent-Reply-To: gcc-gnats@gcc.gnu.org, fredlwm@pervalidus.net Received: (qmail 22104 invoked from network); 30 Oct 2002 16:41:38 -0000 Received: from unknown (HELO pervalidus.dyndns.org) (200.255.184.132) by sources.redhat.com with SMTP; 30 Oct 2002 16:41:38 -0000 Received: from fredlwm by pervalidus.dyndns.org with local (Exim 4.10) id 186vuS-0006gR-00 for gcc-gnats@gcc.gnu.org; Wed, 30 Oct 2002 13:41:36 -0300 Message-Id: Date: Wed, 30 Oct 2002 08:46:00 -0000 From: fredlwm@pervalidus.net To: gcc-gnats@gcc.gnu.org X-Send-Pr-Version: 3.113 Subject: c/8404: arguments/stack corrupted when passing non-byte aligned struct with attribute packed X-SW-Source: 2002-10/txt/msg01253.txt.bz2 List-Id: >Number: 8404 >Category: c >Synopsis: arguments/stack corrupted when passing non-byte aligned struct with attribute packed >Confidential: no >Severity: serious >Priority: medium >Responsible: unassigned >State: open >Class: wrong-code >Submitter-Id: net >Arrival-Date: Wed Oct 30 08:46:03 PST 2002 >Closed-Date: >Last-Modified: >Originator: Frédéric L. W. Meunier >Release: 3.2 >Organization: >Environment: System: Linux pervalidus 2.4.19 #1 Sat Aug 17 13:14:00 BRT 2002 i686 unknown unknown GNU/Linux Architecture: i686 host: i686-pc-linux-gnu build: i686-pc-linux-gnu target: i686-pc-linux-gnu configured with: /usr/local/src/GNU/gcc-3.2/configure --prefix=/usr --libdir=/usr/lib --with-slibdir=/lib --mandir=/usr/share/man --infodir=/usr/share/info --enable-threads --enable-__cxa_atexit --enable-languages=c++ --disable-nls >Description: >How-To-Repeat: // GCC 3.2 BUG REPORT // // This program demonstrates a bug in gcc version 3.2, when passing a // structure with the "packed" attribute comtaining misaligned data. // The data structure is actually from the ATA/ATAPI SMART data // structures. I was working on some legacy code that passed these // structures (not pointers to them!) as arguments. For myself, there // is no urgency in this because I have modified the code to do what // it should have done in the first place -- pass pointers. But it's // a serious bug. // Bruce Allen ballen@uwm.edu // F.L.W. Meunier <0@pervalidus.net> // Compile like this: cc -o bug bug.c // It SHOULD print "These two values should be equal: 16 16 // GCC 3.2 output "These two values should be equal: 62104 16 // System is modified slackware #include #define NUMBER_ATA_SMART_ATTRIBUTES 30 struct ata_smart_attribute { unsigned char id; union { unsigned short all; struct { unsigned prefailure:1; unsigned online:1; unsigned performance:1; unsigned errorrate:1; unsigned eventcount:1 ; unsigned selfperserving:1; unsigned reserved:10; } __attribute__ ((packed)) flag; } status ; unsigned char current; unsigned char worst; unsigned char raw[6]; unsigned char reserv; } __attribute__ ((packed)); struct ata_smart_values { unsigned short int revnumber; struct ata_smart_attribute vendor_attributes [NUMBER_ATA_SMART_ATTRIBUTES]; unsigned char offline_data_collection_status; unsigned char self_test_exec_status; unsigned short int total_time_to_complete_off_line; unsigned char vendor_specific_366; unsigned char offline_data_collection_capability; unsigned short int smart_capability; unsigned char errorlog_capability; unsigned char vendor_specific_371; unsigned char short_test_completion_time; unsigned char extend_test_completion_time; unsigned char reserved_374_385 [12]; unsigned char vendor_specific_386_509 [125]; unsigned char chksum; } __attribute__ ((packed)); struct ata_smart_threshold_entry { unsigned char id; unsigned char threshold; unsigned char reserved[10]; } __attribute__ ((packed)); struct ata_smart_thresholds { unsigned short int revnumber; struct ata_smart_threshold_entry thres_entries[NUMBER_ATA_SMART_ATTRIBUTES]; unsigned char reserved[149]; unsigned char chksum; } __attribute__ ((packed)); // This function is the problem. When it gets it's arguments passsd // (a total of 2x512+4 bytes or 1028 bytes of argument!) the first // seven bytes get messed up (according to ddd/gdb) void problem(struct ata_smart_values data, struct ata_smart_thresholds thresholds, int onlyfailed){ printf("These two values should be equal: %d %d\n", data.revnumber,onlyfailed); return; } // Define two of these data structures struct ata_smart_values smartval; struct ata_smart_thresholds smartthres; // Should print "16 16" but doesn't int main(int argc, char **argv){ unsigned short i=16; smartval.revnumber=smartthres.revnumber=16; problem(smartval, smartthres, i); return 0; } >Fix: don't pass strutures, pass pointers. Seriously, don't know. >Release-Note: >Audit-Trail: >Unformatted: