7 ms·
Why couldn't a future OS update add access control to these registers?
by herpderperator 5y ago
Why couldn't a future OS update add access control to these registers?
- josephcsible 5y agoBecause the CPU doesn't provide a practical means to do so.
- herpderperator 5y agoDoesn't the kernel control CPU access?
- kevingadd 5y agoRegisters aren't resources you access through syscalls, there's no way for the kernel to control them unless you're running under virtualization or the CPU architecture specifically allows access control for the register. (As the site notes, virtualization allows controlling access to this register)
- kolbusa 5y agoCan kernel scan each page it maps as executable and return an error if it finds instructions interacting with the 'bad' register? Assuming the kernel requires executable pages to be read-only (W^X), this may even be doable (but probably very very slow).
- josephcsible 5y ago> Assuming the kernel requires executable pages to be read-only (W^X) Which macOS's kernel doesn't.
- marcan_42 5y agoIt does require that, but it allows flipping between RX and RW at will (for JITs), and the M1 actually has proprietary features to allow userspace to do this without involving the kernel, so the kernel couldn't re-scan when those flips happen (plus it would kill performance anyway). Plus, as I said above, this is prone to false positives anyway because the executable section on ARM also includes constant pools.
- josephcsible 5y agoCan't a MAP_JIT region be writable by one thread and executable by a different thread at the same time?
- anyfoo 5y agohttps://developer.apple.com/documentation/apple-silicon/porting-just-in-time-compilers-to-apple-silicon https://developer.apple.com/documentation/apple-silicon/port...
- josephcsible 5y agoThat link confirms that it can: > Because pthread_jit_write_protect_np changes only the current thread’s permissions, avoid accessing the same memory region from multiple threads. Giving multiple threads access to the same memory region opens up a potential attack vector, in which one thread has write access and another has executable access to the same region.
- marcan_42 5y agoAh, yes, I forgot about that. So indeed there is no non-racy hook point for the kernel to do such a check, even if it made sense and the RX/RW switch went through the kernel, which it doesn't.
- marcan_42 5y agoThe kernel doesn't get a say in what instructions a userspace program can run, other than what the CPU is designed to allow it to control. The bug is the CPU designers forgot to allow it to control this one.
- saagarjha 5y agoApple could "mitigate" this by refusing to sign code interacting with s3_5_c15_c10_1, I guess.
- josephcsible 5y agoDoesn't Rice's theorem mean that they cannot?
- cokernel_hacker 5y agoI believe that Rice's theorem is about computability, not about whether or not it is possible to validate which CPU instructions a program can contain. With certain restrictions, it is possible to do this: Google Native Client [1] has a verifier which checks that programs it executed did not jump into the middle of other instructions, forbade run-time code generation inside of such programs, etc. [1]: https://en.wikipedia.org/wiki/Google_Native_Client https://en.wikipedia.org/wiki/Google_Native_Client
- josephcsible 5y agoYes, but then you're not just blocking instructions that touch s3_5_c15_c10_1; you're also blocking a bunch of other kinds of instructions too.
- anyfoo 5y ago(What other kinds of instructions? Genuinely asking.) I don't think Rice's Theorem applies here. As a counterexample: On a hypothetical CPU where all instructions have fixed width (e.g. 32 bits), if accessing a register requires the instruction to have, say, the 10th bit set, and all other instructions don't, and if there is no way to generate new instructions (e.g. the CPU only allows execution from ROM), then it is trivial to check whether there is any instruction in ROM that has bit 10 set. The next part I'm less sure how to state it rigorously (I'm not in the field): In our hypothetical CPU, I think disallowing that instruction either lets you remain being Turing Complete or not. In the former case, it's still the case that you can compute everything a Turing Machine can.
- CGamesPlay 5y agoThere's more specific answers here, but in general the answer to this question is "only partly". The kernel is what initially gives your process a time slice on the CPU, by setting an alarm for the CPU to return control to the kernel at the end of the time slice, and then just jumping into your code. During your time slice, you can do anything you want to the CPU, and in general only interrupts (timer interrupts, hardware interrupts, page faults, etc) will cause the kernel to get involved again. There are some specific features that CPU designers add to give extra control to the kernel, but that's a feature of the CPU and it's only when the CPU has explicitly added that type of control.
- saagarjha 5y ago> The kernel is what initially gives your process a time slice on the CPU, by setting an alarm for the CPU to return control to the kernel at the end of the time slice, and then just jumping into your code. Somewhat critically, it will also drop down to EL0.
- anyfoo 5y agoBecause the OS has no say. A running program issues an assembly instruction to the CPU to read or write this register, and the CPU complies. For the OS to have a say, the CPU would need to provide a way where the OS tells it (usually by setting certain values in other registers) that the CPU should not allow access, at least under certain circumstances. The article actually does go into certain situations where the access is more restricted (search for "VHE"), but also in how that does not really apply here.
- slver 5y agoYou gotta access those bits though some instructions though. What if the command pipeline filters those instructions.
- deleted 5y ago[deleted]
- anyfoo 5y agoCan you elaborate what you mean? What is the "command pipeline" here?
- x0054 5y agoYou are working here with CPU registers. At this point the OS has no say, it’s a hardware bug. Not a particularly serious one though.
- slver 5y agoI didn't say the OS filters the pipeline. Modern CPUs have a lot of updateable microcode, including how it handles its command pipeline.
- throwaheyy 5y agoModern x86/x64 CPUs. The M1 might not have updatable microcode.