Subject: kern/35934: read(2) from raw disk into unaligned buffer
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: None <apb@cequrux.com>
List: netbsd-bugs
Date: 03/06/2007 08:35:00
>Number:         35934
>Category:       kern
>Synopsis:       read(2) from raw disk into unaligned buffer
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Mar 06 08:35:00 +0000 2007
>Originator:     Alan Barrett
>Release:        NetBSD 4.99.13
>Organization:
Not much
>Environment:
System: NetBSD 4.99.13
Architecture: i386
Machine: i386
>Description:
When read(2) is asked to read from a raw disk device into an unaligned
buffer, the result is written into memory starting 1 byte before the
specified buffer.  This problem does not occur when reading from
ordinary files or from non-raw disk devices.
	
>How-To-Repeat:
$ cat >test.c <<EOF

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    int fd;
    int offset;
    union {
        uint64_t u_i64;                 /* ensure union is aligned */
        unsigned char u_chars[2*512];	/* larger than necessary*/
        } u;
#define buf u.u_chars

    if (argc != 2) exit(1);

    fd = open(argv[1], O_RDONLY);
    if (fd < 0) exit(2);
    for (offset = 0; offset < 8; offset++) {
        memset(buf, 0, sizeof(buf));
        lseek(fd, 0, 0);
        read(fd, &buf[offset], 512);
        printf("%02x%02x%02x%02x%02x%02x%02x%02x\n",
                buf[0], buf[1], buf[2], buf[3],
                buf[4], buf[5], buf[6], buf[7]);
    }
    return 0;
}

EOF
$ gcc -o test test.c
$ sudo ./test /dev/wd0a # works
eb3c904e65744253
00eb3c904e657442
0000eb3c904e6574
000000eb3c904e65
00000000eb3c904e
0000000000eb3c90
000000000000eb3c
00000000000000eb
$ sudo ./test /dev/rwd0a # fails
eb3c904e65744253
eb3c904e65744253
0000eb3c904e6574
0000eb3c904e6574
00000000eb3c904e
00000000eb3c904e
000000000000eb3c
000000000000eb3c

>Fix:
	Not provided.