macho: bound ncmds by sizeofcmds and validate nsyms upfront
ober
406c270ccbadad626e0b76f84adf9038e4b2e5ee
--- a/lib/jasm/object/macho.ss +++ b/lib/jasm/object/macho.ss @@ -240,6 +240,8 @@ [stroff (list-ref symtab 2)] [strsize (list-ref symtab 3)] [str-limit (+ stroff strsize)]) + (when (> (+ symoff (* nsyms 16)) (bv-len bv)) + (error 'read-macho-bytevector "Mach-O symtab count exceeds file" nsyms)) (let loop ([index 0] [symbols '()]) (if (= index nsyms) (reverse symbols) @@ -271,6 +273,8 @@ [sizeofcmds (u32 bv 20 endian)] [command-info #f]) (require-range 'read-macho-bytevector bv 32 sizeofcmds) + (when (> ncmds (div sizeofcmds 8)) + (error 'read-macho-bytevector "Mach-O load command count exceeds command size" ncmds sizeofcmds)) (set! command-info (parse-load-commands endian bv ncmds)) (make-macho-object endian cpu-type --- a/tests/test-malformed-objects.ss +++ b/tests/test-malformed-objects.ss @@ -68,6 +68,34 @@ (put32le! bv #x60 1) bv)) +(def (macho-ncmds-exceeds-sizeofcmds) + (let ([bv (make-bytevector 48 0)]) + (put32le! bv 0 #xfeedfacf) + (put32le! bv 4 #x0100000c) + (put32le! bv 12 1) + (put32le! bv 16 2) + (put32le! bv 20 8) + (put32le! bv 32 #xff) + (put32le! bv 36 8) + (put32le! bv 40 #xff) + (put32le! bv 44 8) + bv)) + +(def (macho-symtab-count-overrun) + (let ([bv (make-bytevector 56 0)]) + (put32le! bv 0 #xfeedfacf) + (put32le! bv 4 #x0100000c) + (put32le! bv 12 1) + (put32le! bv 16 1) + (put32le! bv 20 24) + (put32le! bv 32 #x2) + (put32le! bv 36 24) + (put32le! bv 40 0) + (put32le! bv 44 #x10000000) + (put32le! bv 48 0) + (put32le! bv 52 0) + bv)) + (def (archive-invalid-bsd-long-name) (let ([bv (make-bytevector 72 (char->integer #\space))]) (put-ascii! bv 0 "!<arch>\n") @@ -160,6 +188,12 @@ (test-raises "mach-o segment section overrun" (read-macho-bytevector (macho-segment-with-section-overrun))) +(test-raises "mach-o ncmds exceeds sizeofcmds" + (read-macho-bytevector (macho-ncmds-exceeds-sizeofcmds))) + +(test-raises "mach-o symtab count overrun" + (read-macho-bytevector (macho-symtab-count-overrun))) + (test-raises "coff truncated section table" (read-coff-bytevector (coff-with-truncated-section-table)))