Commit 1046d880 authored by David Woodhouse's avatar David Woodhouse

[JFFS2] Check CRC32 on dirent and data nodes each time they're read

Also, make sure dirents are marked REF_UNCHECKED when we 'discover' them
through eraseblock summary.
Signed-off-by: default avatarDavid Woodhouse <dwmw2@infradead.org>
parent fc6612f6
...@@ -116,19 +116,42 @@ static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_r ...@@ -116,19 +116,42 @@ static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_r
uint32_t *latest_mctime, uint32_t *mctime_ver) uint32_t *latest_mctime, uint32_t *mctime_ver)
{ {
struct jffs2_full_dirent *fd; struct jffs2_full_dirent *fd;
uint32_t crc;
/* The direntry nodes are checked during the flash scanning */
BUG_ON(ref_flags(ref) == REF_UNCHECKED);
/* Obsoleted. This cannot happen, surely? dwmw2 20020308 */ /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
BUG_ON(ref_obsolete(ref)); BUG_ON(ref_obsolete(ref));
/* Sanity check */ crc = crc32(0, rd, sizeof(*rd) - 8);
if (unlikely(PAD((rd->nsize + sizeof(*rd))) != PAD(je32_to_cpu(rd->totlen)))) { if (unlikely(crc != je32_to_cpu(rd->node_crc))) {
JFFS2_ERROR("illegal nsize in node at %#08x: nsize %#02x, totlen %#04x\n", JFFS2_NOTICE("header CRC failed on dirent node at %#08x: read %#08x, calculated %#08x\n",
ref_offset(ref), rd->nsize, je32_to_cpu(rd->totlen)); ref_offset(ref), je32_to_cpu(rd->node_crc), crc);
return 1; return 1;
} }
/* If we've never checked the CRCs on this node, check them now */
if (ref_flags(ref) == REF_UNCHECKED) {
struct jffs2_eraseblock *jeb;
int len;
/* Sanity check */
if (unlikely(PAD((rd->nsize + sizeof(*rd))) != PAD(je32_to_cpu(rd->totlen)))) {
JFFS2_ERROR("illegal nsize in node at %#08x: nsize %#02x, totlen %#04x\n",
ref_offset(ref), rd->nsize, je32_to_cpu(rd->totlen));
return 1;
}
jeb = &c->blocks[ref->flash_offset / c->sector_size];
len = ref_totlen(c, jeb, ref);
spin_lock(&c->erase_completion_lock);
jeb->used_size += len;
jeb->unchecked_size -= len;
c->used_size += len;
c->unchecked_size -= len;
ref->flash_offset = ref_offset(ref) | REF_PRISTINE;
spin_unlock(&c->erase_completion_lock);
}
fd = jffs2_alloc_full_dirent(rd->nsize + 1); fd = jffs2_alloc_full_dirent(rd->nsize + 1);
if (unlikely(!fd)) if (unlikely(!fd))
return -ENOMEM; return -ENOMEM;
...@@ -198,10 +221,18 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref ...@@ -198,10 +221,18 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
struct jffs2_tmp_dnode_info *tn; struct jffs2_tmp_dnode_info *tn;
uint32_t len, csize; uint32_t len, csize;
int ret = 1; int ret = 1;
uint32_t crc;
/* Obsoleted. This cannot happen, surely? dwmw2 20020308 */ /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
BUG_ON(ref_obsolete(ref)); BUG_ON(ref_obsolete(ref));
crc = crc32(0, rd, sizeof(*rd) - 8);
if (unlikely(crc != je32_to_cpu(rd->node_crc))) {
JFFS2_NOTICE("node CRC failed on dnode at %#08x: read %#08x, calculated %#08x\n",
ref_offset(ref), je32_to_cpu(rd->node_crc), crc);
return 1;
}
tn = jffs2_alloc_tmp_dnode_info(); tn = jffs2_alloc_tmp_dnode_info();
if (!tn) { if (!tn) {
JFFS2_ERROR("failed to allocate tn (%zu bytes).\n", sizeof(*tn)); JFFS2_ERROR("failed to allocate tn (%zu bytes).\n", sizeof(*tn));
...@@ -213,14 +244,6 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref ...@@ -213,14 +244,6 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
/* If we've never checked the CRCs on this node, check them now */ /* If we've never checked the CRCs on this node, check them now */
if (ref_flags(ref) == REF_UNCHECKED) { if (ref_flags(ref) == REF_UNCHECKED) {
uint32_t crc;
crc = crc32(0, rd, sizeof(*rd) - 8);
if (unlikely(crc != je32_to_cpu(rd->node_crc))) {
JFFS2_NOTICE("header CRC failed on node at %#08x: read %#08x, calculated %#08x\n",
ref_offset(ref), je32_to_cpu(rd->node_crc), crc);
goto free_out;
}
/* Sanity checks */ /* Sanity checks */
if (unlikely(je32_to_cpu(rd->offset) > je32_to_cpu(rd->isize)) || if (unlikely(je32_to_cpu(rd->offset) > je32_to_cpu(rd->isize)) ||
......
...@@ -453,7 +453,7 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras ...@@ -453,7 +453,7 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
return -ENOMEM; return -ENOMEM;
} }
fd->raw = sum_link_node_ref(c, jeb, je32_to_cpu(spd->offset) | REF_PRISTINE, fd->raw = sum_link_node_ref(c, jeb, je32_to_cpu(spd->offset) | REF_UNCHECKED,
PAD(je32_to_cpu(spd->totlen)), ic); PAD(je32_to_cpu(spd->totlen)), ic);
fd->next = NULL; fd->next = NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment