diff options
author | dillon <dillon@FreeBSD.org> | 2000-12-17 23:57:05 +0000 |
---|---|---|
committer | dillon <dillon@FreeBSD.org> | 2000-12-17 23:57:05 +0000 |
commit | 69242be380386045f137192707e6c38be6c2dde4 (patch) | |
tree | 23fde77258079844ec411e103362a6eaf26bb780 /sys | |
parent | 50b480af640ec7a7a0fabc8becf398da5c3e87fc (diff) | |
download | FreeBSD-src-69242be380386045f137192707e6c38be6c2dde4.zip FreeBSD-src-69242be380386045f137192707e6c38be6c2dde4.tar.gz |
Avoid a data-consistency race between write() and mmap()
by ensuring that newly allocated blocks are zerod. The
race can occur even in the case where the write covers
the entire block.
Reported by: Sven Berkvens <sven@berkvens.net>, Marc Olzheim <zlo@zlo.nu>
Diffstat (limited to 'sys')
-rw-r--r-- | sys/gnu/ext2fs/ext2_readwrite.c | 9 | ||||
-rw-r--r-- | sys/gnu/fs/ext2fs/ext2_readwrite.c | 9 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_readwrite.c | 9 |
3 files changed, 27 insertions, 0 deletions
diff --git a/sys/gnu/ext2fs/ext2_readwrite.c b/sys/gnu/ext2fs/ext2_readwrite.c index f054a6e..30a2f56 100644 --- a/sys/gnu/ext2fs/ext2_readwrite.c +++ b/sys/gnu/ext2fs/ext2_readwrite.c @@ -238,10 +238,19 @@ WRITE(ap) if (uio->uio_offset + xfersize > ip->i_size) vnode_pager_setsize(vp, uio->uio_offset + xfersize); + /* + * Avoid a data-consistency race between write() and mmap() + * by ensuring that newly allocated blocks are zerod. The + * race can occur even in the case where the write covers + * the entire block. + */ + flags |= B_CLRBUF; +#if 0 if (fs->s_frag_size > xfersize) flags |= B_CLRBUF; else flags &= ~B_CLRBUF; +#endif error = ext2_balloc(ip, lbn, blkoffset + xfersize, ap->a_cred, &bp, flags); diff --git a/sys/gnu/fs/ext2fs/ext2_readwrite.c b/sys/gnu/fs/ext2fs/ext2_readwrite.c index f054a6e..30a2f56 100644 --- a/sys/gnu/fs/ext2fs/ext2_readwrite.c +++ b/sys/gnu/fs/ext2fs/ext2_readwrite.c @@ -238,10 +238,19 @@ WRITE(ap) if (uio->uio_offset + xfersize > ip->i_size) vnode_pager_setsize(vp, uio->uio_offset + xfersize); + /* + * Avoid a data-consistency race between write() and mmap() + * by ensuring that newly allocated blocks are zerod. The + * race can occur even in the case where the write covers + * the entire block. + */ + flags |= B_CLRBUF; +#if 0 if (fs->s_frag_size > xfersize) flags |= B_CLRBUF; else flags &= ~B_CLRBUF; +#endif error = ext2_balloc(ip, lbn, blkoffset + xfersize, ap->a_cred, &bp, flags); diff --git a/sys/ufs/ufs/ufs_readwrite.c b/sys/ufs/ufs/ufs_readwrite.c index 4830120..e1d775c 100644 --- a/sys/ufs/ufs/ufs_readwrite.c +++ b/sys/ufs/ufs/ufs_readwrite.c @@ -468,10 +468,19 @@ WRITE(ap) if (uio->uio_offset + xfersize > ip->i_size) vnode_pager_setsize(vp, uio->uio_offset + xfersize); + /* + * Avoid a data-consistency race between write() and mmap() + * by ensuring that newly allocated blocks are zerod. The + * race can occur even in the case where the write covers + * the entire block. + */ + flags |= B_CLRBUF; +#if 0 if (fs->fs_bsize > xfersize) flags |= B_CLRBUF; else flags &= ~B_CLRBUF; +#endif /* XXX is uio->uio_offset the right thing here? */ error = VOP_BALLOC(vp, uio->uio_offset, xfersize, ap->a_cred, flags, &bp); |