https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=298669

            Bug ID: 298669
           Summary: pmbr goes in an infinite loop in case of oversized
                    freebsd-boot partition
           Product: Base System
           Version: 15.1-RELEASE
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Some People
          Priority: ---
         Component: misc
          Assignee: [email protected]
          Reporter: [email protected]

Created attachment 274893
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=274893&action=edit
Fix the bug introduced by D42774

Since 14.1-RELEASE, pmbr has been modified so if the freebsd-boot partition
that is loaded is > 545 KB, it just prints "Loaded only 545k" instead of
hanging (https://reviews.freebsd.org/D42774).

In fact, if you have a freebsd-boot partition > 545 KB, it displays this
message but in an infinite loop and fill the console with that without continue
to boot.

------------------
#
# We found a boot partition.  Load it into RAM starting at 0x7c00.
#
                movw %bx,%di                    # Save partition pointer in %di
                leaw PART_START_LBA(%di),%si
                movw $LOAD/16,%bx
                movw %bx,%es
                xorw %bx,%bx
load_boot:      push %si                        # Save %si
                call read
                pop %si                         # Restore
                movl PART_END_LBA(%di),%eax     # See if this was the last LBA
                cmpl (%si),%eax
                jnz next_boot
                movl PART_END_LBA+4(%di),%eax
                cmpl 4(%si),%eax
                jnz next_boot
                mov %bx,%es                     # Reset %es to zero 
                jmp LOAD                        # Jump to boot code
next_boot:      addl $1,(%si)                   # Next LBA
                adcl $0,4(%si)
                mov %es,%ax                     # Adjust segment for next
                addw $SECSIZE/16,%ax            #  sector
                cmp $0x9000,%ax                 # Don't load past 0x90000,
                jb sz_ok                        #  545k should be enough for
                call err_big                    #  any boot code, but warn
                mov $0x9000-SECSIZE/16,%ax      #  and truncate
sz_ok:          mov %ax,%es
                jmp load_boot
------------------

After err_big is called, instead of jumping to the loaded bootcode, it
"truncates". It wants to fill below 0x90000 with the last sector possible. What
is the purpose of this? Once it reaches 0x90000, it should just stop loading
and jump. Because, with this code, there is no other way to goes out of the
loop but to be on the last LBA.

Moreover, the call to err_big changes %bx and %si, so the test to the last LBA
of the partition never succeed, hence the infinite loop.

I propose this code. I have tested and it works as intended. It prints only
once the warning message and continues to boot.

------------------
next_boot:      addl $1,(%si)                   # Next LBA
                adcl $0,4(%si)
                mov %es,%ax                     # Adjust segment for next
                addw $SECSIZE/16,%ax            #  sector
                cmp $0x9000,%ax                 # Don't load past 0x90000,
                jb sz_ok                        #  545k should be enough for
                call err_big                    #  any boot code, but warn
                xorw %bx,%bx
                mov %bx,%es                     # Reset %es to zero
                jmp LOAD                        # Jump to boot code
sz_ok:          mov %ax,%es
                jmp load_boot
------------------

The attached patch make this.

-- 
You are receiving this mail because:
You are the assignee for the bug.

Reply via email to