[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: David Woodhouse <dwmw2@infradead.org>
This commit is contained in:
parent
fc6612f627
commit
1046d88001
|
@ -116,12 +116,23 @@ 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));
|
||||||
|
|
||||||
|
crc = crc32(0, rd, sizeof(*rd) - 8);
|
||||||
|
if (unlikely(crc != je32_to_cpu(rd->node_crc))) {
|
||||||
|
JFFS2_NOTICE("header CRC failed on dirent node at %#08x: read %#08x, calculated %#08x\n",
|
||||||
|
ref_offset(ref), je32_to_cpu(rd->node_crc), crc);
|
||||||
|
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 */
|
/* Sanity check */
|
||||||
if (unlikely(PAD((rd->nsize + sizeof(*rd))) != PAD(je32_to_cpu(rd->totlen)))) {
|
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",
|
JFFS2_ERROR("illegal nsize in node at %#08x: nsize %#02x, totlen %#04x\n",
|
||||||
|
@ -129,6 +140,18 @@ static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_r
|
||||||
return 1;
|
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
|
||||||
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
|
||||||
|
|
||||||
/* 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
|
||||||
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;
|
||||||
|
|
Loading…
Reference in a new issue