aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2013-09-12 09:31:39 -0400
committerJ. Bruce Fields <bfields@redhat.com>2013-10-29 17:43:52 -0400
commit49e7372063a220651b4f12fa46113559533cafee (patch)
tree5646b5f1a30977b5e31313d47973695662245b9c /fs/nfsd
parent956c4fee446c568ad102625da931e259f22c67ee (diff)
nfsd: fh_update should error out in unexpected cases
The reporter saw a NULL dereference when a filesystem's ->mknod returned success but left the dentry negative, and then nfsd tried to dereference d_inode (in this case because the CREATE was followed by a GETATTR in the same nfsv4 compound). fh_update already checks for this and another broken case, but for some reason it returns success and leaves nfsd trying to soldier on. If it failed we'd avoid the crash. There's only so much we can do with a buggy filesystem, but it's easy enough to bail out here, so let's do that. Reported-by: Antti Tönkyrä <daedalus@pingtimeout.net> Tested-by: Antti Tönkyrä <daedalus@pingtimeout.net> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/nfsfh.c8
1 files changed, 3 insertions, 5 deletions
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 3d0e15ae6f72..3c37b160dcad 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -598,22 +598,20 @@ fh_update(struct svc_fh *fhp)
598 _fh_update_old(dentry, fhp->fh_export, &fhp->fh_handle); 598 _fh_update_old(dentry, fhp->fh_export, &fhp->fh_handle);
599 } else { 599 } else {
600 if (fhp->fh_handle.fh_fileid_type != FILEID_ROOT) 600 if (fhp->fh_handle.fh_fileid_type != FILEID_ROOT)
601 goto out; 601 return 0;
602 602
603 _fh_update(fhp, fhp->fh_export, dentry); 603 _fh_update(fhp, fhp->fh_export, dentry);
604 if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID) 604 if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID)
605 return nfserr_opnotsupp; 605 return nfserr_opnotsupp;
606 } 606 }
607out:
608 return 0; 607 return 0;
609
610out_bad: 608out_bad:
611 printk(KERN_ERR "fh_update: fh not verified!\n"); 609 printk(KERN_ERR "fh_update: fh not verified!\n");
612 goto out; 610 return nfserr_serverfault;
613out_negative: 611out_negative:
614 printk(KERN_ERR "fh_update: %pd2 still negative!\n", 612 printk(KERN_ERR "fh_update: %pd2 still negative!\n",
615 dentry); 613 dentry);
616 goto out; 614 return nfserr_serverfault;
617} 615}
618 616
619/* 617/*