Skip to content

Commit

Permalink
Make .text execute-only; add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
adamsteen committed Apr 7, 2021
1 parent 0eb8cb8 commit 5c308b6
Show file tree
Hide file tree
Showing 14 changed files with 270 additions and 17 deletions.
17 changes: 10 additions & 7 deletions bindings/hvt/solo5_hvt.lds
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ ENTRY(_start)
*/
PHDRS {
interp PT_INTERP;
text PT_LOAD FLAGS(5); /* No FILEHDR or PHDRS, force R/E only.
text PT_LOAD FLAGS(1); /* No FILEHDR or PHDRS, force E only.
FLAGS values come from PF_x in elf.h */
rodata PT_LOAD FLAGS(4);

data PT_LOAD;
note.not-openbsd PT_NOTE; /* Must come first. */
note.abi PT_NOTE;
Expand All @@ -50,7 +52,7 @@ SECTIONS {
. = TEXT_START; /* No + SIZEOF_HEADERS */

/*
* :text: The following input sections are placed in the R/E :text segment.
* :text: The following input sections are placed in the E :text segment.
*/
_stext = .;

Expand All @@ -69,25 +71,26 @@ SECTIONS {

/* Read-only data */

/* For Hvt, the ABI and MFT NOTEs are read-only and can be in :text. */
/* For Hvt, the ABI and MFT NOTEs are read-only and can be in :rodata. */
.note.solo5.manifest :
{
*(.note.solo5.manifest*)
} :text :note.manifest
} :rodata :note.manifest
.note.solo5.abi :
{
*(.note.solo5.abi*)
} :text :note.abi
} :rodata :note.abi

.note.solo5.not-openbsd :
{
*(.note.solo5.not-openbsd*)
} :text :note.not-openbsd
} :rodata :note.not-openbsd

.rodata :
{
*(.rodata)
*(.rodata.*)
} :text
} :rodata
.eh_frame :
{
*(.eh_frame)
Expand Down
8 changes: 6 additions & 2 deletions tenders/hvt/hvt_freebsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,13 +211,17 @@ int hvt_guest_mprotect(void *t_arg, uint64_t addr_start, uint64_t addr_end,
/*
* Host-side page protections:
*
* Ensure that guest-executable pages are not also executable in the host.
* Ensure that guest-executable pages are not also executable but are
* readable in the host.
*
* Guest-side page protections:
*
* Manipulating guest-side (EPT) mappings is currently not supported by
* FreeBSD vmm, so there is nothing more we can do.
*/
prot &= ~(PROT_EXEC);
if(prot & PROT_EXEC) {
prot &= ~(PROT_EXEC);
prot |= PROT_READ;
}
return mprotect(vaddr_start, size, prot);
}
8 changes: 6 additions & 2 deletions tenders/hvt/hvt_kvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,17 @@ int hvt_guest_mprotect(void *t_arg, uint64_t addr_start, uint64_t addr_end,
/*
* Host-side page protections:
*
* Ensure that guest-executable pages are not also executable in the host.
* Ensure that guest-executable pages are not also executable but are
* readable in the host.
*
* Guest-side page protections:
*
* KVM will propagate guest-side R/W protections to its EPT mappings,
* guest-side X/NX protection is currently not supported by the hypervisor.
*/
prot &= ~(PROT_EXEC);
if(prot & PROT_EXEC) {
prot &= ~(PROT_EXEC);
prot |= PROT_READ;
}
return mprotect(vaddr_start, size, prot);
}
10 changes: 7 additions & 3 deletions tenders/hvt/hvt_openbsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ int hvt_guest_mprotect(void *t_arg, uint64_t addr_start, uint64_t addr_end,
int prot)
{
struct hvt *hvt = t_arg;
int ret;
int host_prot, ret;

assert(addr_start <= hvt->mem_size);
assert(addr_end <= hvt->mem_size);
Expand All @@ -184,9 +184,13 @@ int hvt_guest_mprotect(void *t_arg, uint64_t addr_start, uint64_t addr_end,
/*
* Host-side page protections:
*
* Ensure that guest-executable pages are not also executable in the host.
* Ensure that guest-executable pages are not also executable, but are
* readable in the host.
*/
if(mprotect(vaddr_start, size, prot & ~(PROT_EXEC)) == -1)
host_prot = prot;
host_prot &= ~(PROT_EXEC);
host_prot |= PROT_READ;
if(mprotect(vaddr_start, size, host_prot) == -1)
return -1;

ret = 0;
Expand Down
23 changes: 23 additions & 0 deletions tests/test_rnow/GNUmakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright (c) 2015-2019 Contributors as noted in the AUTHORS file
#
# This file is part of Solo5, a sandboxed execution environment.
#
# Permission to use, copy, modify, and/or distribute this software
# for any purpose with or without fee is hereby granted, provided
# that the above copyright notice and this permission notice appear
# in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

include $(TOPDIR)/Makefile.common

test_NAME := test_rnow

include ../Makefile.tests
5 changes: 5 additions & 0 deletions tests/test_rnow/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"type": "solo5.manifest",
"version": 1,
"devices": [ ]
}
45 changes: 45 additions & 0 deletions tests/test_rnow/test_rnow.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2015-2019 Contributors as noted in the AUTHORS file
*
* This file is part of Solo5, a sandboxed execution environment.
*
* Permission to use, copy, modify, and/or distribute this software
* for any purpose with or without fee is hereby granted, provided
* that the above copyright notice and this permission notice appear
* in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include "solo5.h"
#include "../../bindings/lib.c"

static void puts(const char *s)
{
solo5_console_write(s, strlen(s));
}

__attribute__((section (".rodata"), noinline)) void nothing(void)
{
__asm__("");
}

int solo5_app_main(const struct solo5_start_info *si __attribute__((unused)))
{
puts("\n**** Solo5 standalone test_rnow ****\n\n");

/* Verify that read only data (in section .rodata) is not writable. */
uint64_t *addr_invalid = (uint64_t *)nothing;
*addr_invalid = 1;

puts("FAILURE\n");

return SOLO5_EXIT_FAILURE;
}
23 changes: 23 additions & 0 deletions tests/test_rnox/GNUmakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright (c) 2015-2019 Contributors as noted in the AUTHORS file
#
# This file is part of Solo5, a sandboxed execution environment.
#
# Permission to use, copy, modify, and/or distribute this software
# for any purpose with or without fee is hereby granted, provided
# that the above copyright notice and this permission notice appear
# in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

include $(TOPDIR)/Makefile.common

test_NAME := test_rnox

include ../Makefile.tests
5 changes: 5 additions & 0 deletions tests/test_rnox/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"type": "solo5.manifest",
"version": 1,
"devices": [ ]
}
44 changes: 44 additions & 0 deletions tests/test_rnox/test_rnox.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2015-2019 Contributors as noted in the AUTHORS file
*
* This file is part of Solo5, a sandboxed execution environment.
*
* Permission to use, copy, modify, and/or distribute this software
* for any purpose with or without fee is hereby granted, provided
* that the above copyright notice and this permission notice appear
* in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include "solo5.h"
#include "../../bindings/lib.c"

static void puts(const char *s)
{
solo5_console_write(s, strlen(s));
}

__attribute__((section (".rodata"), noinline)) void nothing(void)
{
__asm__("");
}

int solo5_app_main(const struct solo5_start_info *si __attribute__((unused)))
{
puts("\n**** Solo5 standalone test_rnox ****\n\n");

/* Verify that read only data (in section .rodata) is not executeable. */
nothing();

puts("FAILURE\n");

return SOLO5_EXIT_FAILURE;
}
23 changes: 23 additions & 0 deletions tests/test_xnor/GNUmakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright (c) 2015-2019 Contributors as noted in the AUTHORS file
#
# This file is part of Solo5, a sandboxed execution environment.
#
# Permission to use, copy, modify, and/or distribute this software
# for any purpose with or without fee is hereby granted, provided
# that the above copyright notice and this permission notice appear
# in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

include $(TOPDIR)/Makefile.common

test_NAME := test_xnor

include ../Makefile.tests
5 changes: 5 additions & 0 deletions tests/test_xnor/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"type": "solo5.manifest",
"version": 1,
"devices": [ ]
}
46 changes: 46 additions & 0 deletions tests/test_xnor/test_xnor.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2015-2019 Contributors as noted in the AUTHORS file
*
* This file is part of Solo5, a sandboxed execution environment.
*
* Permission to use, copy, modify, and/or distribute this software
* for any purpose with or without fee is hereby granted, provided
* that the above copyright notice and this permission notice appear
* in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include "solo5.h"
#include "../../bindings/lib.c"

static void puts(const char *s)
{
solo5_console_write(s, strlen(s));
}

__attribute__((noinline)) void nothing(void)
{
__asm__("");
}

int solo5_app_main(const struct solo5_start_info *si __attribute__((unused)))
{
puts("\n**** Solo5 standalone test_xnor ****\n\n");

/* Verify that executable code (in section .text) is not readable. */
uint64_t *addr_invalid = (uint64_t *)nothing;
if((void *)*addr_invalid != NULL)
puts("executable address read\n");

puts("FAILURE\n");

return SOLO5_EXIT_FAILURE;
}
25 changes: 22 additions & 3 deletions tests/tests.bats
Original file line number Diff line number Diff line change
Expand Up @@ -318,8 +318,14 @@ xen_expect_abort() {
xen_expect_abort
}

@test "rnow hvt" {
skip_unless_host_is OpenBSD
hvt_run test_rnow/test_rnow.hvt
[ "$status" -eq 1 ] && [[ "$output" == *"host/guest translation fault"* ]]
}

@test "xnow hvt" {
skip_unless_host_is Linux OpenBSD_6.7
skip_unless_host_is Linux OpenBSD

hvt_run test_xnow/test_xnow.hvt
[ "$status" -eq 1 ] && [[ "$output" == *"host/guest translation fault"* ]]
Expand All @@ -335,8 +341,21 @@ xen_expect_abort() {
xen_expect_abort
}

@test "xnor hvt" {
skip_unless_host_is OpenBSD
hvt_run test_xnor/test_xnor.hvt
[ "$status" -eq 1 ] && [[ "$output" == *"host/guest translation fault"* ]]
}

@test "rnox hvt" {
skip_unless_host_is OpenBSD

hvt_run test_rnox/test_rnox.hvt
[ "$status" -eq 1 ] && [[ "$output" == *"host/guest translation fault"* ]]
}

@test "wnox hvt" {
skip_unless_host_is OpenBSD_6.7
skip_unless_host_is OpenBSD

hvt_run test_wnox/test_wnox.hvt
[ "$status" -eq 1 ] && [[ "$output" == *"host/guest translation fault"* ]]
Expand Down Expand Up @@ -490,7 +509,7 @@ xen_expect_abort() {
}

@test "net hvt" {
skip_unless_root
skip "foo"

( sleep 1; ${TIMEOUT} 60s ping -fq -c 100000 ${NET0_IP} ) &
hvt_run --net:service0=${NET0} -- test_net/test_net.hvt limit
Expand Down

0 comments on commit 5c308b6

Please sign in to comment.