Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

flashrom.c: Fail immediately when trying to write/erase wp regions #17

Open
wants to merge 4 commits into
base: sync
Choose a base branch
from

Conversation

m-iwanicki
Copy link

@m-iwanicki m-iwanicki commented Dec 5, 2024

write_protect_check can be deleted and PR0 check will still happen but only one region at a time, so if we write/erase multiple regions (e.g. -i fd -i bios) then first region might get written if it is read-write.

In case of e.g. FREG1: BIOS region (0x00580000-0x00ffffff) is read-write. & PR0: Warning: 0x00b00000-0x00ffffff is read-only. write/erase would still fail even if we tried to flash only unprotected parts of region e.g. 0x00580000-0x00590000

To force write/erase add --force argument.

meson test:

# meson test -C builddir
ninja: Entering directory `/flashrom/builddir'
ninja: no work to do.
1/1 cmocka test flashrom        OK              1.47s

Ok:                 1
Expected Fail:      0
Fail:               0
Unexpected Pass:    0
Skipped:            0
Timeout:            0

Full log written to /flashrom/builddir/meson-logs/testlog.txt

Tested on Protectli VP6670:

Try to flash whole chip:

bash-5.2# flashrom -p internal -w backup.rom
flashrom 1.5.0-devel (git:v1.2-1579-gc50d797f) on Linux 6.6.21-yocto-standard (x86_64)
flashrom is free software, get the source code at https://flashrom.org

coreboot table found at 0x76a14000.
Found chipset "Intel Alder Lake-P".
Enabling flash write... Warning: BIOS region SMM protection is enabled!
Warning: Setting BIOS Control at 0xdc from 0xaa to 0x89 failed.
New value is 0xaa.
SPI Configuration is locked down.
FREG0: Flash Descriptor region (0x00000000-0x00000fff) is read-write.
FREG1: BIOS region (0x00580000-0x00ffffff) is read-write.
FREG2: Management Engine region (0x00001000-0x003aefff) is read-write.
PR0: Warning: 0x00b00000-0x00ffffff is read-only.
At least some flash regions are write protected. For write operations,
you should use a flash layout and include only writable regions. See
manpage for more details.
PROBLEMS, continuing anyway
Found Macronix flash chip "MX25L12805D" (16384 kB, Programmer-specific) on internal.
===
This flash part has status UNTESTED for operations: WP
The test status of this chip may have been updated in the latest development
version of flashrom. If you are running the latest development version,
please email a report to [email protected] if any of the above operations
work correctly for you with this flash chip. Please include the flashrom log
file for all operations you tested (see the man page for details), and mention
which mainboard or programmer you tested in the subject line.
You can also try to follow the instructions here:
https://www.flashrom.org/contrib_howtos/how_to_mark_chip_tested.html
Thanks for your help!
check_for_unwritable_regions: cannot write/erase inside BIOS region (0x580000..0xffffff).
Requested regions are write protected. Aborting.

Try to flash protected part:

bash-5.2# flashrom -p internal --ifd -i bios -w backup.rom
(...)
Reading ich descriptor... done.
Using region: "bios".
check_for_unwritable_regions: cannot write/erase inside BIOS region (0x580000..0xffffff).
Requested regions are write protected. Aborting.

Try to flash unprotected part:

bash-5.2# flashrom -p internal --ifd -i fd -w backup.rom
(...)
Reading ich descriptor... done.
Using region: "fd".
Reading old flash chip contents... done.
Erase/write done from 0 to fff

WP protection checked with dummy programmer:

unprotected part:

# builddir/flashrom -p dummy:hwwp=yes,emulate=S25FL128L --wp-enable --wp-range 0x00040000,0x00fc0000 -l <(echo '00000000:0003ffff part1') -i part1 -E
flashrom 1.5.0-devel (git:v1.2-1579-gc50d797f79df) on Linux 6.11.10-300.fc41.x86_64 (x86_64)
flashrom is free software, get the source code at https://flashrom.org

Using region: "part1".
Found Spansion flash chip "S25FL128L" (16384 kB, SPI) on dummy.
===
This flash part has status UNTESTED for operations: WP
The test status of this chip may have been updated in the latest development
version of flashrom. If you are running the latest development version,
please email a report to [email protected] if any of the above operations
work correctly for you with this flash chip. Please include the flashrom log
file for all operations you tested (see the man page for details), and mention
which mainboard or programmer you tested in the subject line.
You can also try to follow the instructions here:
https://www.flashrom.org/contrib_howtos/how_to_mark_chip_tested.html
Thanks for your help!
Enabled hardware protection
Activated protection range: start=0x00040000 length=0x00fc0000 (upper 63/64)
Failed to unlock flash status reg with wp support.
Unsetting lock bit(s) failed.
Erase/write done from 0 to 3ffff

Protected part:

# builddir/flashrom -p dummy:hwwp=yes,emulate=S25FL128L --wp-enable --wp-range 0x00040000,0x00fc0000 -l <(echo '00000000:0004ffff part1') -i part1 -E
flashrom 1.5.0-devel (git:v1.2-1579-gc50d797f79df) on Linux 6.11.10-300.fc41.x86_64 (x86_64)
flashrom is free software, get the source code at https://flashrom.org

Using region: "part1".
Found Spansion flash chip "S25FL128L" (16384 kB, SPI) on dummy.
===
This flash part has status UNTESTED for operations: WP
The test status of this chip may have been updated in the latest development
version of flashrom. If you are running the latest development version,
please email a report to [email protected] if any of the above operations
work correctly for you with this flash chip. Please include the flashrom log
file for all operations you tested (see the man page for details), and mention
which mainboard or programmer you tested in the subject line.
You can also try to follow the instructions here:
https://www.flashrom.org/contrib_howtos/how_to_mark_chip_tested.html
Thanks for your help!
Enabled hardware protection
Activated protection range: start=0x00040000 length=0x00fc0000 (upper 63/64)
Requested regions are write protected. Aborting.
Your flash chip is in an unknown state.
Please report this to the mailing list at [email protected] or
on IRC (see https://www.flashrom.org/Contact for details), thanks!

@mkopec
Copy link
Member

mkopec commented Dec 6, 2024

In case of e.g. FREG1: BIOS region (0x00580000-0x00ffffff) is read-write. & PR0: Warning: 0x00b00000-0x00ffffff is read-only. write/erase would still fail even if we tried to flash only unprotected parts of region e.g. 0x00580000-0x00590000

Can you change this so that only attempting to flash the actually protected ranges will throw an error? For example if someone has WP_RO protected but only wants to flash RW_SECTION_*

@m-iwanicki m-iwanicki force-pushed the refuse-flashing-if-protected branch from 337da02 to e7b4efa Compare December 6, 2024 18:31
@m-iwanicki
Copy link
Author

m-iwanicki commented Dec 6, 2024

Tests

@mkopec
Tests were made on the same Protectli as before

  1. Flash regions

    bash-5.2# flashrom -p internal
    flashrom 1.5.0-devel (git:v1.2-1581-g4dc3fa98) on Linux 6.6.21-yocto-standard (x86_64)
    flashrom is free software, get the source code at https://flashrom.org
    
    coreboot table found at 0x76a14000.
    Found chipset "Intel Alder Lake-P".
    Enabling flash write... Warning: BIOS region SMM protection is enabled!
    Warning: Setting BIOS Control at 0xdc from 0xaa to 0x89 failed.
    New value is 0xaa.
    SPI Configuration is locked down.
    FREG0: Flash Descriptor region (0x00000000-0x00000fff) is read-write.
    FREG1: BIOS region (0x00580000-0x00ffffff) is read-write.
    FREG2: Management Engine region (0x00001000-0x003aefff) is read-write.
    PR0: Warning: 0x00b00000-0x00ffffff is read-only.
    
  2. Layout file:

    bash-5.2# cat layout
    00000000:00000fff freg0
    00580000:005fffff rw_bios
    00a00000:00bfffff rw_r_bios
    00c00000:00cfffff r_bios
    
  3. Try to flash range that's partially protected

    bash-5.2# flashrom -p internal -l layout -i rw_r_bios -w backup.rom
    flashrom 1.5.0-devel (git:v1.2-1581-g4dc3fa98) on Linux 6.6.21-yocto-standard (x86_64)
    flashrom is free software, get the source code at https://flashrom.org
    
    Using region: "rw_r_bios".
    (...)
    Requested regions are write protected. Aborting.
    
  4. Try to flash range that's fully protected

    bash-5.2# flashrom -p internal -l layout -i r_bios -w backup.rom
    flashrom 1.5.0-devel (git:v1.2-1581-g4dc3fa98) on Linux 6.6.21-yocto-standard (x86_64)
    flashrom is free software, get the source code at https://flashrom.org
    
    Using region: "r_bios"
    (...)
    Requested regions are write protected. Aborting.
    
  5. Try to flash 2 ranges one unprotected and one protected

    bash-5.2# flashrom -p internal -l layout -i rw_bios -i r_bios -w backup.rom
    flashrom 1.5.0-devel (git:v1.2-1581-g4dc3fa98) on Linux 6.6.21-yocto-standard (x86_64)
    flashrom is free software, get the source code at https://flashrom.org
    
    Using regions: "r_bios", "rw_bios".
    (...)
    Requested regions are write protected. Aborting.
    
  6. Try to flash 2 ranges in different regions one unprotected and one protected

    bash-5.2# flashrom -p internal -l layout -i freg0 -i r_bios -w backup.rom
    flashrom 1.5.0-devel (git:v1.2-1581-g4dc3fa98) on Linux 6.6.21-yocto-standard (x86_64)
    flashrom is free software, get the source code at https://flashrom.org
    
    Using regions: "r_bios", "freg0".
    (...)
    Requested regions are write protected. Aborting.
    
  7. Try to flash unprotected part of BIOS region.
    Erase/write was likely skipped as requested ranges are identical.

    bash-5.2# flashrom -p internal -l layout -i rw_bios -w backup.rom
    flashrom 1.5.0-devel (git:v1.2-1581-g4dc3fa98) on Linux 6.6.21-yocto-standard (x86_64)
    flashrom is free software, get the source code at https://flashrom.org
    
    Using region: "rw_bios".
    coreboot table found at 0x76a14000.
    Found chipset "Intel Alder Lake-P".
    Enabling flash write... Warning: BIOS region SMM protection is enabled!
    Warning: Setting BIOS Control at 0xdc from 0xaa to 0x89 failed.
    New value is 0xaa.
    SPI Configuration is locked down.
    FREG0: Flash Descriptor region (0x00000000-0x00000fff) is read-write.
    FREG1: BIOS region (0x00580000-0x00ffffff) is read-write.
    FREG2: Management Engine region (0x00001000-0x003aefff) is read-write.
    PR0: Warning: 0x00b00000-0x00ffffff is read-only.
    At least some flash regions are write protected. For write operations,
    you should use a flash layout and include only writable regions. See
    manpage for more details.
    PROBLEMS, continuing anyway
    Found Macronix flash chip "MX25L12805D" (16384 kB, Programmer-specific) on internal.
    ===
    This flash part has status UNTESTED for operations: WP
    The test status of this chip may have been updated in the latest development
    version of flashrom. If you are running the latest development version,
    please email a report to [email protected] if any of the above operations
    work correctly for you with this flash chip. Please include the flashrom log
    file for all operations you tested (see the man page for details), and mention
    which mainboard or programmer you tested in the subject line.
    You can also try to follow the instructions here:
    https://www.flashrom.org/contrib_howtos/how_to_mark_chip_tested.html
    Thanks for your help!
    Reading old flash chip contents... done.
    Erase/write done from 580000 to 5fffff
    

@m-iwanicki m-iwanicki force-pushed the refuse-flashing-if-protected branch from e7b4efa to ababbe1 Compare December 6, 2024 18:39
@mkopec
Copy link
Member

mkopec commented Dec 13, 2024

Seems to work as described 👍

tested on NV40MB (Tiger Lake)

@@ -20,3 +20,6 @@
/util/ich_descriptors_tool/.obj

target/

subprojects/cmocka-*/
subprojects/packagecache/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either remove or split into a separate commit, please

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

11e7895: those are folders generated by meson test.

flashrom.c Outdated
@@ -1752,6 +1796,13 @@ int prepare_flash_access(struct flashctx *const flash,
return 1;
}

if ((write_it || erase_it) && !flash->flags.force) {
if(write_protect_check(flash)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if(write_protect_check(flash)) {
if (write_protect_check(flash)) {

Please make code style consistent

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -1289,6 +1289,13 @@ struct hwseq_data {
struct fd_region fd_regions[MAX_FD_REGIONS];
};

#define MAX_PR_REGISTERS 6
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this come from a specification?

Copy link
Author

@m-iwanicki m-iwanicki Dec 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I used largest value that could be returned in

flashrom/ichspi.c

Line 2108 in ababbe1

static void init_chipset_properties(struct swseq_data *swseq, struct hwseq_data *hwseq,

{
uint8_t off = reg_pr0 + (i * 4);
uint32_t pr = mmio_readl(ich_spibar + off);
unsigned int rwperms_idx = ICH_PR_PERMS(pr);
enum ich_access_protection rwperms = access_perms_to_protection[rwperms_idx];

prot->base = ICH_FREG_BASE(pr);
prot->limit = ICH_FREG_LIMIT(pr);
prot->write_prot = rwperms == WRITE_PROT;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
prot->write_prot = rwperms == WRITE_PROT;
prot->write_prot = (rwperms == WRITE_PROT) || (rwperms == LOCKED);

I think, at least

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assumed based on

flashrom/ichspi.c

Line 2267 in ababbe1

switch (ich_spi_rw_restricted) {
that LOCKED != write-protected
If I'm reading this correctly in case ich_spi_rw_restricted == LOCKED then warning will only mention that's it's read-protected

ichspi.c Outdated
prot->base = ICH_FREG_BASE(pr);
prot->limit = ICH_FREG_LIMIT(pr);
prot->write_prot = rwperms == WRITE_PROT;
prot->read_prot = rwperms == READ_PROT || rwperms == LOCKED;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
prot->read_prot = rwperms == READ_PROT || rwperms == LOCKED;
prot->read_prot = (rwperms ==READ_PROT) || (rwperms == LOCKED);

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change-Id: Ic39b4acf1da73d093ce3a7df71c1c549d92240d5
Signed-off-by: Michał Iwanicki <[email protected]>
Change-Id: I989006eae97f5e015df20026b6f5361ad41223c1
Signed-off-by: Michał Iwanicki <[email protected]>
Change-Id: Iee172044959df8efd7148adb3a918a7dad963f6f
Signed-off-by: Michał Iwanicki <[email protected]>
Change-Id: I1cdcfacaf61285bf4d7789610461a3f02ea4c64b
Signed-off-by: Michał Iwanicki <[email protected]>
@m-iwanicki m-iwanicki force-pushed the refuse-flashing-if-protected branch from ababbe1 to c80f032 Compare December 18, 2024 08:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants