mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-09-29 08:00:26 +09:00
JFFS2: Process obsolete nodes as well as accurate ones
Obsolete nodes (ie. without the JFFS2_NODE_ACCURATE flag) were ignored because they had seemingly invalid crc. This could lead to finding the phantom node header in obsolete node data. Signed-off-by: Petr Borsodi <petr.borsodi@i.cz>
This commit is contained in:
parent
1bc5d3a568
commit
25ec2282eb
@ -1471,7 +1471,7 @@ static u32
|
|||||||
jffs2_1pass_build_lists(struct part_info * part)
|
jffs2_1pass_build_lists(struct part_info * part)
|
||||||
{
|
{
|
||||||
struct b_lists *pL;
|
struct b_lists *pL;
|
||||||
struct jffs2_unknown_node *node;
|
union jffs2_node_union *node;
|
||||||
u32 nr_sectors;
|
u32 nr_sectors;
|
||||||
u32 i;
|
u32 i;
|
||||||
u32 counter4 = 0;
|
u32 counter4 = 0;
|
||||||
@ -1507,6 +1507,7 @@ jffs2_1pass_build_lists(struct part_info * part)
|
|||||||
#endif
|
#endif
|
||||||
/* Indicates a sector with a CLEANMARKER was found */
|
/* Indicates a sector with a CLEANMARKER was found */
|
||||||
int clean_sector = 0;
|
int clean_sector = 0;
|
||||||
|
struct jffs2_unknown_node crcnode;
|
||||||
|
|
||||||
/* Set buf_size to maximum length */
|
/* Set buf_size to maximum length */
|
||||||
buf_size = DEFAULT_EMPTY_SCAN_SIZE;
|
buf_size = DEFAULT_EMPTY_SCAN_SIZE;
|
||||||
@ -1600,9 +1601,10 @@ jffs2_1pass_build_lists(struct part_info * part)
|
|||||||
}
|
}
|
||||||
prevofs = ofs;
|
prevofs = ofs;
|
||||||
if (sector_ofs + part->sector_size <
|
if (sector_ofs + part->sector_size <
|
||||||
ofs + sizeof(*node))
|
ofs + sizeof(struct jffs2_unknown_node))
|
||||||
break;
|
break;
|
||||||
if (buf_ofs + buf_len < ofs + sizeof(*node)) {
|
if (buf_ofs + buf_len <
|
||||||
|
ofs + sizeof(struct jffs2_unknown_node)) {
|
||||||
buf_len = min_t(uint32_t, buf_size, sector_ofs
|
buf_len = min_t(uint32_t, buf_size, sector_ofs
|
||||||
+ part->sector_size - ofs);
|
+ part->sector_size - ofs);
|
||||||
get_fl_mem((u32)part->offset + ofs, buf_len,
|
get_fl_mem((u32)part->offset + ofs, buf_len,
|
||||||
@ -1610,7 +1612,7 @@ jffs2_1pass_build_lists(struct part_info * part)
|
|||||||
buf_ofs = ofs;
|
buf_ofs = ofs;
|
||||||
}
|
}
|
||||||
|
|
||||||
node = (struct jffs2_unknown_node *)&buf[ofs-buf_ofs];
|
node = (union jffs2_node_union *)&buf[ofs - buf_ofs];
|
||||||
|
|
||||||
if (*(uint32_t *)(&buf[ofs-buf_ofs]) == 0xffffffff) {
|
if (*(uint32_t *)(&buf[ofs-buf_ofs]) == 0xffffffff) {
|
||||||
uint32_t inbuf_ofs;
|
uint32_t inbuf_ofs;
|
||||||
@ -1665,23 +1667,41 @@ jffs2_1pass_build_lists(struct part_info * part)
|
|||||||
* the 'clean_sector' flag.
|
* the 'clean_sector' flag.
|
||||||
*/
|
*/
|
||||||
clean_sector = 0;
|
clean_sector = 0;
|
||||||
if (node->magic != JFFS2_MAGIC_BITMASK ||
|
if (node->u.magic != JFFS2_MAGIC_BITMASK) {
|
||||||
!hdr_crc(node)) {
|
|
||||||
ofs += 4;
|
ofs += 4;
|
||||||
counter4++;
|
counter4++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (ofs + node->totlen >
|
|
||||||
sector_ofs + part->sector_size) {
|
crcnode.magic = node->u.magic;
|
||||||
|
crcnode.nodetype = node->u.nodetype | JFFS2_NODE_ACCURATE;
|
||||||
|
crcnode.totlen = node->u.totlen;
|
||||||
|
crcnode.hdr_crc = node->u.hdr_crc;
|
||||||
|
if (!hdr_crc(&crcnode)) {
|
||||||
ofs += 4;
|
ofs += 4;
|
||||||
counter4++;
|
counter4++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ofs + node->u.totlen > sector_ofs + part->sector_size) {
|
||||||
|
ofs += 4;
|
||||||
|
counter4++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(node->u.nodetype & JFFS2_NODE_ACCURATE)) {
|
||||||
|
DEBUGF("Obsolete node type: %x len %d offset 0x%x\n",
|
||||||
|
node->u.nodetype, node->u.totlen, ofs);
|
||||||
|
ofs += ((node->u.totlen + 3) & ~3);
|
||||||
|
counterF++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* if its a fragment add it */
|
/* if its a fragment add it */
|
||||||
switch (node->nodetype) {
|
switch (node->u.nodetype) {
|
||||||
case JFFS2_NODETYPE_INODE:
|
case JFFS2_NODETYPE_INODE:
|
||||||
if (buf_ofs + buf_len < ofs + sizeof(struct
|
if (buf_ofs + buf_len <
|
||||||
jffs2_raw_inode)) {
|
ofs + sizeof(struct jffs2_raw_inode)) {
|
||||||
buf_len = min_t(uint32_t,
|
buf_len = min_t(uint32_t,
|
||||||
sizeof(struct jffs2_raw_inode),
|
sizeof(struct jffs2_raw_inode),
|
||||||
sector_ofs +
|
sector_ofs +
|
||||||
@ -1701,8 +1721,8 @@ jffs2_1pass_build_lists(struct part_info * part)
|
|||||||
jffs2_free_cache(part);
|
jffs2_free_cache(part);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (max_totlen < node->totlen)
|
if (max_totlen < node->u.totlen)
|
||||||
max_totlen = node->totlen;
|
max_totlen = node->u.totlen;
|
||||||
break;
|
break;
|
||||||
case JFFS2_NODETYPE_DIRENT:
|
case JFFS2_NODETYPE_DIRENT:
|
||||||
if (buf_ofs + buf_len < ofs + sizeof(struct
|
if (buf_ofs + buf_len < ofs + sizeof(struct
|
||||||
@ -1711,7 +1731,7 @@ jffs2_1pass_build_lists(struct part_info * part)
|
|||||||
jffs2_raw_dirent *)
|
jffs2_raw_dirent *)
|
||||||
node)->nsize) {
|
node)->nsize) {
|
||||||
buf_len = min_t(uint32_t,
|
buf_len = min_t(uint32_t,
|
||||||
node->totlen,
|
node->u.totlen,
|
||||||
sector_ofs +
|
sector_ofs +
|
||||||
part->sector_size -
|
part->sector_size -
|
||||||
ofs);
|
ofs);
|
||||||
@ -1736,19 +1756,19 @@ jffs2_1pass_build_lists(struct part_info * part)
|
|||||||
jffs2_free_cache(part);
|
jffs2_free_cache(part);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (max_totlen < node->totlen)
|
if (max_totlen < node->u.totlen)
|
||||||
max_totlen = node->totlen;
|
max_totlen = node->u.totlen;
|
||||||
counterN++;
|
counterN++;
|
||||||
break;
|
break;
|
||||||
case JFFS2_NODETYPE_CLEANMARKER:
|
case JFFS2_NODETYPE_CLEANMARKER:
|
||||||
if (node->totlen != sizeof(struct jffs2_unknown_node))
|
if (node->u.totlen != sizeof(struct jffs2_unknown_node))
|
||||||
printf("OOPS Cleanmarker has bad size "
|
printf("OOPS Cleanmarker has bad size "
|
||||||
"%d != %zu\n",
|
"%d != %zu\n",
|
||||||
node->totlen,
|
node->u.totlen,
|
||||||
sizeof(struct jffs2_unknown_node));
|
sizeof(struct jffs2_unknown_node));
|
||||||
if ((node->totlen ==
|
if (node->u.totlen ==
|
||||||
sizeof(struct jffs2_unknown_node)) &&
|
sizeof(struct jffs2_unknown_node) &&
|
||||||
(ofs == sector_ofs)) {
|
ofs == sector_ofs) {
|
||||||
/*
|
/*
|
||||||
* Found a CLEANMARKER at the beginning
|
* Found a CLEANMARKER at the beginning
|
||||||
* of the sector. It's in the correct
|
* of the sector. It's in the correct
|
||||||
@ -1758,20 +1778,21 @@ jffs2_1pass_build_lists(struct part_info * part)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case JFFS2_NODETYPE_PADDING:
|
case JFFS2_NODETYPE_PADDING:
|
||||||
if (node->totlen < sizeof(struct jffs2_unknown_node))
|
if (node->u.totlen <
|
||||||
|
sizeof(struct jffs2_unknown_node))
|
||||||
printf("OOPS Padding has bad size "
|
printf("OOPS Padding has bad size "
|
||||||
"%d < %zu\n",
|
"%d < %zu\n",
|
||||||
node->totlen,
|
node->u.totlen,
|
||||||
sizeof(struct jffs2_unknown_node));
|
sizeof(struct jffs2_unknown_node));
|
||||||
break;
|
break;
|
||||||
case JFFS2_NODETYPE_SUMMARY:
|
case JFFS2_NODETYPE_SUMMARY:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("Unknown node type: %x len %d offset 0x%x\n",
|
printf("Unknown node type: %x len %d offset 0x%x\n",
|
||||||
node->nodetype,
|
node->u.nodetype,
|
||||||
node->totlen, ofs);
|
node->u.totlen, ofs);
|
||||||
}
|
}
|
||||||
ofs += ((node->totlen + 3) & ~3);
|
ofs += ((node->u.totlen + 3) & ~3);
|
||||||
counterF++;
|
counterF++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user