Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 7 Feb 2005 22:07:48 +0200 (EET)
From:      Andriy Gapon <avg@icyb.net.ua>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   kern/77234: corrupted data is read from UDF filesystem if read starts at non-aligned offset
Message-ID:  <200502072007.j17K7m2R016739@oddity.topspin.kiev.ua>
Resent-Message-ID: <200502072010.j17KAOVZ029835@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         77234
>Category:       kern
>Synopsis:       corrupted data is read from UDF filesystem if read starts at non-aligned offset
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Feb 07 20:10:24 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     Andriy Gapon
>Release:        FreeBSD 5.2.1-RELEASE-p13 i386
>Organization:
>Environment:
System: FreeBSD 5.2.1-RELEASE-p13 386
sys/fs/udf/udf_vnops.c is patched to revision 1.50


	
>Description:
it seems that udf_readatoffset() function does not properly handle
certain offset, size combinations:
offset%bsize != 0
and
size in ](bsize-offset%bsize) + n*bsize, bsize + n*bsize]
where n = 0, 1, 2, ... 

or with graphic illustration:
  current offset
  v
  |--------|        - data that we want to read
  |******|&|        - '*' are for good data, '&' for junk in memory
|--------|--------| - data on disk
|^^^^^^^^|          - this is what would be read with current code
|^^^^^^^^|^^^^^^^^| - this is what should be read
^        ^        ^
sector (or logical block) boundaries

this happens because calculations of number of sectors to read do not
take into account the fact that an additional sector may be needed because
of current offset alignment.

>How-To-Repeat:
mount udf disk and perform something similar to large enough file:
tmp$ dd if=/mnt/dvdrom/oddity/export.level-7.2005-02-01.dump.gz of=ttt bs=2000
21+1 records in
21+1 records out
42472 bytes transferred in 0.226800 secs (187266 bytes/sec)
tmp$ diff /mnt/dvdrom/oddity/export.level-7.2005-02-01.dump.gz ttt
Binary files /mnt/dvdrom/oddity/export.level-7.2005-02-01.dump.gz and ttt differ
tmp$ dd if=/mnt/dvdrom/oddity/export.level-7.2005-02-01.dump.gz of=ttt bs=2048
20+1 records in
20+1 records out
42472 bytes transferred in 0.038471 secs (1104001 bytes/sec)
tmp$ diff /mnt/dvdrom/oddity/export.level-7.2005-02-01.dump.gz ttt
tmp$ 

file should be the same in both cases

>Fix:

number of requested bytes passed to udf_readlblks should be increased 
by (offset & udfmp->bmask) bytes.
For the same reasons max_size calculated in udf_bmap_internal() should be
decreased by the same value, so that we do not read beyond extent end.

>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200502072007.j17K7m2R016739>