This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Linux getdents.c is not aliasing safe


Daniel Jacobowitz <dan@debian.org> writes:

|> Highlights:
|>       char *kbuf = buf;
|>       size_t kbytes = nbytes;
|>       if (offsetof (DIRENT_TYPE, d_name)
|>           < offsetof (struct kernel_dirent64, d_name)
|>           && nbytes <= sizeof (DIRENT_TYPE))
|>         {
|>           kbytes = nbytes + offsetof (struct kernel_dirent64, d_name)
|>                    - offsetof (DIRENT_TYPE, d_name);
|>           kbuf = __alloca(kbytes);
|>         }
|> 
|>           dp = (DIRENT_TYPE *)buf;
|>           kdp = (struct kernel_dirent64 *) kbuf;
|> 
|>               uint64_t d_ino = kdp->d_ino;
|>               int64_t d_off = kdp->d_off;
|>               unsigned char d_type = kdp->d_type;
|> 
|>               DIRENT_SET_DP_INO (dp, d_ino);
|>               dp->d_off = d_off;
|> 
|> GCC is perfectly free to re-order the stores and loads here; if it does,
|> when buf and kbuf are pointing at the same thing (which they usually are),
|> then storing to dp->d_off (at offset 4 in a 32-bit dirent) corrupts d_ino
|> (at offset 0 and size 8 in a kernel_dirent64).  This is why Debian was
|> seeing a broken ldconfig.
|> 
|> Not sure how to fix this while still editing the buffer in-place.  It seems
|> like we want the equivalent of:
|> 
|> union {
|>   DIRENT_TYPE dpbuf[];
|>   struct kernel_dirent64[];
|> }
|> 
|> but that's not legal C.

How about using two pointers of type

union {
  DIRENT_TYPE dp;
  struct kernel_dirent64 kdp;
}

?

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux AG, Deutschherrnstr. 15-19, D-90429 Nürnberg
Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]