Added a very simple checksum field to the init ramdisk.

This uncovers a bug where the bootloader may corrupt the initrd on x64.

This is probably related to our kernel64 hack..
This commit is contained in:
Jonas 'Sortie' Termansen 2011-12-01 21:44:11 +01:00
parent 2faafd3f99
commit b0884584a1
3 changed files with 49 additions and 0 deletions

View File

@ -49,6 +49,16 @@ bool writeall(int fd, const void* p, size_t size)
return true;
}
uint8_t ContinueChecksum(uint8_t checksum, const void* p, size_t size)
{
const uint8_t* buffer = (const uint8_t*) p;
while ( size-- )
{
checksum += *buffer++;
}
return checksum;
}
void usage(int argc, char* argv[])
{
printf("usage: %s [OPTIONS] <files>\n", argv[0]);
@ -136,11 +146,16 @@ int main(int argc, char* argv[])
return 1;
}
// Keep track of the file checksum.
Sortix::InitRD::Trailer trailer;
trailer.sum = 0;
// Write the initrd headers.
Sortix::InitRD::Header header;
memset(&header, 0, sizeof(header));
strcpy(header.magic, "sortix-initrd-1");
header.numfiles = numfiles;
trailer.sum = ContinueChecksum(trailer.sum, &header, sizeof(header));
if ( !writeall(fd, &header, sizeof(header)) )
{
error(0, errno, "write: %s", dest);
@ -209,6 +224,7 @@ int main(int argc, char* argv[])
return 1;
}
trailer.sum = ContinueChecksum(trailer.sum, &fileheader, sizeof(fileheader));
if ( !writeall(fd, &fileheader, sizeof(fileheader)) )
{
error(0, errno, "write: %s", dest);
@ -242,6 +258,7 @@ int main(int argc, char* argv[])
return 1;
}
trailer.sum = ContinueChecksum(trailer.sum, &buffer, bytesread);
if ( !writeall(fd, buffer, bytesread) )
{
error(0, errno, "write: %s", dest);
@ -259,5 +276,13 @@ int main(int argc, char* argv[])
close(filefd);
}
if ( !writeall(fd, &trailer, sizeof(trailer)) )
{
error(0, errno, "write: %s", dest);
close(fd);
unlink(dest);
return 1;
}
return 0;
}

View File

@ -93,6 +93,16 @@ namespace Sortix
return 0;
}
uint8_t ContinueChecksum(uint8_t checksum, const void* p, size_t size)
{
const uint8_t* buffer = (const uint8_t*) p;
while ( size-- )
{
checksum += *buffer++;
}
return checksum;
}
void Init(byte* theinitrd, size_t size)
{
initrd = theinitrd;
@ -104,6 +114,15 @@ namespace Sortix
if ( size < sizeneeded ) { PanicF("initrd.cpp: initrd is too small"); }
// TODO: We need to do more validation here!
Trailer* trailer = (Trailer*) (initrd + initrdsize - sizeof(Trailer));
uint8_t checksum = ContinueChecksum(0, initrd, initrdsize - sizeof(Trailer));
if ( trailer->sum != checksum )
{
PanicF("InitRD Checksum failed: the ramdisk may have been "
"corrupted by the bootloader: Got %u instead of %u\n",
checksum, trailer->sum);
}
Syscall::Register(SYSCALL_PRINT_PATH_FILES, (void*) SysPrintPathFiles);
Syscall::Register(SYSCALL_GET_FILEINFO, (void*) SysGetFileInfo);
Syscall::Register(SYSCALL_GET_NUM_FILES, (void*) SysGetNumFiles);

View File

@ -49,6 +49,11 @@ namespace Sortix
char name[128];
};
struct Trailer
{
uint8_t sum; // sum of all bytes but the trailer.
};
#ifdef SORTIX_KERNEL
void Init(byte* initrd, size_t size);
byte* Open(const char* filepath, size_t* size);