aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDoug Graham <dgraham@nortel.com>2009-09-22 19:48:00 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-23 10:39:57 -0400
commit9f6c1333938c5d93da8be8f29f3b5469a3c00f95 (patch)
treea0fdd0e3baffa1a997eb39f780b893337921a1d4 /fs
parent532f649f148bf70e6a5816d95fe55e6a065e8754 (diff)
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>
Diffstat (limited to 'fs')
-rw-r--r--fs/minix/dir.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/fs/minix/dir.c b/fs/minix/dir.c
index d407e7a0b6fe..6198731d7fcd 100644
--- a/fs/minix/dir.c
+++ b/fs/minix/dir.c
@@ -308,14 +308,18 @@ int minix_delete_entry(struct minix_dir_entry *de, struct page *page)
308 struct inode *inode = (struct inode*)mapping->host; 308 struct inode *inode = (struct inode*)mapping->host;
309 char *kaddr = page_address(page); 309 char *kaddr = page_address(page);
310 loff_t pos = page_offset(page) + (char*)de - kaddr; 310 loff_t pos = page_offset(page) + (char*)de - kaddr;
311 unsigned len = minix_sb(inode->i_sb)->s_dirsize; 311 struct minix_sb_info *sbi = minix_sb(inode->i_sb);
312 unsigned len = sbi->s_dirsize;
312 int err; 313 int err;
313 314
314 lock_page(page); 315 lock_page(page);
315 err = __minix_write_begin(NULL, mapping, pos, len, 316 err = __minix_write_begin(NULL, mapping, pos, len,
316 AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); 317 AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
317 if (err == 0) { 318 if (err == 0) {
318 de->inode = 0; 319 if (sbi->s_version == MINIX_V3)
320 ((minix3_dirent *) de)->inode = 0;
321 else
322 de->inode = 0;
319 err = dir_commit_chunk(page, pos, len); 323 err = dir_commit_chunk(page, pos, len);
320 } else { 324 } else {
321 unlock_page(page); 325 unlock_page(page);
@@ -440,7 +444,10 @@ void minix_set_link(struct minix_dir_entry *de, struct page *page,
440 err = __minix_write_begin(NULL, mapping, pos, sbi->s_dirsize, 444 err = __minix_write_begin(NULL, mapping, pos, sbi->s_dirsize,
441 AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); 445 AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
442 if (err == 0) { 446 if (err == 0) {
443 de->inode = inode->i_ino; 447 if (sbi->s_version == MINIX_V3)
448 ((minix3_dirent *) de)->inode = inode->i_ino;
449 else
450 de->inode = inode->i_ino;
444 err = dir_commit_chunk(page, pos, sbi->s_dirsize); 451 err = dir_commit_chunk(page, pos, sbi->s_dirsize);
445 } else { 452 } else {
446 unlock_page(page); 453 unlock_page(page);
@@ -470,7 +477,14 @@ ino_t minix_inode_by_name(struct dentry *dentry)
470 ino_t res = 0; 477 ino_t res = 0;
471 478
472 if (de) { 479 if (de) {
473 res = de->inode; 480 struct address_space *mapping = page->mapping;
481 struct inode *inode = mapping->host;
482 struct minix_sb_info *sbi = minix_sb(inode->i_sb);
483
484 if (sbi->s_version == MINIX_V3)
485 res = ((minix3_dirent *) de)->inode;
486 else
487 res = de->inode;
474 dir_put_page(page); 488 dir_put_page(page);
475 } 489 }
476 return res; 490 return res;