Bug 533063 - preadv()/pwritev() prototypes are broken on i386 with -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
Summary: preadv()/pwritev() prototypes are broken on i386 with -D_LARGEFILE_SOURCE -D_...
Alias: None
Product: Fedora
Classification: Fedora
Component: glibc
Version: 11
Hardware: All
OS: Linux
Target Milestone: ---
Assignee: Andreas Schwab
QA Contact: Fedora Extras Quality Assurance
Depends On:
Blocks: F12Blocker, F12FinalBlocker F12VirtTarget 545006
TreeView+ depends on / blocked
Reported: 2009-11-04 20:55 UTC by Daniel Berrangé
Modified: 2010-03-15 20:11 UTC (History)
14 users (show)

Fixed In Version: 2.10.2-1
Doc Type: Bug Fix
Doc Text:
Clone Of:
Last Closed: 2009-11-05 18:40:27 UTC

Attachments (Terms of Use)

Description Daniel Berrangé 2009-11-04 20:55:41 UTC
Description of problem:
When compiling a program that uses  preadv() with  -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 set,  the last off_t  parameter  is supposed to be 64-bit in size, however, an incorrect prototype causes it to remain 32-bit. This results in data being read/written to/from the wrong place

This short demo illustrating the problem

$ cat > p.c <<EOF
#include <unistd.h>
#include <stdio.h>
#include <sys/uio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>

int main (int argc, char **argv) {
    int fd;
    unsigned long long off = 0xffffffffeeffull;
    char data[11] = "0123456789";
    char got[11];
    struct iovec gotv[] = {
        { got, 11 },

    fd = open("demo.img", O_RDWR | O_CREAT | O_TRUNC, S_IWUSR | S_IRUSR);

    ftruncate(fd, off);
    lseek(fd, off, SEEK_SET);
    write(fd, data, 11);

    memset(got, 0, 11);
    preadv(fd, gotv, 1, off);

    memset(got, 0, 11);
    lseek(fd, off, SEEK_SET);
    read(fd, got, 11);

    return 0;

Compiling this program using

 $ gcc -g -O0 -Wall $(getconf LFS_CFLAGS) $(getconf LFS_LIBS) $(getconf LFS_LDFLAGS) -o p  p.c 

And then strace'ing the program

open("demo.img", O_RDWR|O_CREAT|O_TRUNC|O_LARGEFILE, 0600) = 3
ftruncate64(3, 281474976706303)         = -1 EFBIG (File too large)
_llseek(3, 281474976706303, 0xbfee6220, SEEK_SET) = -1 EINVAL (Invalid argument)
write(3, "0123456789\0"..., 11)         = 11
pread64(3, 0xbfee61d0, 11, 13830099914970885887) = -1 EINVAL (Invalid argument)
_llseek(3, 281474976706303, 0xbfee6220, SEEK_SET) = -1 EINVAL (Invalid argument)
read(3, ""..., 11)                      = 0
exit_group(0)                           = ?

If everything were operating correctly, the  larst arg to pread64 should have been  the same as that used in ftruncate64/__llseek

Version-Release number of selected component (if applicable):

How reproducible:

Steps to Reproduce:
1. Build above test program on an i386 host, using -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
2. Run it under strace
Actual results:
Offsets to preadv/pwritev system calls are incorrect

Expected results:

Additional info:

Comment 1 Daniel Berrangé 2009-11-04 20:57:22 UTC
It would appear to me that in /usr/include/sys/uio.h, that these prototypes

extern ssize_t __REDIRECT (preadv, (int __fd, __const struct iovec *__iovec,
                                    int __count, __off_t __offset),
                           preadv64) __wur;
extern ssize_t __REDIRECT (pwritev, (int __fd, __const struct iovec *__iovec,
                                     int __count, __off_t __offset),
                           pwritev64) __wur;

should be using '__off64_t' instead ?

Comment 2 Mark McLoughlin 2009-11-04 21:01:36 UTC
bug #526549 is the 32 bit qemu data corruptor that uncovered this; we've worked around the issue by disabling preadv/pwritev use for F-12 GA

Comment 3 Jakub Jelinek 2009-11-04 21:34:28 UTC
Yes, the suggested change in #c1 looks correct to me.  While off_t is 64-bit, __off_t is not for 32-bit arches, even when -D_FILE_OFFSET_BITS=64.

Comment 5 Bill Nottingham 2009-11-05 14:51:11 UTC
Built as 2.11-2.

Comment 6 Adam Williamson 2009-11-05 18:40:27 UTC
<adamw> notting: where are we on 533063 (the glibc bug), did we tag the fixed glibc and rebuilds of affected packages?
<notting> adamw: yeah, a couple of hours ago.
<adamw> notting: should we close the bug then?
<notting> adamw: sure!

Fedora Bugzappers volunteer triage team

Comment 7 Fedora Update System 2009-11-20 12:48:30 UTC
glibc-2.10.2-1 has been submitted as an update for Fedora 11.

Comment 8 Fedora Update System 2009-12-16 01:07:31 UTC
glibc-2.10.2-1 has been pushed to the Fedora 11 stable repository.  If problems still persist, please make note of it in this bug report.

Note You need to log in before you can comment on or make changes to this bug.