Everything is crap.  That includes UEFI.  So apparently some UEFI
firmware thinks it is ok to write to the code segment.  And
technically the standard allows this unless the EFI_MEMORY_RO
attribute is set.  But of course nobody does.

Anyway, give in.  I'll still restrict setting PROT_EXEC a bit even if
it violates the standard.  At least until the first firmware shows up
that genuinly tries to execute code in the data segment.

ok?


Index: arch/arm64/dev/efi.c
===================================================================
RCS file: /cvs/src/sys/arch/arm64/dev/efi.c,v
retrieving revision 1.3
diff -u -p -r1.3 efi.c
--- arch/arm64/dev/efi.c        12 Jan 2018 14:52:55 -0000      1.3
+++ arch/arm64/dev/efi.c        6 Apr 2018 10:19:41 -0000
@@ -125,7 +125,7 @@ efi_attach(struct device *parent, struct
                        vaddr_t va = desc->VirtualStart;
                        paddr_t pa = desc->PhysicalStart;
                        int npages = desc->NumberOfPages;
-                       vm_prot_t prot = PROT_READ;
+                       vm_prot_t prot = PROT_READ | PROT_WRITE;
 
 #ifdef EFI_DEBUG
                        printf("type 0x%x pa 0x%llx va 0x%llx pages 0x%llx attr 
0x%llx\n",
@@ -142,10 +142,20 @@ efi_attach(struct device *parent, struct
                        if ((desc->Attribute & EFI_MEMORY_WB) == 0)
                                pa |= PMAP_DEVICE;
 
+                       /*
+                        * Only make pages marked as runtime service code
+                        * executable.  This violates the standard but it
+                        * seems we can get away with it.
+                        */
                        if (desc->Type == EfiRuntimeServicesCode)
                                prot |= PROT_EXEC;
-                       else
-                               prot |= PROT_WRITE;
+
+                       if (desc->Attribute & EFI_MEMORY_RP)
+                               prot &= ~PROT_READ;
+                       if (desc->Attribute & EFI_MEMORY_XP)
+                               prot &= ~PROT_EXEC;
+                       if (desc->Attribute & EFI_MEMORY_RO)
+                               prot &= ~PROT_WRITE;
 
                        while (npages--) {
                                pmap_enter(sc->sc_pm, va, pa, prot,

Reply via email to