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

WMI ACPI object conversion rules #1146

Open
Wer-Wolf opened this issue Mar 25, 2024 · 9 comments
Open

WMI ACPI object conversion rules #1146

Wer-Wolf opened this issue Mar 25, 2024 · 9 comments
Assignees
Labels

Comments

@Wer-Wolf
Copy link

The example WMI ACPI code contains no information on how ACPI objects are serialized into the WMI buffer.
According to this article, driver operate on plain WMI buffers for exchanging data.

So far i found out that:

  • ACPI integers seem to be converted into 32 bit WMI integers (even if they are 64 bit long)
  • ACPI buffers are copied as-is
  • ACPI strings are converted into WMI strings

What i do not know is how ACPI Packages are processed and if the ACPI-WMI mapper takes the alignment of the WMI data items into account. Would it be possible to write a short guide about ACPI object conversion rules for firmware developers?

Thanks,
Armin Wolf

@Wer-Wolf
Copy link
Author

Any progress?

@Wer-Wolf
Copy link
Author

I did some research myself, and i found found at that ACPI packages are "unpacked" by converting the data items inside with alignment:

  • integers: 4 byte
  • strings: 2 byte
  • buffers: 1 byte

@Wer-Wolf
Copy link
Author

I also found out that there is a bug inside the wmiacpi.sys driver which can be triggered by returning an ACPI package containing another ACPI package from an ACPI method.

ASL-Code:

Return (Package () {
    0xabcd,
    Buffer () { 0x1 },
    Package () {
            0xfeed,
            "TEST"
    },
    Buffer () { 0x2 },
    0xabcd
}

Result:

cd ab 00 00 // int
01 // Buffer
00 00 // Type 0 (ACPI_METHOD_ARGUMENT_INTEGER)
04 00 // 4 bytes
ed fe 00 00 // int data
01 00 // Type (ACPI_METHOD_ARGUMENT_STRING)
05 00 // 5 bytes
54 45 53 54 00 // string data "TEST"
...

Basically the driver starts to copy raw _ACPI_METHOD_ARGUMENT_V1 structs when encountering a ACPI package, treating it like a ACPI buffer.

Trying to recursively parse such ACPI packages however will allow the firmware to trigger stack overflows, so the best solution would be to just return an error.

@Wer-Wolf
Copy link
Author

Also it seems that there exists a buffer overflow somewhere inside the WMI stack, since when defining an WMI event with a single uint32 payload, the WMI stack somehow accepts ACPI buffers containing only two bytes of data.

The upper two bytes of the resulting uint32 are filled with garbage data, but the lower two bytes contain the data from the buffer.

@yinghany
Copy link
Contributor

yinghany commented Jun 22, 2024 via email

@tomas
Copy link

tomas commented Jun 24, 2024

@yinghany Please don't mention me again in this repo

@Wer-Wolf
Copy link
Author

Wer-Wolf commented Jul 6, 2024

Any progress so far?

@datasoftco
Copy link

datasoftco commented Aug 17, 2024 via email

@Wer-Wolf
Copy link
Author

It also seems that when converting UTF16 WMI strings to ACPI strings, the driver does not return an error when receiving non-ASCII characters, instead the string is modified (ö -> o, etc)

This might cause big issues if firmware developers are not aware of that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants