kvm: sentry executable mappings have to be read-only

The sentry guest page tables must not allow to execute writable memory regions.

PiperOrigin-RevId: 426183789
This commit is contained in:
Andrei Vagin
2022-02-03 10:49:57 -08:00
committed by gVisor bot
parent 34f41dfcbf
commit e31c3f18da
2 changed files with 22 additions and 9 deletions
+15 -4
View File
@@ -198,7 +198,7 @@ func (m *machine) createVCPU(id int) *vCPU {
// readOnlyGuestRegions contains regions that have to be mapped read-only into
// the guest physical address space. Right now, it is used on arm64 only.
var readOnlyGuestRegions []region
var readOnlyGuestRegions []virtualRegion
// newMachine returns a new VM context.
func newMachine(vm int) (*machine, error) {
@@ -247,7 +247,7 @@ func newMachine(vm int) (*machine, error) {
m.kernel.PageTables.Map(
hostarch.Addr(pr.virtual),
pr.length,
pagetables.MapOpts{AccessType: hostarch.AnyAccess},
pagetables.MapOpts{AccessType: hostarch.ReadWrite},
pr.physical)
return true // Keep iterating.
@@ -257,7 +257,7 @@ func newMachine(vm int) (*machine, error) {
// available in the VM. Note that this doesn't guarantee no future
// faults, however it should guarantee that everything is available to
// ensure successful vCPU entry.
mapRegion := func(vr region, flags uint32) {
mapRegion := func(vr virtualRegion, flags uint32) {
for virtual := vr.virtual; virtual < vr.virtual+vr.length; {
physical, length, ok := translateToPhysical(virtual)
if !ok {
@@ -269,6 +269,17 @@ func newMachine(vm int) (*machine, error) {
// Cap the length to the end of the area.
length = vr.virtual + vr.length - virtual
}
// Update page tables for executable mappings.
if vr.accessType.Execute {
if vr.accessType.Write {
panic(fmt.Sprintf("executable mapping can't be writable: %#v", vr))
}
m.kernel.PageTables.Map(
hostarch.Addr(virtual),
length,
pagetables.MapOpts{AccessType: vr.accessType},
physical)
}
// Ensure the physical range is mapped.
m.mapPhysical(physical, length, physicalRegions, flags)
@@ -295,7 +306,7 @@ func newMachine(vm int) (*machine, error) {
vr.length += 1 << 20
}
mapRegion(vr.region, 0)
mapRegion(vr, 0)
})
+7 -5
View File
@@ -107,16 +107,18 @@ func archPhysicalRegions(physicalRegions []physicalRegion) []physicalRegion {
return // skip region.
}
if !vr.accessType.Write {
readOnlyGuestRegions = append(readOnlyGuestRegions, vr.region)
readOnlyGuestRegions = append(readOnlyGuestRegions, vr)
}
})
rdRegions := readOnlyGuestRegions[:]
// Add an unreachable region.
rdRegions = append(rdRegions, region{
virtual: 0xffffffffffffffff,
length: 0,
rdRegions = append(rdRegions, virtualRegion{
region: region{
virtual: 0xffffffffffffffff,
length: 0,
},
})
var regions []physicalRegion
@@ -137,7 +139,7 @@ func archPhysicalRegions(physicalRegions []physicalRegion) []physicalRegion {
start := pr.virtual
end := pr.virtual + pr.length
for start < end {
rdRegion := rdRegions[i]
rdRegion := rdRegions[i].region
rdStart := rdRegion.virtual
rdEnd := rdRegion.virtual + rdRegion.length
if rdEnd <= start {