linux/fs/ntfs
NeilBrown 01408c4939 [PATCH] Prepare for __copy_from_user_inatomic to not zero missed bytes
The problem is that when we write to a file, the copy from userspace to
pagecache is first done with preemption disabled, so if the source address is
not immediately available the copy fails *and* *zeros* *the* *destination*.

This is a problem because a concurrent read (which admittedly is an odd thing
to do) might see zeros rather that was there before the write, or what was
there after, or some mixture of the two (any of these being a reasonable thing
to see).

If the copy did fail, it will immediately be retried with preemption
re-enabled so any transient problem with accessing the source won't cause an
error.

The first copying does not need to zero any uncopied bytes, and doing so
causes the problem.  It uses copy_from_user_atomic rather than copy_from_user
so the simple expedient is to change copy_from_user_atomic to *not* zero out
bytes on failure.

The first of these two patches prepares for the change by fixing two places
which assume copy_from_user_atomic does zero the tail.  The two usages are
very similar pieces of code which copy from a userspace iovec into one or more
page-cache pages.  These are changed to remove the assumption.

The second patch changes __copy_from_user_inatomic* to not zero the tail.
Once these are accepted, I will look at similar patches of other architectures
where this is important (ppc, mips and sparc being the ones I can find).

This patch:

There is a problem with __copy_from_user_inatomic zeroing the tail of the
buffer in the case of an error.  As it is called in atomic context, the error
may be transient, so it results in zeros being written where maybe they
shouldn't be.

In the usage in filemap, this opens a window for a well timed read to see data
(zeros) which is not consistent with any ordering of reads and writes.

Most cases where __copy_from_user_inatomic is called, a failure results in
__copy_from_user being called immediately.  As long as the latter zeros the
tail, the former doesn't need to.  However in *copy_from_user_iovec
implementations (in both filemap and ntfs/file), it is assumed that
copy_from_user_inatomic will zero the tail.

This patch removes that assumption, so that after this patch it will
be safe for copy_from_user_inatomic to not zero the tail.

This patch also adds some commentary to filemap.h and asm-i386/uaccess.h.

After this patch, all architectures that might disable preempt when
kmap_atomic is called need to have their __copy_from_user_inatomic* "fixed".
This includes
 - powerpc
 - i386
 - mips
 - sparc

Signed-off-by: Neil Brown <neilb@suse.de>
Cc: David Howells <dhowells@redhat.com>
Cc: Anton Altaparmakov <aia21@cantab.net>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: William Lee Irwin III <wli@holomorphy.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-06-25 10:01:09 -07:00
..
ChangeLog NTFS: Semaphore to mutex conversion. 2006-03-23 16:57:48 +00:00
Makefile NTFS: Fix an (innocent) off-by-one error in the runlist code. 2006-03-23 14:57:43 +00:00
aops.c NTFS: Semaphore to mutex conversion. 2006-03-23 16:57:48 +00:00
aops.h [PATCH] read_mapping_page for address space 2006-06-23 07:43:02 -07:00
attrib.c [PATCH] read_mapping_page for address space 2006-06-23 07:43:02 -07:00
attrib.h NTFS: Add fs/ntfs/attrib.[hc]::ntfs_attr_extend_allocation(), a function to 2005-10-04 15:18:56 +01:00
bitmap.c NTFS: Fix a stupid bug in __ntfs_bitmap_set_bits_in_run() which caused the 2005-10-04 13:06:00 +01:00
bitmap.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
collate.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
collate.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
compress.c NTFS: Semaphore to mutex conversion. 2006-03-23 16:57:48 +00:00
debug.c NTFS: Fix printk format warnings on ia64. (Randy Dunlap) 2005-05-05 11:11:47 +01:00
debug.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
dir.c [PATCH] Make most file operations structs in fs/ const 2006-03-28 09:16:06 -08:00
dir.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
endian.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
file.c [PATCH] Prepare for __copy_from_user_inatomic to not zero missed bytes 2006-06-25 10:01:09 -07:00
index.c [PATCH] mutex subsystem, semaphore to mutex: VFS, ->i_sem 2006-01-09 15:59:24 -08:00
index.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
inode.c NTFS: Semaphore to mutex conversion. 2006-03-23 16:57:48 +00:00
inode.h NTFS: Semaphore to mutex conversion. 2006-03-23 16:57:48 +00:00
layout.h NTFS: Improve comments on file attribute flags in fs/ntfs/layout.h. 2006-03-23 16:09:40 +00:00
lcnalloc.c NTFS: - Change ntfs_cluster_alloc() to take an extra boolean parameter 2005-10-04 14:36:56 +01:00
lcnalloc.h NTFS: - Change ntfs_cluster_alloc() to take an extra boolean parameter 2005-10-04 14:36:56 +01:00
logfile.c [PATCH] bitops: ntfs: remove generic_ffs() 2006-03-26 08:57:15 -08:00
logfile.h NTFS: Fix sparse warnings that have crept in over time. 2005-09-22 13:26:44 +01:00
malloc.h NTFS: In attrib.c::ntfs_attr_set() call balance_dirty_pages_ratelimited() 2005-10-11 14:54:42 +01:00
mft.c [PATCH] bitops: ntfs: remove generic_ffs() 2006-03-26 08:57:15 -08:00
mft.h NTFS: Remove all the make_bad_inode() calls. This should only be called 2006-03-23 15:59:32 +00:00
mst.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
namei.c NTFS: Handle the recently introduced -ENAMETOOLONG return value from 2006-03-23 16:25:23 +00:00
ntfs.h [PATCH] Make most file operations structs in fs/ const 2006-03-28 09:16:06 -08:00
quota.c [PATCH] mutex subsystem, semaphore to mutex: VFS, ->i_sem 2006-01-09 15:59:24 -08:00
quota.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
runlist.c NTFS: Fix an (innocent) off-by-one error in the runlist code. 2006-03-23 14:57:43 +00:00
runlist.h NTFS: Add ntfs_rl_punch_nolock() which punches a caller specified hole into a runlist. 2005-09-08 20:26:34 +01:00
super.c [PATCH] VFS: Permit filesystem to perform statfs with a known root dentry 2006-06-23 07:42:45 -07:00
sysctl.c NTFS: - Add disable_sparse mount option together with a per volume sparse 2005-05-05 10:53:01 +01:00
sysctl.h [PATCH] turn many #if $undefined_string into #ifdef $undefined_string 2005-07-27 16:26:08 -07:00
time.h NTFS: Change time to u64 in time.h::ntfs2utc() as it otherwise generates a 2005-05-05 11:01:13 +01:00
types.h NTFS: Stamp the transaction log ($UsnJrnl), aka user space journal, if it 2005-06-25 15:28:56 +01:00
unistr.c NTFS: Limit name length in fs/ntfs/unistr.c::ntfs_nlstoucs() to maximum 2006-03-23 16:05:11 +00:00
upcase.c NTFS: Do more detailed reporting of why we cannot mount read-write by 2006-02-24 10:48:14 +00:00
usnjrnl.c NTFS: Stamp the transaction log ($UsnJrnl), aka user space journal, if it 2005-06-25 15:28:56 +01:00
usnjrnl.h NTFS: Stamp the transaction log ($UsnJrnl), aka user space journal, if it 2005-06-25 15:28:56 +01:00
volume.h NTFS: Do more detailed reporting of why we cannot mount read-write by 2006-02-24 10:48:14 +00:00