[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Memory overwrites of jffs_file struct (JFFS 1)



I'm having a problem with the parent and children pointers being overwritten
with garbage (or at least something I don't want there) in a JFFS file system on
one of our ETRAX boards.  

The problem is easily reproduced by a "umount /mnt/flash" followed by a "mount
-t jffs /dev/flash2 /mnt/flash rw".  After that I cannot cd to /etc/httpd/conf
(same directory every time) because the board oopses (2.4.20 kernel; I checked
the JFFS CVS on infradead.org and it hasn't been changed since).  After a
reboot, the file system is always fine again.  The mount is always reported as
successful, and the directory structure printed at debug level 1 is identical to
the printout when the board is rebooted (when the file system is ok).

What happens is that the conf file's parent and children pointers are
overwritten, so I added padding before them to see if they were overwritten by
someone using their respective pointer names:

  struct jffs_control *c;
  __u32 pad1;
  __u32 pad2;
  struct jffs_file *parent;   /* Reference to the parent directory.  */
  struct jffs_file *children; /* Always NULL for plain files.  */

Sure enough, doing a jffs_print_file on dir in jffs_find_child reveals that
someone has written where they shouldn't (the whole jffs_file struct is zeroed
when allocated, and pad1/pad2 are 0 for all other files in the log):

  0x00000001, /* highest_version  */
  0xc0f63ec0, /* c  */   
  0xf609e000, /* pad1  */
  0x000000c0, /* pad2  */
  0xc01810c0, /* parent  */
  0xc0f61960, /* children  */

In other words, the parent and children pointers were not used when doing the
garbage write.  To see if it was related to the jffs_control struct being placed
before parent/children, I moved it to last in the jffs_file struct, but kept the
padding:

  0x00000001, /* highest_version  */
  0x00000000, /* pad1  */
  0xf609e000, /* pad2  */
  0xc01810c0, /* parent  */
  0xc0f61960, /* children  */

Again, the area is overwritten, but it can't be related to the jffs_control
struct.  Since the jffs_control struct occupies 4 bytes, the erroneous write
becomes displaced by 4 bytes (the 0xc0 which was originally in pad2 is masked by
the fact that the parent pointer already ends in c0, so the overwrite isn't
visible).  So, someone or something writes 4 bytes to an address related to the
jffs_file struct, but not aligned to any member of the struct.

With a little imagination, the combined contents of pad1 and pad2 could be seen
as a jffs_file struct pointer: 0xc0f609e0, which happens to be a valid file in
the file system.  I'm not sure if that means anything.

Any suggestion on where to look for the culprit is appreciated.  (I can repeat
this with any amount of debug.)

-- 
Orjan Friberg
Axis Communications AB

To unsubscribe from this list: send the line "unsubscribe jffs-dev" in
the body of a message to majordomo@xxxxxxx.com