From owner-freebsd-bugs@FreeBSD.ORG Tue Dec 16 16:30:32 2003 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 07DF716A4CE for ; Tue, 16 Dec 2003 16:30:32 -0800 (PST) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id E851043D1F for ; Tue, 16 Dec 2003 16:30:20 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) hBH0UKFR098826 for ; Tue, 16 Dec 2003 16:30:20 -0800 (PST) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.10/8.12.10/Submit) id hBH0UKpR098825; Tue, 16 Dec 2003 16:30:20 -0800 (PST) (envelope-from gnats) Resent-Date: Tue, 16 Dec 2003 16:30:20 -0800 (PST) Resent-Message-Id: <200312170030.hBH0UKpR098825@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Matthias Andree Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 6139B16A4CE for ; Tue, 16 Dec 2003 16:20:30 -0800 (PST) Received: from mail.dt.e-technik.uni-dortmund.de (mail.dt.E-Technik.Uni-Dortmund.DE [129.217.163.1]) by mx1.FreeBSD.org (Postfix) with ESMTP id 5A59B43D3F for ; Tue, 16 Dec 2003 16:20:26 -0800 (PST) (envelope-from matthias.andree@gmx.de) Received: from m2a2.dyndns.org (krusty.dt.e-technik.uni-dortmund.de [129.217.163.1])22E5617A14 for ; Wed, 17 Dec 2003 01:20:25 +0100 (CET) Received: from libertas.emma.line.org (libertas.emma.line.org [192.168.0.2]) by merlin.emma.line.org (Postfix) with ESMTP id 81728838DB; Wed, 17 Dec 2003 01:20:23 +0100 (CET) Received: from emma by libertas.emma.line.org with local (Exim 4.24; FreeBSD) id 1AWPQM-00006K-VN; Wed, 17 Dec 2003 01:20:22 +0100 Message-Id: Date: Wed, 17 Dec 2003 01:20:22 +0100 From: Matthias Andree To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Subject: kern/60313: data destruction: lseek() misalignment silently ignored by some block devices X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: Matthias Andree List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 17 Dec 2003 00:30:32 -0000 >Number: 60313 >Category: kern >Synopsis: data destruction: lseek() misalignment silently ignored by some block devices >Confidential: no >Severity: critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Dec 16 16:30:20 PST 2003 >Closed-Date: >Last-Modified: >Originator: Matthias Andree >Release: FreeBSD 4.9-STABLE i386 >Organization: >Environment: System: FreeBSD libertas.emma.line.org 4.9-STABLE FreeBSD 4.9-STABLE #65: Sat Dec 13 20:13:45 CET 2003 toor@libertas.emma.line.org:/usr/src/sys/compile/LIBERTAS i386 >Description: da(4) will happily return success on lseek() to some random position that is not aligned at a block boundary and start writing from the beginning, byte 0, of the block, ignoring the lseek(). In other words, if I have a drive with 512 bytes per block, seek to offset 256 and write 512 bytes, da(4) will scribble over the first 256 bytes as well. Either the seek or the write should be rejected. vn(4) will accept the seek but a subsequent write(2) will return the bogus EINVAL in errno. ad(4) status is unknown. FreeBSD 5 status is unknown. >How-To-Repeat: Save this test program as tryraw.c. Compile this DESTRUCTIVE test program and run it on an UNUSED partition: gcc -O -o tryraw tryraw.c ./tryraw /dev/da0s1b WARNING: THIS TEST DESTROYS DATA IN THE GIVEN PARTITION! USE IT ON AN INACTIVE SWAP PARTITION ONLY (i. e. comment the swap partition out, reboot). /* BEGIN tryraw.c */ #include #include #include #include #include #include #include void barf(const char *t) __attribute__((noreturn)); void barf(const char *t) { perror(t); exit(EXIT_FAILURE); } int main(int argc, char **argv) { int bs, fd; int want = 0x66, t; struct disklabel dl; char *x; if (argc < 2) { fprintf(stderr, "need a partition that I can clobber.\n"); exit(EXIT_FAILURE); } fd = open(argv[1], O_RDWR); if (fd < 0) barf("open"); if (0 == ioctl(fd, DIOCGDINFO, &dl)) { printf("sector size: %lu\n", (unsigned long)(bs = dl.d_secsize)); } else barf("ioctl DIOCGDINFO"); /* this writes bs = blocksize times the byte 0x66 at offset #0 * then seeks to offset #bs/2 then writes bs times the byte 0x33. */ if (!(x = malloc(bs))) barf("malloc"); memset(x, want, bs); if (lseek(fd, 0, SEEK_SET) == (off_t)-1) barf("lseek 0"); if (write(fd, x, bs) < bs) barf("write"); memset(x, 0x33, bs); t = lseek(fd, bs >> 1, SEEK_SET); if (t == -1) barf("lseek bs/2"); printf("seeked to byte #%d\n", t); if (write(fd, x, bs) < bs) barf("write"); if (lseek(fd, 0, SEEK_SET) == (off_t)-1) barf("lseek 0"); if (read(fd, x, bs) < bs) barf("read"); if (x[0] == want) puts("OK"); else printf("KERNEL BUG: byte #0 is %x, should be %x\n", x[0], want); free(x); return 0; } /* END tryraw.c */ >Fix: Let lseek return (off_t)-1 and errno==EINVAL when the device doesn't support unaligned access. >Release-Note: >Audit-Trail: >Unformatted: