[HN Gopher] Investigating a vanishing BIOS on the Fujitsu Lifebo...
___________________________________________________________________
Investigating a vanishing BIOS on the Fujitsu Lifebook AH532
Author : timschumi
Score : 111 points
Date : 2024-01-20 18:45 UTC (4 hours ago)
(HTM) web link (blog.timschumi.net)
(TXT) w3m dump (blog.timschumi.net)
| asmor wrote:
| Early UEFI firmware having quirks like this is pretty common, and
| it's also not uncommon for the BIOS Menu and other things you'd
| hope to be persistent (Diagnostics, Secure Erase Tool on Lenovo
| laptops) to just be boot entries with some hardcoded (but not
| absolute) protections.
|
| I remember the opposite problem being the case on the T420 BIOS.
| If you didn't set a newly added entry as NextBoot, it'd just
| disappear after reboot.
| csdvrx wrote:
| The UEFI entries are just regular EFI variables, except they use
| a special GUID: 8BE4DF61-93CA-11D2-AA0D-00E098032B8C cf
| https://stackoverflow.com/questions/67395528/ and the actual
| description in
| https://github.com/erikberglund/AppleNVRAM/blob/master/EFI/8...
| with examples on how to access them from an UEFI shell on
| https://oofhours.com/2019/09/02/geeking-out-with-uefi/
|
| These variables are what `efibootmgr` lists and can change on
| Linux, what `bcdedit /enum firmware` lists on Windows, and what
| GetSetVariable can manipulate on Windows cf
| https://github.com/ProSlatisa/GetSetVariable/tree/master/Var...
|
| Ultimately, each are OS-specific solutions, while it would be
| interesting to make a crossover between efibootmgr and
| GetSetVariable (and that C program) to create a tool working on
| both Linux and Windows with cosmopolitan to restore/hack
| 8BE4DF61-93CA-11D2-AA0D-00E098032B8C variables, because a quick
| search on that magic shows some people have uploaded their efivar
| to github for other models so it must be a common issue!
| timschumi wrote:
| > Ultimately, each are OS-specific solutions, while it would be
| interesting to make a crossover between efibootmgr and
| GetSetVariable (and that C program) to create a tool working on
| both Linux and Windows
|
| I seems that nobody except for Linux (for some not yet
| determined reason) is having issues with retrieving EFI
| variables on this hardware, and one could potentially classify
| this as a bug in `efibootmgr` as well (due to how it handles
| creating the new entry in unknown conditions).
|
| In either case, Linux is the only thing affected by this, so in
| real-world setups Linux is going to be the only boot option
| that is available while the boot menu is in a broken state.
| crote wrote:
| There's a pretty decent chance nobody else is actually
| _trying_. The only other OS getting installed is Windows, and
| that 's probably coming straight from a disk image or a
| recovery partition.
|
| Especially in laptops, a lot of hardware / firmware issues
| are simply "solved" by baking a fix into the pre-installed
| Windows version. It's a solution for 99% of users, so why
| bother spending time looking into the root cause?
| peppermint_gum wrote:
| >There's a pretty decent chance nobody else is actually
| trying. The only other OS getting installed is Windows, and
| that's probably coming straight from a disk image or a
| recovery partition.
|
| From TFA: "Note: At this point, I checked that Windows and
| various other UEFI tools are able to read the variables
| just fine, so Linux' output is confirmed to be incorrect."
| csdvrx wrote:
| > From TFA: "Note: At this point, I checked that Windows
| and various other UEFI tools are able to read the
| variables just fine, so Linux' output is confirmed to be
| incorrect."
|
| UEFI is a bit complicated and it's well known the EDD3
| specifications can cause issues to efibootmgr, for
| example on Dell
| https://github.com/rhboot/efibootmgr/issues/86
|
| I just think it'd be nicer to have a multiplatform way to
| tweak UEFI boot variable, so you can fiddle with your
| UEFI variables from either Linux or Windows without
| having to actually go into the UEFI shell or use a PE32
| like RU.EFI : https://ruexe.blogspot.com/
| timschumi wrote:
| > The only other OS getting installed is Windows, and
| that's probably coming straight from a disk image or a
| recovery partition.
|
| > Especially in laptops, a lot of hardware / firmware
| issues are simply "solved" by baking a fix into the pre-
| installed Windows version. It's a solution for 99% of
| users, so why bother spending time looking into the root
| cause?
|
| The Windows versions I installed for testing were non-OEM
| versions. They still behaved as expected.
|
| Notably, Windows didn't just know about all the standard
| UEFI variables, but also about a non-standard one that I
| added for testing. This means that there definitely is a
| way to ask for the list of variables so that the UEFI
| accepts it (sadly, reverse engineering that is a pain), and
| that the Linux kernel is most likely the place where an
| actual fix has to happen.
|
| Of course, yes, at the end of the day, the root cause is a
| specification non-conformity in the UEFI itself.
| csdvrx wrote:
| > (sadly, reverse engineering that is a pain), and that
| the Linux kernel is most likely the place where an actual
| fix has to happen.
|
| You did most of the work already, and it's super
| interesting (or at least, it's the kind of things I find
| super interesting lol) so you may want to finish fixing
| the issue?
|
| It's funny how outside RU.EFI, there're no nice tools for
| such a basic features as tweaking UEFI variables, so if
| you are into this kind of things, you may also be
| interested by writing a better efibootmgr: many people
| (including myself, and now you) are dissatisfied by the
| issues it can create: https://old.reddit.com/r/archlinux/
| comments/18j6o7x/rfc_what...
| dishsoap wrote:
| > Especially in laptops, a lot of hardware / firmware
| issues are simply "solved" by baking a fix into the pre-
| installed Windows version. It's a solution for 99% of
| users, so why bother spending time looking into the root
| cause?
|
| I've never really seen a single example of this. Could you
| provide some?
| cjbprime wrote:
| Is there any indication why Linux can't read these efivars? That
| seems like a short fix away from the research already done, and
| would take care of everything. (Once you have the C skills
| already demonstrated in the post, kernel code is not especially
| difficult to debug.)
| timschumi wrote:
| As far as I have tracked it down (quite literally up to the
| point where it switches into the EFI context to run the
| respective service handler), the UEFI denies a call to
| `GetNextVariableName` with `EFI_INVALID_PARAMETER` (that part
| is actually indicated in `dmesg`) even though the request
| appears to be specification-compliant (and the existing
| implementation evidently hasn't been an issue on any other
| notable hardware).
|
| The main issue with fixing it properly is that I'd most likely
| have to reverse engineer the Windows kernel or the UEFI
| firmware itself (note to self: I haven't yet checked whether
| any of the *BSDs can read EFI variables in general and on this
| hardware in particular) to figure out where the request is
| going wrong/what Windows is doing different.
|
| It's not impossible, given that one can unpack the UEFI PI
| firmware image into all the separate modules, but going through
| them to figure out where variable management is implemented
| will still take me a few weeks at least (not due to any
| particular challenge, it's just consuming a lot of time that I
| don't have right now).
| cjbprime wrote:
| Makes sense! I wonder if there is a way to dynamically watch
| the Windows call, to compare it with the Linux one, to avoid
| the tedious reverse engineering. Or if the syntax of Windows
| GetNextVariableName() use is generally understood/documented?
|
| This could happen either through somehow getting logging from
| the Windows end, or somehow changing the UEFI to be one you
| control and logging there, or finding a different BIOS/OS
| that can read the vars and getting it to log its work.
| timschumi wrote:
| > Makes sense! I wonder if there is a way to dynamically
| watch the Windows call, to compare it with the Linux one,
| to avoid the tedious reverse engineering. Or if the syntax
| of Windows GetNextVariableName() use is generally
| understood/documented?
|
| The userspace interface is somewhat documented by third-
| parties (because it is technically internal). However, the
| important parts happen kernel side, and I'd rather avoid
| diving too deep into Windows because some very interesting
| job postings (understandably) have "No exposure to
| Microsoft code or reverse-engineering of Microsoft
| software" in them.
|
| I already tried getting to the service handler
| implementation via Linux, but memory protections made it
| weird enough that I was even questioning whether it was
| returning correct raw data when trying to read it from
| memory (or I have been looking at the wrong set of
| headers).
| yonatan8070 wrote:
| > or somehow changing the UEFI to be one you control
|
| wouldn't that be trivial simply using a VM?
|
| I don't know a thing about BIOS internals, so this might be
| completely irrelevant
| mjg59 wrote:
| Last I checked (which was about a decade ago) Windows
| doesn't call GetNextVariableName() - it just accesses
| variables on demand. We should probably handle that in a
| cleaner way.
| timschumi wrote:
| It seems like that is no longer the case. I was able to
| successfully retrieve a non-standard variable using the
| `UEFIv2` PowerShell module [1] (which is just a thin
| wrapper around the undocumented
| `NtEnumerateSystemEnvironmentValuesEx` function) without
| actually naming the variable in question.
|
| To the untrained layman like me, this sounds like Windows
| actually is querying via `GetNextVariableName`, because
| UEFI doesn't seem to offer any other interfaces that
| aren't "get/set variable by name".
|
| [1] https://www.powershellgallery.com/packages/UEFIv2
| csdvrx wrote:
| > The main issue with fixing it properly is that I'd most
| likely have to reverse engineer the Windows kernel or the
| UEFI firmware itself
|
| Before doing such complicated things, have you tried with
| RU.EFI?
| timschumi wrote:
| I haven't, and (as I already said) I also haven't tried any
| of the BSDs yet. I put both on the list of things to try.
| drewg123 wrote:
| FreeBSD can read and manipulate EFI variables in general. It
| would be interesting to see what happens when you try efivar
| or efibootmgr in FreeBSD.
|
| Grab the memstick image from here:
| https://download.freebsd.org/releases/ISO-IMAGES/14.0/
|
| Uncompress it, and dd it to your USB drive. (dd
| if=FreeBSD-14.0-RELEASE-amd64-memstick.img of=/dev/sdb bs=1m
| conv=sync, assuming sdb is your usb stick..)
| jandrese wrote:
| One thing I've gotten used to over the years is Linux
| complaining that some part of the machine's EFI is buggy no
| matter what machine it is installed on. Apparently it's just
| too complicated for hardware manufacturers to get right. I
| also feel like there is far too much duplicated effort in the
| industry with everybody making their own version that is
| slightly buggy in a unique way.
| js2 wrote:
| > I made an image of the Winbond 25Q32BVSIG SPI flash chip.
|
| I'd love a footnote explaining how you did this.
| csdvrx wrote:
| If I may guess, with a dongle supported by flashrom, soldering
| wires to the flash chip, and a lot of patience - because doing
| the same thing from say linux can run into permission problems:
| the firmware really doesn't want you to read the flash chip.
| timschumi wrote:
| Luckily, it was the type of flash chip that I could use an
| external programmer and a test clip for. I haven't actually
| ever tried reading/writing through the internal programmer.
| Scoundreller wrote:
| Test clip? Fancy!
|
| Had to reflash an SOIC i2c chip before and just soldered
| wires on. Some pins are easier where you have a via to
| solder to instead of the pin. Had to _carefully_ lift the
| VCC pin to avoid turning on the whole board. Not all is
| lost if you break a pin: can _carefully_ file down a bit of
| the plastic chip encapsulation to expose some pin to
| rebridge it once complete.
|
| It's really nice to see how much cheaper ZIF sockets, test
| clips and programmers have gotten over the last few
| decades.
| timschumi wrote:
| I guessed which chip it was (with a little bit of help from
| leaked schematics for similar laptop models), bought the first
| programmer that I saw online that appeared to be compatible
| (anything with a CH341A in it, apparently) and ran `flashrom
| --programmer ch341a_spi -r bios.bin`.
|
| Had there been any more than one possible type of chip and more
| than three of these similar looking chips on the [accessible
| part of the] motherboard, I'd probably still be sitting here
| trying to figure out what to do.
|
| In any case, I'll try and add it to the blog post once I figure
| out how to do footnotes. :^)
| xlii wrote:
| Around 20 years ago I had Fujitsu Siemens V3505 that beyond
| giving me a lot of grief when it came to get it to work ACPI,
| hardware buttons or getting FN-less function keys it had weird
| characteristic of requiring motherboard replacement every single
| time I installed Linux on it.
|
| As it was advertised as OpenSUSE compatible (and even came with
| stickers and such) first one or two times they made a fuss about
| it, but after that they replaced pretty much on the demand.
|
| I wonder if that was also related to the issue article was
| mentioning. But such design lasting for multiple years?
| dataflow wrote:
| Confused, this only occurred during _installation_? Not booting
| after the OS was installed?
___________________________________________________________________
(page generated 2024-01-20 23:00 UTC)