Commit e37a41af authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] bfs filesystem read past the end of dir

From: Jakub Jermar <jermar@itbs.cz>

I found out that BFS filesystem will eventually try to read and interpret
garbage past the end of directory in bfs_add_entry().  If the garbage
(interpreted as i-node number) is not set to zero (does it have to be?)
bfs_add_entry() will consider it a regular directory entry. 

This causes weird things like this:
# touch a
# rm a
# ls
# touch b
# ls
a

My patch detects an attempt to read past the end of directory and explicitly
clears the garbage that represents i-node number.  Thus the correct behaviour
is achieved.

(was unable to contact Tigran)
parent 28d627fb
...@@ -274,7 +274,7 @@ static int bfs_add_entry(struct inode * dir, const char * name, int namelen, int ...@@ -274,7 +274,7 @@ static int bfs_add_entry(struct inode * dir, const char * name, int namelen, int
{ {
struct buffer_head * bh; struct buffer_head * bh;
struct bfs_dirent * de; struct bfs_dirent * de;
int block, sblock, eblock, off; int block, sblock, eblock, off, eoff;
int i; int i;
dprintf("name=%s, namelen=%d\n", name, namelen); dprintf("name=%s, namelen=%d\n", name, namelen);
...@@ -286,12 +286,17 @@ static int bfs_add_entry(struct inode * dir, const char * name, int namelen, int ...@@ -286,12 +286,17 @@ static int bfs_add_entry(struct inode * dir, const char * name, int namelen, int
sblock = BFS_I(dir)->i_sblock; sblock = BFS_I(dir)->i_sblock;
eblock = BFS_I(dir)->i_eblock; eblock = BFS_I(dir)->i_eblock;
eoff = dir->i_size % BFS_BSIZE;
for (block=sblock; block<=eblock; block++) { for (block=sblock; block<=eblock; block++) {
bh = sb_bread(dir->i_sb, block); bh = sb_bread(dir->i_sb, block);
if(!bh) if(!bh)
return -ENOSPC; return -ENOSPC;
for (off=0; off<BFS_BSIZE; off+=BFS_DIRENT_SIZE) { for (off=0; off<BFS_BSIZE; off+=BFS_DIRENT_SIZE) {
de = (struct bfs_dirent *)(bh->b_data + off); de = (struct bfs_dirent *)(bh->b_data + off);
if (block==eblock && off>=eoff) {
/* Do not read/interpret the garbage in the end of eblock. */
de->ino = 0;
}
if (!de->ino) { if (!de->ino) {
if ((block-sblock)*BFS_BSIZE + off >= dir->i_size) { if ((block-sblock)*BFS_BSIZE + off >= dir->i_size) {
dir->i_size += BFS_DIRENT_SIZE; dir->i_size += BFS_DIRENT_SIZE;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment