From patchwork Wed Dec 5 22:25:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Samuel Thibault X-Patchwork-Id: 30559 Received: (qmail 11670 invoked by alias); 5 Dec 2018 22:25:39 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 11485 invoked by uid 89); 5 Dec 2018 22:25:37 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.1 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS, SPF_NEUTRAL autolearn=ham version=3.3.2 spammy=bottom, senders, mach, Our X-HELO: hera.aquilenet.fr From: Samuel Thibault To: libc-alpha@sourceware.org Cc: Damien Zammit Subject: [PATCH] Restrict access to PCI cfg io ports to one process Date: Wed, 5 Dec 2018 23:25:27 +0100 Message-Id: <20181205222528.25579-1-samuel.thibault@ens-lyon.org> MIME-Version: 1.0 From: Damien Zammit --- i386/i386/io_perm.c | 27 ++++++++++++++++++++++----- i386/i386/io_perm.h | 2 -- i386/include/mach/i386/mach_i386.defs | 2 -- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/i386/i386/io_perm.c b/i386/i386/io_perm.c index 3224fdd3..086d1d8f 100644 --- a/i386/i386/io_perm.c +++ b/i386/i386/io_perm.c @@ -67,10 +67,22 @@ #include "io_perm.h" #include "gdt.h" #include "pcb.h" + +#define PCI_CFG1_START 0xcf8 +#define PCI_CFG1_END 0xcff +#define PCI_CFG2_START 0xc000 +#define PCI_CFG2_END 0xcfff + +#define IS_IN_PROTECTED_RANGE(from, to) \ + ( ( ( from <= PCI_CFG1_END ) && ( to >= PCI_CFG1_START ) ) || \ + ( ( from <= PCI_CFG2_END ) && ( to >= PCI_CFG2_START ) ) ) + /* Our device emulation ops. See below, at the bottom of this file. */ static struct device_emulation_ops io_perm_device_emulation_ops; +/* Flag to hold PCI io cfg access lock */ +static boolean_t taken_pci_cfg = FALSE; /* The outtran which allows MIG to convert an io_perm_t object to a port representing it. */ @@ -107,17 +119,15 @@ convert_port_to_io_perm (ipc_port_t port) return io_perm; } -#if TODO_REMOVE_ME -/* TODO. Fix this comment. */ /* The destructor which is called when the last send right to a port representing an io_perm_t object vanishes. */ void io_perm_deallocate (io_perm_t io_perm) { - /* TODO. Is there anything to deallocate in here? I don't think so, as we - don't allocate anything in `convert_port_to_io_perm'. */ + /* We need to check if the io_perm was a PCI cfg one and release it */ + if (IS_IN_PROTECTED_RANGE(io_perm->from, io_perm->to)) + taken_pci_cfg = FALSE; } -#endif /* Our ``no senders'' handling routine. Deallocate the object. */ static @@ -185,6 +195,10 @@ i386_io_perm_create (const ipc_port_t master_port, io_port_t from, io_port_t to, if (from > to) return KERN_INVALID_ARGUMENT; + /* Only one process may take a range that includes PCI cfg registers */ + if (taken_pci_cfg && IS_IN_PROTECTED_RANGE(from, to)) + return KERN_PROTECTION_FAILURE; + io_perm_t io_perm; io_perm = (io_perm_t) kalloc (sizeof *io_perm); @@ -216,6 +230,9 @@ i386_io_perm_create (const ipc_port_t master_port, io_port_t from, io_port_t to, *new = io_perm; + if (IS_IN_PROTECTED_RANGE(from, to)) + taken_pci_cfg = TRUE; + return KERN_SUCCESS; } diff --git a/i386/i386/io_perm.h b/i386/i386/io_perm.h index a7f1f6fe..b97cf973 100644 --- a/i386/i386/io_perm.h +++ b/i386/i386/io_perm.h @@ -58,8 +58,6 @@ typedef struct io_perm *io_perm_t; extern io_perm_t convert_port_to_io_perm (ipc_port_t); extern ipc_port_t convert_io_perm_to_port (io_perm_t); -#if TODO_REMOVE_ME extern void io_perm_deallocate (io_perm_t); -#endif #endif /* _I386_IO_PERM_H_ */ diff --git a/i386/include/mach/i386/mach_i386.defs b/i386/include/mach/i386/mach_i386.defs index 0703d59a..a8cb91ce 100644 --- a/i386/include/mach/i386/mach_i386.defs +++ b/i386/include/mach/i386/mach_i386.defs @@ -51,9 +51,7 @@ type io_perm_t = mach_port_t #if KERNEL_SERVER intran: io_perm_t convert_port_to_io_perm(mach_port_t) outtran: mach_port_t convert_io_perm_to_port(io_perm_t) -#if TODO_REMOVE_ME destructor: io_perm_deallocate(io_perm_t) -#endif #endif /* KERNEL_SERVER */ ;