Bug 533063 - preadv()/pwritev() prototypes are broken on i386 with -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
preadv()/pwritev() prototypes are broken on i386 with -D_LARGEFILE_SOURCE -D_...
Status: CLOSED ERRATA
Product: Fedora
Classification: Fedora
Component: glibc (Show other bugs)
11
All Linux
high Severity medium
: ---
: ---
Assigned To: Andreas Schwab
Fedora Extras Quality Assurance
:
Depends On:
Blocks: F12Blocker/F12FinalBlocker F12VirtTarget 545006
  Show dependency treegraph
 
Reported: 2009-11-04 15:55 EST by Daniel Berrange
Modified: 2010-03-15 16:11 EDT (History)
14 users (show)

See Also:
Fixed In Version: 2.10.2-1
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2009-11-05 13:40:27 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Daniel Berrange 2009-11-04 15:55:41 EST
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;
}
EOF


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):
glibc-headers-2.10.1-5.i586

How reproducible:
Always

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
3.
  
Actual results:
Offsets to preadv/pwritev system calls are incorrect

Expected results:


Additional info:
Comment 1 Daniel Berrange 2009-11-04 15:57:22 EST
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 16:01:36 EST
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 16:34:28 EST
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 09:51:11 EST
Built as 2.11-2.
Comment 6 Adam Williamson 2009-11-05 13:40:27 EST
<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
https://fedoraproject.org/wiki/BugZappers
Comment 7 Fedora Update System 2009-11-20 07:48:30 EST
glibc-2.10.2-1 has been submitted as an update for Fedora 11.
http://admin.fedoraproject.org/updates/glibc-2.10.2-1
Comment 8 Fedora Update System 2009-12-15 20:07:31 EST
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.