summaryrefslogtreecommitdiffstats
path: root/sys/ufs/ffs/ffs_alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/ufs/ffs/ffs_alloc.c')
-rw-r--r--sys/ufs/ffs/ffs_alloc.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c
index 5ad5775..d462cbb 100644
--- a/sys/ufs/ffs/ffs_alloc.c
+++ b/sys/ufs/ffs/ffs_alloc.c
@@ -2906,10 +2906,11 @@ buffered_write(fp, uio, active_cred, flags, td)
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;
daddr_t lbn;
@@ -2920,10 +2921,29 @@ buffered_write(fp, uio, active_cred, flags, td)
* 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);
+ 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);
return (EINVAL);
+ }
+ ip = VTOI(vp);
+ if (ip->i_devvp != devvp) {
+ vput(vp);
+ return (EINVAL);
+ }
fs = ip->i_fs;
+ vput(vp);
foffset_lock_uio(fp, uio, flags);
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
#ifdef DEBUG
OpenPOWER on IntegriCloud