diff options
author | David Woodhouse <dwmw2@infradead.org> | 2007-03-09 06:44:00 -0500 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2007-03-09 06:44:00 -0500 |
commit | c7258a4477b5ed0243c28ec107b98bb946757448 (patch) | |
tree | c1b3bce6ea3567ac7e23241ec13a2c4a40972b0f /fs/jffs2 | |
parent | 470bc844361b238bcbe6a07ba47d51fca25f2742 (diff) |
[JFFS2] Check for all-zero node headers
Due to a poor choice of CRC32 seed, a node header which is all zeroes
would pass the CRC32 check. Explicitly check for this case, and treat it
as we do a CRC failure.
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'fs/jffs2')
-rw-r--r-- | fs/jffs2/readinode.c | 16 | ||||
-rw-r--r-- | fs/jffs2/scan.c | 9 |
2 files changed, 24 insertions, 1 deletions
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index 58a0b912e9d0..717a48cf7df2 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c | |||
@@ -373,7 +373,14 @@ free_out: | |||
373 | static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, struct jffs2_unknown_node *un) | 373 | static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, struct jffs2_unknown_node *un) |
374 | { | 374 | { |
375 | /* We don't mark unknown nodes as REF_UNCHECKED */ | 375 | /* We don't mark unknown nodes as REF_UNCHECKED */ |
376 | BUG_ON(ref_flags(ref) == REF_UNCHECKED); | 376 | if (ref_flags(ref) == REF_UNCHECKED) { |
377 | JFFS2_ERROR("REF_UNCHECKED but unknown node at %#08x\n", | ||
378 | ref_offset(ref)); | ||
379 | JFFS2_ERROR("Node is {%04x,%04x,%08x,%08x}. Please report this error.\n", | ||
380 | je16_to_cpu(un->magic), je16_to_cpu(un->nodetype), | ||
381 | je32_to_cpu(un->totlen), je32_to_cpu(un->hdr_crc)); | ||
382 | return 1; | ||
383 | } | ||
377 | 384 | ||
378 | un->nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(un->nodetype)); | 385 | un->nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(un->nodetype)); |
379 | 386 | ||
@@ -576,6 +583,13 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf | |||
576 | jffs2_mark_node_obsolete(c, ref); | 583 | jffs2_mark_node_obsolete(c, ref); |
577 | goto cont; | 584 | goto cont; |
578 | } | 585 | } |
586 | /* Due to poor choice of crc32 seed, an all-zero node will have a correct CRC */ | ||
587 | if (!je32_to_cpu(node->u.hdr_crc) && !je16_to_cpu(node->u.nodetype) && | ||
588 | !je16_to_cpu(node->u.magic) && !je32_to_cpu(node->u.totlen)) { | ||
589 | JFFS2_NOTICE("All zero node header at %#08x.\n", ref_offset(ref)); | ||
590 | jffs2_mark_node_obsolete(c, ref); | ||
591 | goto cont; | ||
592 | } | ||
579 | 593 | ||
580 | switch (je16_to_cpu(node->u.nodetype)) { | 594 | switch (je16_to_cpu(node->u.nodetype)) { |
581 | 595 | ||
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c index 31c1475d922a..7fb45bd4915c 100644 --- a/fs/jffs2/scan.c +++ b/fs/jffs2/scan.c | |||
@@ -734,6 +734,15 @@ scan_more: | |||
734 | ofs += 4; | 734 | ofs += 4; |
735 | continue; | 735 | continue; |
736 | } | 736 | } |
737 | /* Due to poor choice of crc32 seed, an all-zero node will have a correct CRC */ | ||
738 | if (!je32_to_cpu(node->hdr_crc) && !je16_to_cpu(node->nodetype) && | ||
739 | !je16_to_cpu(node->magic) && !je32_to_cpu(node->totlen)) { | ||
740 | noisy_printk(&noise, "jffs2_scan_eraseblock(): All zero node header at 0x%08x.\n", ofs); | ||
741 | if ((err = jffs2_scan_dirty_space(c, jeb, 4))) | ||
742 | return err; | ||
743 | ofs += 4; | ||
744 | continue; | ||
745 | } | ||
737 | 746 | ||
738 | if (ofs + je32_to_cpu(node->totlen) > | 747 | if (ofs + je32_to_cpu(node->totlen) > |
739 | jeb->offset + c->sector_size) { | 748 | jeb->offset + c->sector_size) { |