Page MenuHomeFreeBSD

Add stricter checks on user changes to SSTATUS.
ClosedPublic

Authored by jhb on Jan 23 2020, 6:04 PM.
Tags
None
Referenced Files
Unknown Object (File)
Wed, Nov 20, 9:42 PM
Unknown Object (File)
Sep 26 2024, 1:39 PM
Unknown Object (File)
Sep 17 2024, 3:15 PM
Unknown Object (File)
Aug 29 2024, 3:05 AM
Unknown Object (File)
Aug 29 2024, 3:05 AM
Unknown Object (File)
Aug 29 2024, 3:05 AM
Unknown Object (File)
Aug 29 2024, 3:05 AM
Unknown Object (File)
Aug 29 2024, 3:05 AM
Subscribers

Details

Summary

Rather than trying to blacklist which bits userland can't write to
via sigreturn() or setcontext(), only permit changes to whitelisted
bits.

  • Permit arbitrary writes to bits in the user-writable USTATUS register that shadows SSTATUS.
  • Ignore changes in write-only bits maintained by the CPU.
  • Ignore the user-supplied value of the FS field used to track floating point state and instead set it to a value matching the actions taken by set_fpcontext().
Test Plan
  • I have only compiled this, haven't booted it yet.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

mhorne added inline comments.
sys/riscv/riscv/machdep.c
374 ↗(On Diff #67221)

We should also allow for SSTATUS_UXL.

This revision is now accepted and ready to land.Jan 23 2020, 8:25 PM

This is actually broken. It flags what look like changes in SD and FS that are bogus (and we should also ignore XS since it is read-only). For FS, the real fix is that set_fpcontext() needs to be setting that field explicitly based on what it does. It either needs to turn FP off if there was no valid state to save, or it needs to set it to clean since it just restored the registers and they are now all match the saved state. I don't think we want to let userland change UXL though? If we supported riscv32 and freebsd32, then you would set UXL during the freebsd32 exec_setregs(), but it would otherwise need to be static until the next exec?

(I found out the SD and FS stuff while testing it in QEMU btw and am testing the changes I mentioned)

  • Ignore read-only bits and FS in sstatus.
This revision now requires review to proceed.Jan 23 2020, 10:32 PM

This actually boots. The first version would boot in qemu, but /usr/bin/login would fail. I added printfs to the EINVAL case and found that the values of SD and FS were varying triggering the false failures. On further thinking, restoring the original FS would not be correct anyway. It should either be OFF or CLEAN as I said earlier. I didn't read the description of MSTATUS exhaustively, but I don't think there are any other read-only bits in SSTATUS?

jhb retitled this revision from Only permit user changes to USTATUS bits in SSTATUS. to Add stricter checks on user changes to SSTATUS..Jan 28 2020, 11:07 AM
jhb edited the summary of this revision. (Show Details)
In D23338#511790, @jhb wrote:

I don't think we want to let userland change UXL though? If we supported riscv32 and freebsd32, then you would set UXL during the freebsd32 exec_setregs(), but it would otherwise need to be static until the next exec?

Good point, you're right to leave that one out. I had a quick read through the mstatus/sstatus specification and I think what you have now is the subset of bits needed.

sys/riscv/riscv/machdep.c
379 ↗(On Diff #67232)

Beware, the definition of SSTATUS64_SD appears to be incorrect, it's defined as (1 << 31).

sys/riscv/riscv/machdep.c
379 ↗(On Diff #67232)

I fixed it in r357255, and now you can just use SSTATUS_SD.

  • Fixup to use SSTATUS_SD.
This revision was not accepted when it landed; it landed in state Needs Review.Jan 31 2020, 7:00 PM
This revision was automatically updated to reflect the committed changes.