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

Allow building device paths as constants #983

Open
nicholasbishop opened this issue Oct 30, 2023 · 2 comments
Open

Allow building device paths as constants #983

nicholasbishop opened this issue Oct 30, 2023 · 2 comments

Comments

@nicholasbishop
Copy link
Member

nicholasbishop commented Oct 30, 2023

Splitting this off from #970.

It would be nice to be able to build device paths as global constants as well. This would sidestep the use-after-free issues from nix-community/lanzaboote#194.

Originally posted by @blitz in #970 (comment)

@nicholasbishop
Copy link
Member Author

nicholasbishop commented Nov 2, 2023

I took a look at this, and I think it would be quite difficult to do right now with const types and functions. Many of the tools we want are available in unstable Rust, but it may be a while before it becomes straightforward to do in stable Rust. A couple specific things:

  1. There's no way to call trait methods from const fns (you can't make a const trait, or declare methods in a trait const, or create a const impl of a trait). So the current BuildNode interface wouldn't work at all. There is a fairly straightforward workaround for this one, albeit not super ergonomic: we could generate a big BuildNode enum containing all the node types.
  2. Mutable references are not allowed in const fns. Mutable pointers are, but you can't do much with them; writing and dereferencing are not allowed. So that means you can't pass a byte buffer into a const fn and write to it. The alternative here is to create the byte buffer within the const fn and return it. That works, but copying in the data gets pretty gnarly. You can't use copy_from_slice or anything like that. You could copy the bytes one at a time in a loop, but you can't even use a for loop in a const fn, so it all has to be done very manually and verbosely. EDIT: mut refs in const fns were stabilized in 1.83

Given the difficulties, and the fact that this will (probably) get easier in the future as more things get stabilized, and the fact that I suspect fully const/static device paths are rare, I recommend we not try to add a const device path builder yet. Some potential alternatives for projects that want this:

  1. Generate the device path in build.rs. You can add uefi-rs as a build dependency and use the regular DevicePathBuilder to create a path, then call as_bytes to get the raw bytes. Write those raw bytes out to a file and include_bytes! in your source. Or generate a bit of Rust code containing the raw bytes and include! that.
  2. Hardcode the raw bytes in the static, then have a unit test that creates the same path with DevicePathBuilder. Compare the byte slices and make sure they match.

Lastly, it's totally possible I missed something in my exploration of what const fns can do, and maybe it's not actually as hard to add a const device path builder as I think -- happy to hear if I missed anything!

@phip1611
Copy link
Contributor

phip1611 commented Nov 2, 2023

The approach with build.rs might be a good solution. That's a good idea.

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

No branches or pull requests

2 participants