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

add dynamic range configuration #229

Merged
merged 1 commit into from
Apr 10, 2022
Merged

Conversation

Freax13
Copy link
Member

@Freax13 Freax13 commented Apr 6, 2022

This pr makes it possible to restrict the range of dynamically generated addresses.

This is the last step in getting my higher-half kernel to work with full ASLR.

Cargo.toml Outdated Show resolved Hide resolved
Copy link
Member

@phil-opp phil-opp left a comment

Choose a reason for hiding this comment

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

Looks good to me, thanks!

(One thing that we might want to improve in the longer term is the granularity of UsedLevel4Entries. Right now, we always reserve the full level 4 entry for each mapping, and also round the new dynamic range keys accordingly. Ideally, we would manage these all at 4k page level somehow.)

@phil-opp phil-opp merged commit f890cc1 into rust-osdev:main Apr 10, 2022
@Freax13
Copy link
Member Author

Freax13 commented Apr 10, 2022

(One thing that we might want to improve in the longer term is the granularity of UsedLevel4Entries. Right now, we always reserve the full level 4 entry for each mapping, and also round the new dynamic range keys accordingly. Ideally, we would manage these all at 4k page level somehow.)

We could just store the used ranges in an array instead. The size requirements for that scale linearly with the amount of ranges we'd want to support (which aren't all that many), irregardless of the granularity.
The current strategy scales exponentially with the granularity of the buckets (We need 512 bools for keeping track of all level 4 entries, we'd need 512*512 bools for keeping track of all level 3 entries, and so on).

@Freax13 Freax13 deleted the dynamic-range branch April 10, 2022 10:36
@phil-opp
Copy link
Member

Sounds like a good idea to me! The only question is how many array entries we should reserve for mark_segments.

Just FYI: I'm currently working on a new design of this crate in the next branch. The UEFI implementation is already usable and your recent recent PRs (including this one) are integrated too. The only missing part is the BIOS implementation, which I'm actively working on. I just wanted to let you know, in case you want to try it. There are no real build instructions yet, but you can take a look at the tests directory or just ask me for details.

@phil-opp
Copy link
Member

I'm currently working on a new design of this crate in the next branch.

I just opened a draft PR at #232

@Freax13
Copy link
Member Author

Freax13 commented Apr 10, 2022

Sounds like a good idea to me! The only question is how many array entries we should reserve for mark_segments.

Looks like we need up to 8 ranges (as of time of writing):

  • 1x physical memory mapping
  • 1x recursive page table
  • 1x kernel
  • 1x kernel stack
  • 1x boot info
  • 1x frame buffer
  • 2x for marking ranges outside the dynamic range as unusable
    • A new implementation could have a built-in notion of start and end, so we might not have to allocate ranges for marking out address ranges.

Just FYI: I'm currently working on a new design of this crate in the next branch. The UEFI implementation is already usable and your recent recent PRs (including this one) are integrated too. The only missing part is the BIOS implementation, which I'm actively working on. I just wanted to let you know, in case you want to try it. There are no real build instructions yet, but you can take a look at the tests directory or just ask me for details.

Awesome, I'll give it a try in the next few days!

@phil-opp
Copy link
Member

  • 1x kernel

The kernel could have multiple distinct segments, so we need a larger number.

@phil-opp
Copy link
Member

I'm currently having some problems with the rand_chacha dependency that you added. Seems like it uses some SSE state, which causes LLVM errors when trying to compile the bootloader for x86_64-unknown-none. The LLVM error that happens is rust-lang/rust#61721. Do you have any idea why this happens for x86_64-unknown-none, but not for our custom target? Also, is there an alternative to rand_chacha that we can use?

@phil-opp
Copy link
Member

Ok, I replaced it with rand_hc for now.

@Freax13
Copy link
Member Author

Freax13 commented Apr 10, 2022

Do you have any idea why this happens for x86_64-unknown-none, but not for our custom target?

I'm not quite sure, but the x86_64-unknown-none spec disables a few more cpu features than we do:
https://github.com/rust-lang/rust/blob/32c26302620b2dbbe0a2291f1969bc0b1622ae59/compiler/rustc_target/src/spec/x86_64_unknown_none.rs#L24

Ok, I replaced it with rand_hc for now.

That seems like a good alternative.

@Freax13
Copy link
Member Author

Freax13 commented Apr 13, 2022

The kernel could have multiple distinct segments, so we need a larger number.

That's true. I just manually checked all the test kernels and they have between 4 and 8 segments. My kernel has 9.

We could just use a higher capacity e.g 32. Assuming 16 bytes for each entry (8 bytes for address and 8 bytes for the size) that would need 512 bytes which is what we currently also use for the entry_state array.

hawkw added a commit to hawkw/mycelium that referenced this pull request Sep 28, 2022
Version [0.10.13][1] of `bootloader` made it possible to configure the
start address of the dynamic range into which the kernel binary is
mapped (see rust-osdev/bootloader#229). This allows us to configure the
bootloader to boot with the kernel already mapped into the higher half
of the virtual address space, which seems nice.

[1]: https://github.com/rust-osdev/bootloader/blob/main/Changelog.md#01013--2022-09-25
hawkw added a commit to hawkw/mycelium that referenced this pull request Sep 28, 2022
Version [0.10.13][1] of `bootloader` made it possible to configure the
start address of the dynamic range into which the kernel binary is
mapped (see rust-osdev/bootloader#229). This allows us to configure the
bootloader to boot with the kernel already mapped into the higher half
of the virtual address space, which seems nice.

[1]: https://github.com/rust-osdev/bootloader/blob/main/Changelog.md#01013--2022-09-25
hawkw added a commit to hawkw/mycelium that referenced this pull request Sep 28, 2022
Version [0.10.13][1] of `bootloader` made it possible to configure the
start address of the dynamic range into which the kernel binary is
mapped (see rust-osdev/bootloader#229). This allows us to configure the
bootloader to boot with the kernel already mapped into the higher half
of the virtual address space, which seems nice.

[1]: https://github.com/rust-osdev/bootloader/blob/main/Changelog.md#01013--2022-09-25
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.

3 participants