Improve correctness of mkyaffs2image: - Ensure overly long filenames are flagged as an error, rather than allowing buffer to not be null terminated or overflow. (strncpy does not guarantee null termination). - Ensure all spare bytes are initialized. (Any uninitialized bytes in PackedTags default to 0; any spare bytes not used by the OOB shuffle default to 0xff like nanderase would have done.) - Add missing closedir() to match opendir(). - Removed double close() of outFile. - Do not close() file handle that failed to open(). Index: mkyaffs2image/mkyaffs2image.c =================================================================== --- mkyaffs2image.orig/mkyaffs2image.c 2010-08-26 13:08:14.000000000 -0600 +++ mkyaffs2image/mkyaffs2image.c 2010-08-26 14:08:27.000000000 -0600 @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include "yaffs_ecc.h" #include "yaffs_guts.h" @@ -154,10 +156,18 @@ #endif } +static void shuffle_oob(char *spareData, yaffs_PackedTags2 *pt) +{ + assert(sizeof(*pt) <= spareSize); + // For non-trivial OOB orderings, here would be a good place to shuffle. + memcpy(spareData, pt, sizeof(*pt)); +} + static int write_chunk(__u8 *data, __u32 objId, __u32 chunkId, __u32 nBytes) { yaffs_ExtendedTags t; yaffs_PackedTags2 pt; + char spareData[spareSize]; error = write(outFile,data,chunkSize); if(error < 0) return error; @@ -182,10 +192,13 @@ nPages++; + memset(&pt, 0, sizeof(pt)); yaffs_PackTags2(&pt,&t,1); - -// return write(outFile,&pt,sizeof(yaffs_PackedTags2)); - return write(outFile,&pt,spareSize); + + memset(spareData, 0xff, sizeof(spareData)); + shuffle_oob(spareData, &pt); + + return write(outFile,spareData,sizeof(spareData)); } @@ -268,7 +281,10 @@ oh->parentObjectId = parent; - strncpy(oh->name,name,YAFFS_MAX_NAME_LENGTH); + if (strlen(name)+1 > sizeof(oh->name)) + return -1; + memset(oh->name,0,sizeof(oh->name)); + strcpy(oh->name,name); if(t != YAFFS_OBJECT_TYPE_HARDLINK) @@ -295,7 +311,10 @@ if(t == YAFFS_OBJECT_TYPE_SYMLINK) { - strncpy(oh->alias,alias,YAFFS_MAX_ALIAS_LENGTH); + if (strlen(alias)+1 > sizeof(oh->alias)) + return -1; + memset(oh->alias,0,sizeof(oh->alias)); + strcpy(oh->alias,alias); } if (convert_endian) @@ -332,7 +351,11 @@ int equivalentObj; int newObj; - sprintf(full_name,"%s/%s",path,entry->d_name); + if (snprintf(full_name,sizeof(full_name),"%s/%s",path,entry->d_name) >= (int)sizeof(full_name)) + { + error = -1; + continue; + } lstat(full_name,&stats); @@ -401,12 +424,12 @@ error = nBytes; printf("%d data chunks written\n",chunk); + close(h); } else { perror("Error opening file"); } - close(h); } @@ -446,6 +469,7 @@ } } } + closedir(dir); } return 0; @@ -513,8 +537,6 @@ "%d NAND pages\n",nObjects, nDirectories, nPages); } - close(outFile); - exit(0); }