Fixing out-of bound writes.

Firstly, packed attribute is added to the structure so that extension
is guarranteed to immediately follow name for the cross-name-extension
reads to succeed.

Secondly, writes into dir_entry->name that span through the extension as
well are split into two, so that FORTIFY_SOURCE's bound checking does
not abort dosfsck. There also was an off-by-one error in auto_rename()'s
sprintf().

Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch>
This commit is contained in:
Lubomir Rintel 2009-12-24 09:39:39 +01:00 committed by Daniel Baumann
parent b8f3efed9c
commit 2c405dd8da
3 changed files with 12 additions and 5 deletions

View File

@ -131,7 +131,10 @@ loff_t alloc_rootdir_entry(DOS_FS *fs, DIR_ENT *de, const char *pattern)
}
memset(de,0,sizeof(DIR_ENT));
while (1) {
sprintf(de->name,pattern,curr_num);
char expanded[12];
sprintf(expanded, pattern, curr_num);
memcpy(de->name+4, expanded, 4);
memcpy(de->ext, expanded+4, 3);
clu_num = fs->root_cluster;
i = 0;
offset2 = cluster_start(fs,clu_num);
@ -349,8 +352,11 @@ static void auto_rename(DOS_FILE *file)
first = file->parent ? file->parent->first : root;
number = 0;
while (1) {
sprintf(file->dir_ent.name, "FSCK%04d", number / 1000);
sprintf(file->dir_ent.ext, "%03d", number % 1000);
char num[8];
sprintf(num, "%07d", number);
memcpy(file->dir_ent.name, "FSCK", 4);
memcpy(file->dir_ent.name+4, num, 4);
memcpy(file->dir_ent.ext, num+4, 3);
for (walk = first; walk; walk = walk->next)
if (walk != file && !strncmp(walk->dir_ent.name,file->dir_ent.
name,MSDOS_NAME)) break;

View File

@ -149,7 +149,7 @@ typedef struct {
__u16 starthi; /* High 16 bits of cluster in FAT32 */
__u16 time,date,start;/* time, date and first cluster */
__u32 size; /* file size (in bytes) */
} DIR_ENT;
} __attribute__ ((packed)) DIR_ENT;
typedef struct _dos_file {
DIR_ENT dir_ent;

View File

@ -1254,7 +1254,8 @@ setup_tables (void)
if ( memcmp(volume_name, " ", 11) )
{
struct msdos_dir_entry *de = &root_dir[0];
memcpy(de->name, volume_name, 11);
memcpy(de->name, volume_name, 8);
memcpy(de->ext, volume_name+8, 3);
de->attr = ATTR_VOLUME;
ctime = localtime(&create_time);
de->time = CT_LE_W((unsigned short)((ctime->tm_sec >> 1) +