Subject: kern/4505: Crash when reading from raw device to non mapped buffer
To: None <gnats-bugs@gnats.netbsd.org>
From: None <kivinen@ssh.fi>
List: netbsd-bugs
Date: 11/16/1997 13:32:42
>Number: 4505
>Category: kern
>Synopsis: System crash when reading from raw device to buffer that is not mapped
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people (Kernel Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Nov 16 03:35:02 1997
>Last-Modified:
>Originator: Tero Kivinen
>Organization:
Ssh Communications Security Ltd
>Release: 1.2
>Environment:
System: NetBSD taulu.ssh.fi 1.2 NetBSD 1.2 (TAULU) #50: Mon Feb 24 21:40:52 EET 1997 kivinen@taulu.ssh.fi:/usr/src/sys/arch/i386/compile/TAULU i386
>Description:
When reading data from raw device (/dev/rwd0a for example) to
buffer that is allocated but not mapped the kernel will crash
(drop to debugger).
Because reading from raw device usually requires root
permission this is not very fatal bug unless some environments
are configured to allow raw disk access to some users
(database disk etc).
>How-To-Repeat:
Run this program with /dev/rwd0b (or any other raw disk
device) as an argument. If you give a block device or define
NO_BUG when compiling it then the kernel doesn't crash.
----------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#define RAW_BUFFER_SIZE 10*1024*1024
int main(int argc, char **argv)
{
char *buffer;
int f;
ssize_t l;
if (argc != 2)
{
fprintf(stderr, "Usage: %s raw_disk_name\n", argv[0]);
exit(1);
}
buffer = malloc(RAW_BUFFER_SIZE);
#ifdef NO_BUG
memset(buffer, 0, RAW_BUFFER_SIZE);
#endif
f = open(argv[1], O_RDONLY, 0);
if (f < 0) { perror("open"); exit(1); }
l = read(f, buffer, RAW_BUFFER_SIZE);
if (l != RAW_BUFFER_SIZE) { perror("read"); exit(1); }
close(f);
exit(0);
}
----------------------------------------------------------------------
# gcc t.c
# sync
# ls -lag
total 324
drwxrwxrwt 2 root wheel 512 Nov 16 13:37 .
drwxr-xr-x 21 tmo wheel 1024 Oct 29 09:37 ..
-rwxr-xr-x 1 root wheel 8845 Nov 16 13:37 a.out
-rw-r--r-- 1 root wheel 577 Nov 16 13:37 t.c
# ./a.out
Usage: ./a.out raw_disk_name
# ./a.out /dev/wd0b
# ./a.out /dev/rwd0b
panic: ptdi 649063
syncing disks... 8 8 6 1 done
dumping to dev 1, offset 370432
dump 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 succeeded
rebooting...
>Fix:
I assume it will give the buffer supplied by user directly to
device read if device is raw device, and the device read is
not prepared to handle page faults. If you use block device
then the pages are always allocated because they are in buffer
cache.
>Audit-Trail:
>Unformatted:
>> NetBSD: 640/15360 k [1.28]
[[[wd(0,a)]/netbsd][-adrs]] :-
798720+36864+581040+[54300+60192]=0x275cf4
entry point at 0x100020
Copyright (c) 1982, 1986, 1989, 1991, 1993
The Regents of the University of California. All rights reserved.
NetBSD 1.2E (puijo0) #2: Wed Jun 25 15:38:59 EET DST 1997
tmo@hylly.ssh.fi:/usr/local/kernel/test
cpu0: family 5 model 2 step 5
cpu0: Intel Pentium (P54C) (586-class)
real mem = 16384000
avail mem = 13549568
using 225 buffers containing 921600 bytes of memory
mainbus0 (root)
... <rest of boot messages removed>
# cd tmp
# ls -lag
total 324
drwxrwxrwt 2 root wheel 512 Nov 16 13:37 .
drwxr-xr-x 21 tmo wheel 1024 Oct 29 09:37 ..
-rwxr-xr-x 1 root wheel 8845 Nov 16 13:37 a.out
-rw-r--r-- 1 root wheel 577 Nov 16 13:37 t.c
# sync
# gcc -DNO_BUG t.c
# ./a.out /dev/wd0b
# ./a.out /dev/rwd0b
# gcc t.c
# ./a.out /dev/rwd0b
panic: ptdi 731063
syncing disks... 1 1 done
dumping to dev 1, offset 370432
...