aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2006-06-18 17:44:21 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2006-06-18 17:44:21 -0400
commit1046d88001e7b8819f60dece2eaf1b44bf4b4460 (patch)
tree82a8f62e785375b2f43bbb3f2b52da60775b5b56
parentfc6612f627c697b348a4ef64f16fb373d86dbd76 (diff)
[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>
-rw-r--r--fs/jffs2/readinode.c51
-rw-r--r--fs/jffs2/summary.c2
2 files changed, 38 insertions, 15 deletions
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index 5351b34d5419..5ea4faafa2d3 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -116,19 +116,42 @@ static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_r
116 uint32_t *latest_mctime, uint32_t *mctime_ver) 116 uint32_t *latest_mctime, uint32_t *mctime_ver)
117{ 117{
118 struct jffs2_full_dirent *fd; 118 struct jffs2_full_dirent *fd;
119 uint32_t crc;
119 120
120 /* The direntry nodes are checked during the flash scanning */
121 BUG_ON(ref_flags(ref) == REF_UNCHECKED);
122 /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */ 121 /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
123 BUG_ON(ref_obsolete(ref)); 122 BUG_ON(ref_obsolete(ref));
124 123
125 /* Sanity check */ 124 crc = crc32(0, rd, sizeof(*rd) - 8);
126 if (unlikely(PAD((rd->nsize + sizeof(*rd))) != PAD(je32_to_cpu(rd->totlen)))) { 125 if (unlikely(crc != je32_to_cpu(rd->node_crc))) {
127 JFFS2_ERROR("illegal nsize in node at %#08x: nsize %#02x, totlen %#04x\n", 126 JFFS2_NOTICE("header CRC failed on dirent node at %#08x: read %#08x, calculated %#08x\n",
128 ref_offset(ref), rd->nsize, je32_to_cpu(rd->totlen)); 127 ref_offset(ref), je32_to_cpu(rd->node_crc), crc);
129 return 1; 128 return 1;
130 } 129 }
131 130
131 /* If we've never checked the CRCs on this node, check them now */
132 if (ref_flags(ref) == REF_UNCHECKED) {
133 struct jffs2_eraseblock *jeb;
134 int len;
135
136 /* Sanity check */
137 if (unlikely(PAD((rd->nsize + sizeof(*rd))) != PAD(je32_to_cpu(rd->totlen)))) {
138 JFFS2_ERROR("illegal nsize in node at %#08x: nsize %#02x, totlen %#04x\n",
139 ref_offset(ref), rd->nsize, je32_to_cpu(rd->totlen));
140 return 1;
141 }
142
143 jeb = &c->blocks[ref->flash_offset / c->sector_size];
144 len = ref_totlen(c, jeb, ref);
145
146 spin_lock(&c->erase_completion_lock);
147 jeb->used_size += len;
148 jeb->unchecked_size -= len;
149 c->used_size += len;
150 c->unchecked_size -= len;
151 ref->flash_offset = ref_offset(ref) | REF_PRISTINE;
152 spin_unlock(&c->erase_completion_lock);
153 }
154
132 fd = jffs2_alloc_full_dirent(rd->nsize + 1); 155 fd = jffs2_alloc_full_dirent(rd->nsize + 1);
133 if (unlikely(!fd)) 156 if (unlikely(!fd))
134 return -ENOMEM; 157 return -ENOMEM;
@@ -198,10 +221,18 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
198 struct jffs2_tmp_dnode_info *tn; 221 struct jffs2_tmp_dnode_info *tn;
199 uint32_t len, csize; 222 uint32_t len, csize;
200 int ret = 1; 223 int ret = 1;
224 uint32_t crc;
201 225
202 /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */ 226 /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
203 BUG_ON(ref_obsolete(ref)); 227 BUG_ON(ref_obsolete(ref));
204 228
229 crc = crc32(0, rd, sizeof(*rd) - 8);
230 if (unlikely(crc != je32_to_cpu(rd->node_crc))) {
231 JFFS2_NOTICE("node CRC failed on dnode at %#08x: read %#08x, calculated %#08x\n",
232 ref_offset(ref), je32_to_cpu(rd->node_crc), crc);
233 return 1;
234 }
235
205 tn = jffs2_alloc_tmp_dnode_info(); 236 tn = jffs2_alloc_tmp_dnode_info();
206 if (!tn) { 237 if (!tn) {
207 JFFS2_ERROR("failed to allocate tn (%zu bytes).\n", sizeof(*tn)); 238 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 244
214 /* If we've never checked the CRCs on this node, check them now */ 245 /* If we've never checked the CRCs on this node, check them now */
215 if (ref_flags(ref) == REF_UNCHECKED) { 246 if (ref_flags(ref) == REF_UNCHECKED) {
216 uint32_t crc;
217
218 crc = crc32(0, rd, sizeof(*rd) - 8);
219 if (unlikely(crc != je32_to_cpu(rd->node_crc))) {
220 JFFS2_NOTICE("header CRC failed on node at %#08x: read %#08x, calculated %#08x\n",
221 ref_offset(ref), je32_to_cpu(rd->node_crc), crc);
222 goto free_out;
223 }
224 247
225 /* Sanity checks */ 248 /* Sanity checks */
226 if (unlikely(je32_to_cpu(rd->offset) > je32_to_cpu(rd->isize)) || 249 if (unlikely(je32_to_cpu(rd->offset) > je32_to_cpu(rd->isize)) ||
diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c
index 51bf1654ce3b..0b02fc79e4d1 100644
--- a/fs/jffs2/summary.c
+++ b/fs/jffs2/summary.c
@@ -453,7 +453,7 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
453 return -ENOMEM; 453 return -ENOMEM;
454 } 454 }
455 455
456 fd->raw = sum_link_node_ref(c, jeb, je32_to_cpu(spd->offset) | REF_PRISTINE, 456 fd->raw = sum_link_node_ref(c, jeb, je32_to_cpu(spd->offset) | REF_UNCHECKED,
457 PAD(je32_to_cpu(spd->totlen)), ic); 457 PAD(je32_to_cpu(spd->totlen)), ic);
458 458
459 fd->next = NULL; 459 fd->next = NULL;