aboutsummaryrefslogtreecommitdiffstats
path: root/com32/modules/sdi.c
diff options
context:
space:
mode:
authorRemi Lefevre <rlefevre@gmail.com>2008-09-03 17:30:44 +0200
committerH. Peter Anvin <hpa@zytor.com>2008-09-08 17:56:39 -0700
commit568999e62a41d1b8f42c5b945b618099ca999394 (patch)
tree5d0fd664696cfe7ded9e4e0445d7c29a27bd4efc /com32/modules/sdi.c
parent6879e4565b2ed27de10e7a22bba568503012ef1a (diff)
downloadsyslinux.git-568999e62a41d1b8f42c5b945b618099ca999394.tar.gz
syslinux.git-568999e62a41d1b8f42c5b945b618099ca999394.tar.xz
syslinux.git-568999e62a41d1b8f42c5b945b618099ca999394.zip
sdi.c32: verify the header checksum
Verify the checksum in the SDI header. SDIheader variable names and checksum algo are from http://skolk.livejournal.com/
Diffstat (limited to 'com32/modules/sdi.c')
-rw-r--r--com32/modules/sdi.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/com32/modules/sdi.c b/com32/modules/sdi.c
index e2be9d51..04e9110e 100644
--- a/com32/modules/sdi.c
+++ b/com32/modules/sdi.c
@@ -39,12 +39,25 @@
# define dprintf(f, ...) ((void)0)
#endif
+typedef uint8_t guid_t[16];
+
struct SDIHeader {
uint32_t Signature;
char Version[4];
uint64_t SDIReserved;
uint64_t BootCodeOffset;
uint64_t BootCodeSize;
+ uint64_t VendorID;
+ uint64_t DeviceID;
+ guid_t DeviceModel;
+ uint64_t DeviceRole;
+ uint64_t Reserved1;
+ guid_t RuntimeGUID;
+ uint64_t RuntimeOEMrev;
+ uint64_t Reserved2;
+ uint64_t PageAlignment; /* BLOB alignment value in pages */
+ uint64_t Reserved3[48];
+ uint64_t Checksum;
};
#define SDI_LOAD_ADDR (16 << 20) /* 16 MB */
@@ -139,6 +152,21 @@ static int boot_sdi(void *ptr, size_t len)
return -1;
}
+/*
+ * Check that the sum of all bytes from first 512 bytes (SDI header)
+ * is 0 modulo 256.
+ */
+int has_valid_header(unsigned char *header)
+{
+ unsigned char checksum;
+ unsigned int i;
+
+ checksum = 0;
+ for (i = 0; i < sizeof(struct SDIHeader); i++)
+ checksum += header[i];
+ return (!checksum);
+}
+
int main(int argc, char *argv[])
{
void *data;
@@ -160,6 +188,11 @@ int main(int argc, char *argv[])
}
fputs("ok\n", stdout);
+ if (!has_valid_header(data)) {
+ error("SDI header is corrupted\n");
+ return 1;
+ }
+
boot_sdi(data, data_len);
error("Invalid SDI file or insufficient memory\n");
return 1;