svn commit: r247211 - stable/9/sys/ufs/ffs
Konstantin Belousov
kib at FreeBSD.org
Sun Feb 24 05:49:00 UTC 2013
Author: kib
Date: Sun Feb 24 05:48:59 2013
New Revision: 247211
URL: http://svnweb.freebsd.org/changeset/base/247211
Log:
MFC r246612:
Fix several unsafe pointer dereferences in the buffered_write() function.
Modified:
stable/9/sys/ufs/ffs/ffs_alloc.c
Directory Properties:
stable/9/sys/ (props changed)
Modified: stable/9/sys/ufs/ffs/ffs_alloc.c
==============================================================================
--- stable/9/sys/ufs/ffs/ffs_alloc.c Sun Feb 24 03:15:43 2013 (r247210)
+++ stable/9/sys/ufs/ffs/ffs_alloc.c Sun Feb 24 05:48:59 2013 (r247211)
@@ -2853,10 +2853,11 @@ buffered_write(fp, uio, active_cred, fla
int flags;
struct thread *td;
{
- struct vnode *devvp;
+ struct vnode *devvp, *vp;
struct inode *ip;
struct buf *bp;
struct fs *fs;
+ struct filedesc *fdp;
int error, vfslocked;
daddr_t lbn;
@@ -2867,12 +2868,34 @@ buffered_write(fp, uio, active_cred, fla
* within the filesystem being written. Yes, this is an ugly hack.
*/
devvp = fp->f_vnode;
- ip = VTOI(td->td_proc->p_fd->fd_cdir);
- if (ip->i_devvp != devvp)
+ if (!vn_isdisk(devvp, NULL))
return (EINVAL);
+ fdp = td->td_proc->p_fd;
+ FILEDESC_SLOCK(fdp);
+ vp = fdp->fd_cdir;
+ vref(vp);
+ FILEDESC_SUNLOCK(fdp);
+ vfslocked = VFS_LOCK_GIANT(vp->v_mount);
+ vn_lock(vp, LK_SHARED | LK_RETRY);
+ /*
+ * Check that the current directory vnode indeed belongs to
+ * UFS before trying to dereference UFS-specific v_data fields.
+ */
+ if (vp->v_op != &ffs_vnodeops1 && vp->v_op != &ffs_vnodeops2) {
+ vput(vp);
+ VFS_UNLOCK_GIANT(vfslocked);
+ return (EINVAL);
+ }
+ ip = VTOI(vp);
+ if (ip->i_devvp != devvp) {
+ vput(vp);
+ VFS_UNLOCK_GIANT(vfslocked);
+ return (EINVAL);
+ }
fs = ip->i_fs;
+ vput(vp);
+ VFS_UNLOCK_GIANT(vfslocked);
foffset_lock_uio(fp, uio, flags);
- vfslocked = VFS_LOCK_GIANT(ip->i_vnode->v_mount);
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
#ifdef DEBUG
if (fsckcmds) {
@@ -2900,7 +2923,6 @@ buffered_write(fp, uio, active_cred, fla
error = bwrite(bp);
out:
VOP_UNLOCK(devvp, 0);
- VFS_UNLOCK_GIANT(vfslocked);
foffset_unlock_uio(fp, uio, flags | FOF_NEXTOFF);
return (error);
}
More information about the svn-src-stable-9
mailing list