Commit 9f6c1333938c5d93da8be8f29f3b5469a3c00f95

Authored by Doug Graham
Committed by Linus Torvalds
1 parent 532f649f14

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>

Showing 1 changed file with 18 additions and 4 deletions Side-by-side Diff

... ... @@ -308,14 +308,18 @@
308 308 struct inode *inode = (struct inode*)mapping->host;
309 309 char *kaddr = page_address(page);
310 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 313 int err;
313 314  
314 315 lock_page(page);
315 316 err = __minix_write_begin(NULL, mapping, pos, len,
316 317 AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
317 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 323 err = dir_commit_chunk(page, pos, len);
320 324 } else {
321 325 unlock_page(page);
... ... @@ -440,7 +444,10 @@
440 444 err = __minix_write_begin(NULL, mapping, pos, sbi->s_dirsize,
441 445 AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
442 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 451 err = dir_commit_chunk(page, pos, sbi->s_dirsize);
445 452 } else {
446 453 unlock_page(page);
... ... @@ -470,7 +477,14 @@
470 477 ino_t res = 0;
471 478  
472 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 488 dir_put_page(page);
475 489 }
476 490 return res;