forked from Minki/linux
V3 minixfs: add missing directory type checking
There are a few places in the Minix FS code where the "inode" field of a minix_dir_entry is used without checking first to see if the dirent is really a minix3_dir_entry. The inode number in a V1/V2 dirent is 16 bits, whereas that in a V3 dirent is 32 bits. Accessing it as a 16 bit field when it really should be accessed as a 32 bit field probably kinda sorta works on a little-endian machine, but leads to some rather odd behaviour on big-endian machines. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Doug Graham <dgraham@nortel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
532f649f14
commit
9f6c133393
@ -308,14 +308,18 @@ int minix_delete_entry(struct minix_dir_entry *de, struct page *page)
|
||||
struct inode *inode = (struct inode*)mapping->host;
|
||||
char *kaddr = page_address(page);
|
||||
loff_t pos = page_offset(page) + (char*)de - kaddr;
|
||||
unsigned len = minix_sb(inode->i_sb)->s_dirsize;
|
||||
struct minix_sb_info *sbi = minix_sb(inode->i_sb);
|
||||
unsigned len = sbi->s_dirsize;
|
||||
int err;
|
||||
|
||||
lock_page(page);
|
||||
err = __minix_write_begin(NULL, mapping, pos, len,
|
||||
AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
|
||||
if (err == 0) {
|
||||
de->inode = 0;
|
||||
if (sbi->s_version == MINIX_V3)
|
||||
((minix3_dirent *) de)->inode = 0;
|
||||
else
|
||||
de->inode = 0;
|
||||
err = dir_commit_chunk(page, pos, len);
|
||||
} else {
|
||||
unlock_page(page);
|
||||
@ -440,7 +444,10 @@ void minix_set_link(struct minix_dir_entry *de, struct page *page,
|
||||
err = __minix_write_begin(NULL, mapping, pos, sbi->s_dirsize,
|
||||
AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
|
||||
if (err == 0) {
|
||||
de->inode = inode->i_ino;
|
||||
if (sbi->s_version == MINIX_V3)
|
||||
((minix3_dirent *) de)->inode = inode->i_ino;
|
||||
else
|
||||
de->inode = inode->i_ino;
|
||||
err = dir_commit_chunk(page, pos, sbi->s_dirsize);
|
||||
} else {
|
||||
unlock_page(page);
|
||||
@ -470,7 +477,14 @@ ino_t minix_inode_by_name(struct dentry *dentry)
|
||||
ino_t res = 0;
|
||||
|
||||
if (de) {
|
||||
res = de->inode;
|
||||
struct address_space *mapping = page->mapping;
|
||||
struct inode *inode = mapping->host;
|
||||
struct minix_sb_info *sbi = minix_sb(inode->i_sb);
|
||||
|
||||
if (sbi->s_version == MINIX_V3)
|
||||
res = ((minix3_dirent *) de)->inode;
|
||||
else
|
||||
res = de->inode;
|
||||
dir_put_page(page);
|
||||
}
|
||||
return res;
|
||||
|
Loading…
Reference in New Issue
Block a user