prepcore: error out if the compressed image is too large to load
authorH. Peter Anvin <hpa@zytor.com>
Mon, 1 Jun 2009 21:47:45 +0000 (14:47 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Mon, 1 Jun 2009 21:47:45 +0000 (14:47 -0700)
Export, from each loader stage, the symbol MaxLMA which indicates to
prepcore how big the image is allowed to be.  Change prepcore to
enforce this limit and to error out otherwise.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
core/common.inc
core/diskstart.inc
core/isolinux.asm
core/layout.inc
core/prefix.inc [new file with mode: 0644]
core/pxelinux.asm
lzo/prepcore.c

index ad64c23..80dbb4f 100644 (file)
@@ -18,3 +18,7 @@
 %include "strcpy.inc"           ; strcpy()
 %include "idle.inc"            ; Idle handling
 %include "adv.inc"             ; Auxillary Data Vector
+
+; Note: the prefix section is included late, to avoid problems with some
+; versions of NASM that had issues with forward references to EQU symbols.
+%include "prefix.inc"          ; Prefix section for prepcore
index b713a1e..b804726 100644 (file)
@@ -668,8 +668,8 @@ rl_checkpt_off      equ ($-$$)
 
 ; Sector pointers
                alignz 4
-               global MaxInitDataSize
 MaxInitDataSize        equ 96 << 10
+MaxLMA         equ 0x7c00+SECTOR_SIZE+MaxInitDataSize
 SectorPtrs     times MaxInitDataSize >> SECTOR_SHIFT dd 0
 SectorPtrsEnd  equ $
 
index 37c1474..b2c9c98 100644 (file)
@@ -431,6 +431,8 @@ found_file:
                ; address (7C00h) is *not* 2K-sector-aligned, the safest
                ; way to deal with this is to load into the xfer_buf_seg
                ; and then copy the data in place.
+MaxLMA         equ xfer_buf_seg << 4
+
                mov bx,(7C00h+SECTOR_SIZE) >> 4
                mov bp,[ImageSectors]
 
index e2c7cbc..fe292b1 100644 (file)
@@ -134,18 +134,3 @@ pktbuf_seg equ cache_seg           ; PXELINUX packet buffers
 %endif
 
 comboot_seg    equ real_mode_seg       ; COMBOOT image loading zone
-
-;
-; The prefix is a small structure that prefaces the actual code;
-; it gives the compression program necessary information.
-;
-
-               section .prefix         nowrite progbits align=16
-pfx_start      dd _start               ; Start of raw chunk
-pfx_compressed dd __pm_code_lma        ; Start of compressed chunk
-pfx_cdatalen   dd lzo_data_size        ; Pointer to compressed size field
-%if IS_ISOLINUX
-pfx_checksum   dd bi_length            ; File length and checksum fields
-%else
-pfx_checksum   dd 0                    ; No checksum
-%endif
diff --git a/core/prefix.inc b/core/prefix.inc
new file mode 100644 (file)
index 0000000..9c8724b
--- /dev/null
@@ -0,0 +1,17 @@
+;
+; The prefix is a small structure that prefaces the actual code;
+; it gives the compression program necessary information.
+;
+
+               section .prefix         nowrite progbits align=16
+pfx_start      dd _start               ; Start of raw chunk
+pfx_compressed dd __pm_code_lma        ; Start of compressed chunk
+pfx_cdatalen   dd lzo_data_size        ; Pointer to compressed size field
+%if IS_ISOLINUX
+pfx_checksum   dd bi_length            ; File length and checksum fields
+%else
+pfx_checksum   dd 0                    ; No checksum
+%endif
+pfx_maxlma     dd MaxLMA               ; Maximum size
+
+               section .text16
index bb536a6..b866369 100644 (file)
@@ -224,6 +224,10 @@ packet_buf_size    equ $-packet_buf
 StackBuf       equ $-44                ; Base of stack if we use our own
 StackTop       equ StackBuf
 
+               ; PXE loads the whole file, but assume it can't be more
+               ; than (384-31)K in size.
+MaxLMA         equ 384*1024
+
 ;
 ; Primary entry point.
 ;
index cb6b483..fc1b6c6 100644 (file)
@@ -95,6 +95,7 @@ struct prefix {
     uint32_t pfx_compressed;
     uint32_t pfx_cdatalen;
     uint32_t pfx_checksum;
+    uint32_t pfx_maxlma;
 };
 
 static inline uint32_t get_32(const uint32_t * p)
@@ -317,6 +318,13 @@ int __lzo_cdecl_main main(int argc, char *argv[])
        set_32((uint32_t *) (infile + soff + 4), csum);
     }
 
+    if (offset+outfile_len > get_32(&prefix->pfx_maxlma)) {
+       printf("%s: output too big (%lu, max %lu)\n",
+              (unsigned long)offset+outfile_len,
+              (unsigned long)get_32(&prefix->pfx_maxlma));
+       exit(1);
+    }
+
     f = fopen(out_name, "wb");
     if (f == NULL) {
        printf("%s: cannot open output file %s\n", progname, out_name);