fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / fs / hpfs / map.c
index 8f21356..c472458 100644 (file)
@@ -126,32 +126,40 @@ struct fnode *hpfs_map_fnode(struct super_block *s, ino_t ino, struct buffer_hea
                        struct extended_attribute *ea;
                        struct extended_attribute *ea_end;
                        if (fnode->magic != FNODE_MAGIC) {
-                               hpfs_error(s, "bad magic on fnode %08x", ino);
+                               hpfs_error(s, "bad magic on fnode %08lx",
+                                       (unsigned long)ino);
                                goto bail;
                        }
                        if (!fnode->dirflag) {
                                if ((unsigned)fnode->btree.n_used_nodes + (unsigned)fnode->btree.n_free_nodes !=
                                    (fnode->btree.internal ? 12 : 8)) {
-                                       hpfs_error(s, "bad number of nodes in fnode %08x", ino);
+                                       hpfs_error(s,
+                                          "bad number of nodes in fnode %08lx",
+                                           (unsigned long)ino);
                                        goto bail;
                                }
                                if (fnode->btree.first_free !=
                                    8 + fnode->btree.n_used_nodes * (fnode->btree.internal ? 8 : 12)) {
-                                       hpfs_error(s, "bad first_free pointer in fnode %08x", ino);
+                                       hpfs_error(s,
+                                           "bad first_free pointer in fnode %08lx",
+                                           (unsigned long)ino);
                                        goto bail;
                                }
                        }
                        if (fnode->ea_size_s && ((signed int)fnode->ea_offs < 0xc4 ||
-                          (signed int)fnode->ea_offs + fnode->ea_size_s > 0x200)) {
-                               hpfs_error(s, "bad EA info in fnode %08x: ea_offs == %04x ea_size_s == %04x",
-                                       ino, fnode->ea_offs, fnode->ea_size_s);
+                          (signed int)fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s > 0x200)) {
+                               hpfs_error(s,
+                                       "bad EA info in fnode %08lx: ea_offs == %04x ea_size_s == %04x",
+                                       (unsigned long)ino,
+                                       fnode->ea_offs, fnode->ea_size_s);
                                goto bail;
                        }
                        ea = fnode_ea(fnode);
                        ea_end = fnode_end_ea(fnode);
                        while (ea != ea_end) {
                                if (ea > ea_end) {
-                                       hpfs_error(s, "bad EA in fnode %08x", ino);
+                                       hpfs_error(s, "bad EA in fnode %08lx",
+                                               (unsigned long)ino);
                                        goto bail;
                                }
                                ea = next_ea(ea);
@@ -225,14 +233,16 @@ struct dnode *hpfs_map_dnode(struct super_block *s, unsigned secno,
                        }
                        for (p = 20; p < dnode->first_free; p += d[p] + (d[p+1] << 8)) {
                                struct hpfs_dirent *de = (struct hpfs_dirent *)((char *)dnode + p);
-                               if (de->length > 292 || (de->length < 32) || (de->length & 3)) {
+                               if (de->length > 292 || (de->length < 32) || (de->length & 3) || p + de->length > 2048) {
                                        hpfs_error(s, "bad dirent size in dnode %08x, dirent %03x, last %03x", secno, p, pp);
                                        goto bail;
                                }
                                if (((31 + de->namelen + de->down*4 + 3) & ~3) != de->length) {
+                                       if (((31 + de->namelen + de->down*4 + 3) & ~3) < de->length && s->s_flags & MS_RDONLY) goto ok;
                                        hpfs_error(s, "namelen does not match dirent size in dnode %08x, dirent %03x, last %03x", secno, p, pp);
                                        goto bail;
                                }
+                               ok:
                                if (hpfs_sb(s)->sb_chk >= 2) b |= 1 << de->down;
                                if (de->down) if (de_down_pointer(de) < 0x10) {
                                        hpfs_error(s, "bad down pointer in dnode %08x, dirent %03x, last %03x", secno, p, pp);