diff options
author | mckusick <mckusick@FreeBSD.org> | 2000-03-15 07:18:15 +0000 |
---|---|---|
committer | mckusick <mckusick@FreeBSD.org> | 2000-03-15 07:18:15 +0000 |
commit | 5ce14e7844c41cb937305222fc007b540271f1bb (patch) | |
tree | 36d1867493a02631c715f3013fa5540ceac4fa42 /sys/ufs/ufs | |
parent | acdd0d6f535796a21982b0df6183c2a5b350906a (diff) | |
download | FreeBSD-src-5ce14e7844c41cb937305222fc007b540271f1bb.zip FreeBSD-src-5ce14e7844c41cb937305222fc007b540271f1bb.tar.gz |
Bug fixes for currently harmless bugs that could rise to bite
the unwary if the code were called in slightly different ways.
1) In ufs_bmaparray() the code for calculating 'runb' will stop one block
short of the first entry in an indirect block. i.e. if an indirect block
contains N block numbers b[0]..b[N-1] then the code will never check if
b[0] and b[1] are sequential. For reference, compare with the equivalent
code that deals with direct blocks.
2) In ufs_lookup() there is an off-by-one error in the test that checks
if dp->i_diroff is outside the range of the the current directory size.
This is completely harmless, since the following while-loop condition
'dp->i_offset < endsearch' is never met, so the code immediately
does a second pass starting at dp->i_offset = 0.
3) Again in ufs_lookup(), the condition in a sanity check is wrong
for directories that are longer than one block. This bug means that
the sanity check is only effective for small directories.
Submitted by: Ian Dowse <iedowse@maths.tcd.ie>
Diffstat (limited to 'sys/ufs/ufs')
-rw-r--r-- | sys/ufs/ufs/ufs_bmap.c | 2 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_lookup.c | 6 |
2 files changed, 4 insertions, 4 deletions
diff --git a/sys/ufs/ufs/ufs_bmap.c b/sys/ufs/ufs/ufs_bmap.c index 14ef56e..57cef46 100644 --- a/sys/ufs/ufs/ufs_bmap.c +++ b/sys/ufs/ufs/ufs_bmap.c @@ -214,7 +214,7 @@ ufs_bmaparray(vp, bn, bnp, ap, nump, runp, runb) ++bn, ++*runp); bn = xap->in_off; if (runb && bn) { - for(--bn; bn > 0 && *runb < maxrun && + for(--bn; bn >= 0 && *runb < maxrun && is_sequential(ump, ((daddr_t *)bp->b_data)[bn], ((daddr_t *)bp->b_data)[bn+1]); --bn, ++*runb); diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c index a5be8e7..11f2ae4 100644 --- a/sys/ufs/ufs/ufs_lookup.c +++ b/sys/ufs/ufs/ufs_lookup.c @@ -192,7 +192,7 @@ ufs_lookup(ap) */ bmask = VFSTOUFS(vdp->v_mount)->um_mountp->mnt_stat.f_iosize - 1; if (nameiop != LOOKUP || dp->i_diroff == 0 || - dp->i_diroff > dp->i_size) { + dp->i_diroff >= dp->i_size) { entryoffsetinblock = 0; dp->i_offset = 0; numdirpasses = 1; @@ -411,9 +411,9 @@ found: * Check that directory length properly reflects presence * of this entry. */ - if (entryoffsetinblock + DIRSIZ(OFSFMT(vdp), ep) > dp->i_size) { + if (dp->i_offset + DIRSIZ(OFSFMT(vdp), ep) > dp->i_size) { ufs_dirbad(dp, dp->i_offset, "i_size too small"); - dp->i_size = entryoffsetinblock + DIRSIZ(OFSFMT(vdp), ep); + dp->i_size = dp->i_offset + DIRSIZ(OFSFMT(vdp), ep); dp->i_flag |= IN_CHANGE | IN_UPDATE; } brelse(bp); |