diff options
author | David Woodhouse <dwmw2@infradead.org> | 2007-10-13 11:35:58 +0100 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2007-10-13 11:35:58 +0100 |
commit | b534e70cf5529378a1ed994492641ec0330554eb (patch) | |
tree | d0257ffa39a331cad12e855122cb1e540b0eac41 /fs/jffs2/scan.c | |
parent | 69ca4378aa376cf2c49657d4f6951da56c27cd3a (diff) | |
download | op-kernel-dev-b534e70cf5529378a1ed994492641ec0330554eb.zip op-kernel-dev-b534e70cf5529378a1ed994492641ec0330554eb.tar.gz |
[JFFS2] Handle dirents on the flash with embedded zero bytes in names.
In three places: summary scan, normal scan, REF_PRISTINE GC.
Just truncate at the NUL, since that was the correct thing to do in the
only case where this (inexplicable) breakage has been seen.
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'fs/jffs2/scan.c')
-rw-r--r-- | fs/jffs2/scan.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c index 35ef8d8..272872d 100644 --- a/fs/jffs2/scan.c +++ b/fs/jffs2/scan.c @@ -1004,6 +1004,7 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo { struct jffs2_full_dirent *fd; struct jffs2_inode_cache *ic; + uint32_t checkedlen; uint32_t crc; int err; @@ -1024,12 +1025,18 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo pseudo_random += je32_to_cpu(rd->version); - fd = jffs2_alloc_full_dirent(rd->nsize+1); + /* Should never happen. Did. (OLPC trac #4184)*/ + checkedlen = strnlen(rd->name, rd->nsize); + if (checkedlen < rd->nsize) { + printk(KERN_ERR "Dirent at %08x has zeroes in name. Truncating to %d chars\n", + ofs, checkedlen); + } + fd = jffs2_alloc_full_dirent(checkedlen+1); if (!fd) { return -ENOMEM; } - memcpy(&fd->name, rd->name, rd->nsize); - fd->name[rd->nsize] = 0; + memcpy(&fd->name, rd->name, checkedlen); + fd->name[checkedlen] = 0; crc = crc32(0, fd->name, rd->nsize); if (crc != je32_to_cpu(rd->name_crc)) { @@ -1055,7 +1062,7 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo fd->next = NULL; fd->version = je32_to_cpu(rd->version); fd->ino = je32_to_cpu(rd->ino); - fd->nhash = full_name_hash(fd->name, rd->nsize); + fd->nhash = full_name_hash(fd->name, checkedlen); fd->type = rd->type; jffs2_add_fd_to_list(c, fd, &ic->scan_dents); |