Bug 4328 - struct stat is bogus when __USE_FILE_OFFSET64 is defined
Summary: struct stat is bogus when __USE_FILE_OFFSET64 is defined
Status: RESOLVED WORKSFORME
Alias: None
Product: glibc
Classification: Unclassified
Component: libc (show other bugs)
Version: 2.4
: P2 critical
Target Milestone: ---
Assignee: Ulrich Drepper
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-04-06 09:40 UTC by Balazs Scheidler
Modified: 2018-04-20 13:54 UTC (History)
1 user (show)

See Also:
Host: i686-pc-linux-gnu
Target:
Build:
Last reconfirmed:
fweimer: security-


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Balazs Scheidler 2007-04-06 09:40:51 UTC
when __USE_FILE_OFFSET64 is defined fstat() should behave the same as fstat64(),
and struct stat should be compatible with struct stat64. 

This is not the case on my ubuntu edgy system with glibc 2.4-1ubuntu12, but the
same seems to be true for glibc 2.5 as well.

The problem is best described with this gdb session snippet:

(gdb) p (char *)&st.st_size - (char *) &st
$11 = 48
(gdb) p (char *)&st64.st_size - (char *) &st64
$12 = 44

As you can guess, the st_size field contains a bogus value.

I'm using this set of CPPFLAGS:
 -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 

The problem is that bits/stat.h contains short int sized padN fields while
struct stat64 contains int sized padding fields:

struct stat
  {
    __dev_t st_dev;                     /* Device.  */
    unsigned short int __pad1;
    ...
  }

struct stat64
  {

    __dev_t st_dev;                     /* Device.  */
    unsigned int __pad1;

  }
Comment 1 Jakub Jelinek 2007-04-06 09:52:46 UTC
Then the bug is Ubuntu specific.
(gdb) p (char *)&st64.st_size - (char *)&st64
$1 = 44
(gdb) p (char *)&st.st_size - (char *)&st
$2 = 44

and
#define _GNU_SOURCE
#define _LARGEFILE_SOURCE
#define _FILE_OFFSET_BITS 64
#include <sys/stat.h>
#include <stddef.h>
#include <stdio.h>

int
main (void)
{
  printf ("%zd\n", (size_t) offsetof (struct stat, st_size));
  printf ("%zd\n", (size_t) offsetof (struct stat64, st_size));
  return 0;
}

prints 44 twice for 32-bit binaries (both on x86_64 -m32 and on i?86 only),
48 for 64-bit binaries.
Comment 2 Balazs Scheidler 2007-04-06 10:37:50 UTC
hmm... it prints 44 for me as well, it seems to be somewhat more involved, then.
I can clearly reproduce this problem when syslog-ng is run, but prints a proper
value when it is your testprogram.

I'm rechecking now, sorry for bothering you.
Comment 3 Balazs Scheidler 2007-04-06 10:54:49 UTC
Just for the curious, this is not a glibc bug.

gdb uses invalid offsets, probably because it sees two declarations of struct
stat, one is in syslog-ng, the other is a statically linked library (libnet).

The two differs, and I was unlucky. while gdb reports invalid values, the
program sees them perfectly.

I mark the bug VERIFIED.