Merge pull request #1676 from t-koulouris/theo_pr

Numerous fixes and updates for the okernel project
This commit is contained in:
Rolf Neugebauer 2017-04-20 11:22:33 -05:00 committed by GitHub
commit 90d459a82e
5 changed files with 2982 additions and 1197 deletions

View File

@ -1,20 +1,21 @@
FROM linuxkit/alpine-build-kernel:cfdd576c36a52ed2dd62f237f79eeedc2dd3697b@sha256:3fe08db373a9373ba1616a485858f01ebd2d7a3cb364a099d0ed8b45fa419da2
#ARG KERNEL_PREFIX
ARG KERNEL_VERSION
ARG DEBUG=0
ARG PROXY
#ENV KERNEL_SOURCE=https://github.com/linux-okernel/linux-okernel/archive/ok-${KERNEL_VERSION}.tar.gz
ENV KERNEL_SOURCE=https://github.com/linux-okernel/linux-okernel/archive/linux-okernel.tar.gz
ENV OKERNEL_SOURCE=https://github.com/linux-okernel/linux-okernel/archive/${KERNEL_VERSION}.tar.gz
ENV USPACE_SOURCE=https://github.com/linux-okernel/linux-okernel-components/archive/master.tar.gz
RUN curl -fsSL -x ${PROXY} -o linux-${KERNEL_VERSION}.tar.gz ${KERNEL_SOURCE}
RUN apk --update add openssl openssl-dev
RUN cat linux-${KERNEL_VERSION}.tar.gz | tar --absolute-names -xz && mv /linux-okernel-linux-okernel /linux
RUN if [ -n $HTTP_PROXY ]; then \
curl -fsSL -x ${HTTP_PROXY} -o linux-${KERNEL_VERSION}.tar.gz ${OKERNEL_SOURCE}; \
else \
curl -fsSL -o linux-${KERNEL_VERSION}.tar.gz ${OKERNEL_SOURCE}; \
fi
RUN cat linux-${KERNEL_VERSION}.tar.gz | tar --absolute-names -xz && mv /linux-okernel-${KERNEL_VERSION} /linux
# NOTE: This currently re-uses the 4.9 kernel config with CONFIG_OKERNEL set
COPY kernel_config.okernel /linux/arch/x86/configs/x86_64_defconfig
#COPY kernel_config.debug /linux/debug_config
@ -57,17 +58,23 @@ RUN DVER=$(basename $(find /tmp/kernel-modules/lib/modules/ -mindepth 1 -maxdept
mkdir -p "$dir"/arch/x86 && cp -a arch/x86/include "$dir"/arch/x86/ && \
( cd /tmp && tar cf /kernel-dev.tar usr/src )
RUN printf "KERNEL_SOURCE=${KERNEL_SOURCE}\n" > /kernel-source-info
RUN printf "KERNEL_SOURCE=${OKERNEL_SOURCE}\n" > /kernel-source-info
# Build kernel module from linux-okernel-components
RUN curl -fsSL -x ${PROXY} -o okernel-userspace.tar.gz ${USPACE_SOURCE}
RUN if [ -n $HTTP_PROXY ]; then \
curl -fsSL -x ${HTTP_PROXY} -o okernel-userspace.tar.gz ${USPACE_SOURCE}; \
else \
curl -fsSL -o okernel-userspace.tar.gz ${USPACE_SOURCE}; \
fi
RUN cat okernel-userspace.tar.gz | tar --absolute-names -xz && mv /linux-okernel-components-master /ok_components
WORKDIR /ok_components/test_mappings/kvmod
RUN sed -i 's_~/linux-okernel_/linux_' Makefile
RUN make
RUN mkdir -p /tmp/root/kvmod && cp kernel_vuln.ko /tmp/root/kvmod
WORKDIR /tmp
RUN tar cf /kernel_vuln.tar root
RUN sed -i 's_~/linux-okernel_/linux_' Makefile && \
make && \
mkdir -p /tmp/root/kvmod && cp kernel_vuln.ko /tmp/root/kvmod && \
cd /tmp && \
tar cf /kernel_vuln.tar root
WORKDIR /

View File

@ -3,9 +3,9 @@ DEBUG ?= 0
all: bzImage tag
# We push the image to hub twice, once with the full kernel version of
# "mobylinux/kernel:<kernel version>.<major version>.<minor version>-<n>",
# "linuxkit/kernel:<kernel version>.<major version>.<minor version>-<n>",
# where "<n>" is a monotonically increasing config number, and as
# "mobylinux/kernel:<kernel version>.<major version>.x". This version
# "linuxkit/kernel:<kernel version>.<major version>.x". This version
# number is stored in IMAGE_VERSION.
#
# We expect most users to us the "<kernel version>.<major version>.x"
@ -19,16 +19,29 @@ all: bzImage tag
#
# IMAGE_VERSION is used to determine if a new image should be pushed to hub.
KERNEL_VERSION=4.11-rc4
ifdef KERNEL
ifneq ($(KERNEL),latest)
KERNEL_VERSION=$(KERNEL)
IMAGE_VERSION=$(KERNEL_VERSION)-0
else
KERNEL_VERSION=linux-okernel
IMAGE_VERSION=latest
endif
else
KERNEL_VERSION=linux-okernel
IMAGE_VERSION=latest
endif
IMAGE=okernel
IMAGE_MAJOR_VERSION=4.11.x
DEPS=Dockerfile.okernel Makefile kernel_config.okernel Dockerfile.kvmod
PROXY_URL=$(HTTP_PROXY)
MEDIA_TOYBOX=linuxkit/toybox-media:d7e82a7d19ccc84c9071fa7a88ecaa58ae958f7c@sha256:4c7d25f2be2429cd08417c36e04161cb924e46f3e419ee33a0aa9ff3a0942e02
kernel.tag: $(DEPS)
ifdef PROXY_URL
BUILD=$$( tar cf - $^ | docker build -f $< --build-arg DEBUG=$(DEBUG) --build-arg KERNEL_VERSION=$(KERNEL_VERSION) --build-arg PROXY=$(PROXY_URL) -q - ) && [ -n "$$BUILD" ] && echo "Built $$BUILD" && echo "$$BUILD" > $@
ifdef HTTP_PROXY
BUILD=$$( tar cf - $^ | docker build -f $< --build-arg DEBUG=$(DEBUG) --build-arg KERNEL_VERSION=$(KERNEL_VERSION) --build-arg HTTP_PROXY=$(HTTP_PROXY) -q - ) && [ -n "$$BUILD" ] && echo "Built $$BUILD" && echo "$$BUILD" > $@
else
BUILD=$$( tar cf - $^ | docker build -f $< --build-arg DEBUG=$(DEBUG) --build-arg KERNEL_VERSION=$(KERNEL_VERSION) -q - ) && [ -n "$$BUILD" ] && echo "Built $$BUILD" && echo "$$BUILD" > $@
endif
@ -42,34 +55,31 @@ bzImage: kernel.tag
tar xf kernel_vuln.tar -C kvmod
cp x86_64/bzImage $@
.PHONY: image push tag
MEDIA_TOYBOX=linuxkit/toybox-media:d7e82a7d19ccc84c9071fa7a88ecaa58ae958f7c@sha256:4c7d25f2be2429cd08417c36e04161cb924e46f3e419ee33a0aa9ff3a0942e02
#BASE="$MEDIA_TOYBOX"
IMAGE=kernel
.PHONY: image push tag kvmod
default: push
Dockerfile.media:
printf "FROM $(MEDIA_TOYBOX)\nADD . /\n" > $@
printf "FROM $(MEDIA_TOYBOX)\nCOPY bzImage kernel.tar /\n" > $@
image: Dockerfile.media bzImage kernel.tar Dockerfile.kvmod kvmod/root/kvmod/kernel_vuln.ko $(DEPS)
tar cf - $^ | docker build --no-cache -t $(IMAGE):build -f Dockerfile.media -
tar cf - $^ | docker build --no-cache -t ok-kvmod:$(IMAGE_VERSION) -f Dockerfile.kvmod -
kvmod: Dockerfile.kvmod kvmod/root/kvmod/kernel_vuln.ko $(DEPS)
tar cf - $^ | docker build --no-cache -t okernel-kvmod:$(IMAGE_VERSION) -f Dockerfile.kvmod -
push: image
docker pull mobylinux/$(IMAGE):$(IMAGE_VERSION) || \
(docker tag $(IMAGE):build mobylinux/$(IMAGE):$(IMAGE_VERSION) && \
docker push mobylinux/$(IMAGE):$(IMAGE_VERSION) && \
docker tag $(IMAGE):build mobylinux/$(IMAGE):$(IMAGE_MAJOR_VERSION) && \
docker push mobylinux/$(IMAGE):$(IMAGE_MAJOR_VERSION))
docker pull linuxkit/$(IMAGE):$(IMAGE_VERSION) || \
(docker tag $(IMAGE):build linuxkit/$(IMAGE):$(IMAGE_VERSION) && \
docker push linuxkit/$(IMAGE):$(IMAGE_VERSION) && \
docker tag $(IMAGE):build linuxkit/$(IMAGE):$(IMAGE_MAJOR_VERSION) && \
docker push linuxkit/$(IMAGE):$(IMAGE_MAJOR_VERSION))
docker rmi $(IMAGE):build
rm -f hash
tag: image
(docker tag $(IMAGE):build mobylinux/$(IMAGE):$(IMAGE_VERSION) && \
docker tag $(IMAGE):build mobylinux/$(IMAGE):$(IMAGE_MAJOR_VERSION))
(docker tag $(IMAGE):build linuxkit/$(IMAGE):$(IMAGE_VERSION) && \
docker tag $(IMAGE):build linuxkit/$(IMAGE):$(IMAGE_MAJOR_VERSION))
docker rmi $(IMAGE):build
rm -f hash

View File

@ -1,19 +1,25 @@
Authors: Chris Dalton <cid@hpi.com>, Nigel Edwards <nigel.edwards@hpe.com>
Authors: Chris Dalton <cid@hpi.com>, Nigel Edwards <nigel.edwards@hpe.com>,
Theo Koulouris <theo.koulouris@hpe.com>
# Split Kernel
Similar to the nested-kernel work for BSD by Dautenhan[1], the aim of
the split kernel is to introduce a level of intra-kernel protection
into the kernel so that, amongst other things, we can offer lifetime
guarantees over kernel code and data integrity. Unlike the BSD-based
nested kernel work we are focused on the Linux kernel not BSD and do
make use of HW virtualization features such as Extended Page Tables
Project links:
- okernel sources on GitHub: https://github.com/linux-okernel/linux-okernel
- Userspace components and supporting material:
https://github.com/linux-okernel/linux-okernel-components
Similar to the nested-kernel work for BSD by Dautenhan et al[1], the aim
of the split kernel (okernel) is to introduce a level of intra-kernel
protection into the kernel so that, amongst other things, we can offer
lifetime guarantees over kernel code and data integrity. Unlike the BSD-
based nested kernel work, we are focused on the Linux kernel (not BSD) and
do make use of HW virtualization features such as Extended Page Tables
(EPT) or equivalent to provide protection from malicious kernel
changes. (Our initial prototype is based on Intel x86, but the
intention is to be architecture neutral so we can apply it to other
architectures, including AMD and ARM.)
The split-kernel provides a (protected) virtualized view of the kernel
The split kernel provides a (protected) virtualized view of the kernel
for processes entering the kernel through exceptions, syscalls and
interrupts. Though we make use of hardware features designed to
support virtualization, we do not virtualize at the full virtual
@ -62,25 +68,52 @@ to the NR-mode context.
If a process in NR-mode attempts to change the kernel memory in
conflict with permissions in the lower-level page tables, a VMEXIT (in
the current prototype which uses Intel VMX) is triggered. R-mode is
then entered where will handle the permission violation.
then entered where the permission violation can be handled.
# Integration with LinuxKit
Custom Linux distributions utilizing the split kernel can be readily built
using LinuxKit by simply specifying an okernel Docker image in the `kernel`
section of the OS image YAML specification. See the sample YAML files provided
in [examples](https://github.com/linuxkit/linuxkit/tree/master/projects/okernel/examples).
## Building the split kernel image for LinuxKit
- `make` will build and package the latest version of the split kernel, by
pulling sources from the top-of-tree of the okernel project GitHub
(https://github.com/linux-okernel/linux-okernel).
- Additionally, a specific version of the kernel can be built
by setting the 'KERNEL' environment variable to the appropriate
value, e.g.: `make KERNEL=ok-4.11-rc2`. The value MUST correspond
to a legitimate okernel tag present in the project GitHub
(https://github.com/linux-okernel/linux-okernel/tags) beginning
with __"ok-"__.
`make KERNEL=latest` will build the top-of-tree release, equivalent to `make`.
`make kvmod` or `make KERNEL=NNNNNNNN kvmod` where "NNNNNNNN" is the release
string corresponding to a kernel version, will build the kernel
vulnerability emulation kernel module for that kernel, useful for testing.
# Limitations and Caveats
The current implementation does not have any protection of the kernel
in place yet. It is a demonstration that you can create processes run
them in NR-mode using EPTs with a shared kernel. As a further
demonstrations of the concept, it implements protected memory pages,
in place yet. It is a demonstration that you can create processes and
run them in NR-mode using EPTs with a shared kernel. As a further
demonstration of the concept, it implements protected memory pages,
whereby a process may request a protected memory page which will not
be mapped into the EPTs for other processes.
## Roadmap
The next step, and the subject of our ongoing research is to design
the memory protection architecture for the kernel. Examples of the
things that we are considering protecting from root mode processes
are:
- Protection of the page tables (no NR mode process can modify an
page table)
- Protection of kernel executable code RX only
- Protection of kernel data structures RO
- Protection of the page tables (no NR mode process can modify a
page table)
- Protection of kernel executable code (RX only)
- Protection of kernel data structures (RO)
# References
@ -92,5 +125,4 @@ Programming Languages and Operating Systems, March 2015.
- [2] Dune: Safe user-level access to privileged CPU features, Adam
Belay, Andrea Bittau, Ali Mashtizadeh, David Terei, David Mazières,
and Christos Kozyrakis, OSDI '12, Proceedings of the 10th USENIX
Symposium on Operating Systems Design and Implementation, October
2012.
Symposium on Operating Systems Design and Implementation, October 2012.

View File

@ -0,0 +1,49 @@
kernel:
image: "linuxkit/okernel:latest"
cmdline: "console=ttyS0 console=tty0 page_poison=1"
init:
- linuxkit/init:63eed9ca7a09d2ce4c0c5e7238ac005fa44f564b
- linuxkit/runc:b0fb122e10dbb7e4e45115177a61a3f8d68c19a9
- linuxkit/containerd:18eaf72f3f4f9a9f29ca1951f66df701f873060b
- linuxkit/ca-certificates:eabc5a6e59f05aa91529d80e9a595b85b046f935
onboot:
- name: sysctl
image: "linuxkit/sysctl:2cf2f9d5b4d314ba1bfc22b2fe931924af666d8c"
net: host
pid: host
ipc: host
capabilities:
- CAP_SYS_ADMIN
services:
- name: rngd
image: "linuxkit/rngd:3dad6dd43270fa632ac031e99d1947f20b22eec9"
capabilities:
- CAP_SYS_ADMIN
oomScoreAdj: -800
- name: dhcpcd
image: "linuxkit/dhcpcd:48e249ebef6a521eed886b3bce032db69fbb4afa"
binds:
- /var:/var
- /tmp:/etc
capabilities:
- CAP_NET_ADMIN
- CAP_NET_BIND_SERVICE
- CAP_NET_RAW
net: host
oomScoreAdj: -800
- name: sshd
image: "linuxkit/sshd:e108d208adf692c8a0954f602743e0eec445364e"
capabilities:
- all
net: host
pid: host
binds:
- /root/.ssh:/root/.ssh
- /etc/resolv.conf:/etc/resolv.conf
files:
- path: root/.ssh/authorized_keys
contents: '#your ssh key here'
outputs:
- format: kernel+initrd
- format: iso-bios
- format: iso-efi

File diff suppressed because it is too large Load Diff