From 5d9418b27612846b4f31af58617ec5163629e5b4 Mon Sep 17 00:00:00 2001 From: Ciro Santilli Date: Fri, 6 Jul 2018 10:00:08 +0100 Subject: [PATCH] bring CONFIG_FORTIFY_SOURCE back from accidental removal... Notice that it is not working anymore. Rename pci.c into qemu_edu.c Organize kernel_module readmes further --- README.adoc | 56 +++++++++++++++++++++----- kernel_module/README.adoc | 8 +--- kernel_module/fops.c | 2 + kernel_module/kprobe_example.c | 5 +++ kernel_module/pci_min.c | 2 + kernel_module/pmccntr.c | 4 +- kernel_module/{pci.c => qemu_edu.c} | 2 + kernel_module/strlen_overflow.c | 5 +-- kernel_module/user/README.adoc | 38 +++++++---------- kernel_module/user/proc_events.c | 9 ++--- rootfs_overlay/{pci.sh => qemu_edu.sh} | 0 rootfs_overlay/vermagic.sh | 0 12 files changed, 79 insertions(+), 52 deletions(-) rename kernel_module/{pci.c => qemu_edu.c} (99%) rename rootfs_overlay/{pci.sh => qemu_edu.sh} (100%) mode change 100644 => 100755 rootfs_overlay/vermagic.sh diff --git a/README.adoc b/README.adoc index e9e2656..a7aceff 100644 --- a/README.adoc +++ b/README.adoc @@ -4473,14 +4473,17 @@ TODO: it does not work if I try to immediately launch `sleep`, why? insmod /kprobe_example.ko && sleep 4 & sleep 4 & .... -Docs: https://github.com/torvalds/linux/blob/v4.16/Documentation/kprobes.txt - I don't think your code can refer to the surrounding kernel code however: the only visible thing is the value of the registers. You can then hack it up to read the stack and read argument values, but do you really want to? There is also a kprobes + ftrace based mechanism with `CONFIG_KPROBE_EVENTS=y` which does read the memory for us based on format strings that indicate type... https://github.com/torvalds/linux/blob/v4.16/Documentation/trace/kprobetrace.txt Horrendous. Used by: https://github.com/brendangregg/perf-tools/blob/98d42a2a1493d2d1c651a5c396e015d4f082eb20/execsnoop +Bibliography: + +* https://github.com/torvalds/linux/blob/v4.16/Documentation/kprobes.txt +* https://github.com/torvalds/linux/blob/v4.17/samples/kprobes/kprobe_example.c + ==== Count boot instructions * https://www.quora.com/How-many-instructions-does-a-typical-Linux-kernel-boot-take @@ -4595,6 +4598,37 @@ I have observed a single match for that instruction, so it must be the init, and `CONFIG_NET=n` did not significantly reduce instruction counts, so maybe replacing `init` is enough. * gem5 simulates memory latencies. So I think that the CPU loops idle while waiting for memory, and counts will be higher. +=== Linux kernel hardening + +Make it harder to get hacked and easier to notice that you were, at the cost of some (small?) runtime overhead. + +==== CONFIG_FORTIFY_SOURCE + +Detects buffer overflows for us: + +.... +./build -C 'CONFIG_FORTIFY_SOURCE=y' -L fortify +./run -F 'insmod /strlen_overflow.ko' -L fortify +.... + +Possible dmesg output: + +.... +strlen_overflow: loading out-of-tree module taints kernel. +detected buffer overflow in strlen +------------[ cut here ]------------ +.... + +followed by a trace. + +You may not get this error because this depends on `strlen` overflowing at least until the next page: if a random `\0` appears soon enough, it won't blow up as desired. + +I did observe this at link:http://github.com/cirosantilli/linux-kernel-module-cheat/commit/1b451a70d46a5c4619992ad4dd2e4b8f5a84c252[1b451a70d46a5c4619992ad4dd2e4b8f5a84c252] but not at link:http://github.com/cirosantilli/linux-kernel-module-cheat/commit/9b4c1984fc2cb04de0b4d62749cc1f8eabf26c6f[9b4c1984fc2cb04de0b4d62749cc1f8eabf26c6f] TODO: find a more reproducible failure. + +Source: link:kernel_module/strlen_overflow.c[] + +Bibliography: https://www.reddit.com/r/hacking/comments/8h4qxk/what_a_buffer_overflow_in_the_linux_kernel_looks/ + === User mode Linux I once got link:https://en.wikipedia.org/wiki/User-mode_Linux[UML] running on a minimal Buildroot setup at: https://unix.stackexchange.com/questions/73203/how-to-create-rootfs-for-user-mode-linux-on-fedora-18/372207#372207 @@ -5337,7 +5371,7 @@ This section documents: For the more complex interfaces, we focus on simplified educational devices, either: * present in the QEMU upstream: -** <> +** <> * added in link:https://github.com/cirosantilli/qemu[our fork of QEMU]: ** <> ** <> @@ -5386,22 +5420,22 @@ Works because we add to our default QEMU CLI: Probe already does a MMIO write, which generates an IRQ and tests everything. -[[edu]] +[[qemu-edu]] ===== QEMU edu PCI device Small upstream educational PCI device: .... -/pci.sh +/qemu_edu.sh .... This tests a lot of features of the edu device, to understand the results, compare the inputs with the documentation of the hardware: https://github.com/qemu/qemu/blob/v2.12.0/docs/specs/edu.txt Sources: -* kernel module: link:kernel_module/pci.c[] +* kernel module: link:kernel_module/qemu_edu.c[] * QEMU device: https://github.com/qemu/qemu/blob/v2.12.0/hw/misc/edu.c -* test script: link:rootfs_overlay/pci.sh[] +* test script: link:rootfs_overlay/qemu_edu.sh[] Works because we add to our default QEMU CLI: @@ -6164,7 +6198,7 @@ c And in QEMU: .... -/pci.sh +/qemu_edu.sh .... When in <>, using `-D` makes Ctrl-C not get passed to the QEMU guest anymore: it is instead captured by GDB itself, so allow breaking. So e.g. you won't be able to easily quit from a guest progra like: @@ -7440,6 +7474,8 @@ Lets try to understand some stats better. ==== rdtsc +link:https://en.wikipedia.org/wiki/Time_Stamp_Counter[x86 instruction] that returns the cycle count since reset: + .... ./build -kg && ./run -E '/rdtsc.out;m5 exit;' -g ./gem5-stat @@ -7463,7 +7499,7 @@ See also: ===== pmccntr -Unfortunately-we didn't manage to find an ARM analogue: link:kernel_module/pmccntr.c[] is oopsing, and even it if weren't, it likely won't give the cycle count since boot since it needs to be activate before it starts counting anything: +TODO We didn't manage to find a working ARM analogue to <>: link:kernel_module/pmccntr.c[] is oopsing, and even it if weren't, it likely won't give the cycle count since boot since it needs to be activate before it starts counting anything: * https://stackoverflow.com/questions/40454157/is-there-an-equivalent-instruction-to-rdtsc-in-arm * https://stackoverflow.com/questions/31620375/arm-cortex-a7-returning-pmccntr-0-in-kernel-mode-and-illegal-instruction-in-u/31649809#31649809 @@ -8349,7 +8385,7 @@ The action seems to be happening at: `hw/arm/virt.c`. ** `data/readfile`: see <> ** `data/9p`: see <<9p>> ** `data/gem5/`: see: <> -* `kernel_module`: Buildroot package that contains our kernel modules and userland C tests +* link:kernel_module[]: Buildroot package that contains our kernel modules and userland C tests * `out`: gitignored Build outputs. You won't lose data by deleting this folder since everything there can be re-generated, only time. ** `out/`: arch specific outputs *** `out//buildroot`: standard Buildroot output diff --git a/kernel_module/README.adoc b/kernel_module/README.adoc index a27240b..7abe138 100644 --- a/kernel_module/README.adoc +++ b/kernel_module/README.adoc @@ -1,6 +1,4 @@ -= kernel_module - -Our kernel modules! +https://github.com/cirosantilli/linux-kernel-module-cheat#directory-structure . Asynchronous .. link:irq.c[] @@ -9,7 +7,3 @@ Our kernel modules! .. link:timer.c[] .. link:work_from_work.c[] .. link:workqueue_cheat.c[] -. Hardening -.. link:strlen_overflow.c[] -. Tracing -.. link:kprobe_example.c[] diff --git a/kernel_module/fops.c b/kernel_module/fops.c index 5ab3fd2..8db361c 100644 --- a/kernel_module/fops.c +++ b/kernel_module/fops.c @@ -1,3 +1,5 @@ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#file-operations */ + #include #include /* EFAULT */ #include /* file_operations */ diff --git a/kernel_module/kprobe_example.c b/kernel_module/kprobe_example.c index fe3e645..fa53ca6 100644 --- a/kernel_module/kprobe_example.c +++ b/kernel_module/kprobe_example.c @@ -1,3 +1,8 @@ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#kprobes + * + * Adapted from: https://github.com/torvalds/linux/blob/v4.17/samples/kprobes/kprobe_example.c + */ + /* * NOTE: This example is works on x86 and powerpc. * Here's a sample kernel module showing the use of kprobes to dump a diff --git a/kernel_module/pci_min.c b/kernel_module/pci_min.c index 8e59581..1b749f3 100644 --- a/kernel_module/pci_min.c +++ b/kernel_module/pci_min.c @@ -1,3 +1,5 @@ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#pci_min */ + #include #include #include diff --git a/kernel_module/pmccntr.c b/kernel_module/pmccntr.c index bd1dca1..4f33f3d 100644 --- a/kernel_module/pmccntr.c +++ b/kernel_module/pmccntr.c @@ -1,6 +1,4 @@ -/* -ARM only. -*/ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#pmccntr */ #include #include /* EFAULT */ diff --git a/kernel_module/pci.c b/kernel_module/qemu_edu.c similarity index 99% rename from kernel_module/pci.c rename to kernel_module/qemu_edu.c index 4f799ac..70f89d1 100644 --- a/kernel_module/pci.c +++ b/kernel_module/qemu_edu.c @@ -1,3 +1,5 @@ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#qemu-edu */ + #include /* cdev_ */ #include #include diff --git a/kernel_module/strlen_overflow.c b/kernel_module/strlen_overflow.c index 66b4728..574fddc 100644 --- a/kernel_module/strlen_overflow.c +++ b/kernel_module/strlen_overflow.c @@ -1,6 +1,4 @@ -/* -https://www.reddit.com/r/hacking/comments/8h4qxk/what_a_buffer_overflow_in_the_linux_kernel_looks/ -*/ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#config_fortify_source */ #include #include @@ -8,6 +6,7 @@ https://www.reddit.com/r/hacking/comments/8h4qxk/what_a_buffer_overflow_in_the_l static int myinit(void) { + /* Missing terminaing NUL '\0'. */ char buf[] = {'p', 'w', 'n'}; pr_info("%llu\n", (long long unsigned)strlen(buf)); return 0; diff --git a/kernel_module/user/README.adoc b/kernel_module/user/README.adoc index 4a8e0a1..de39aa2 100644 --- a/kernel_module/user/README.adoc +++ b/kernel_module/user/README.adoc @@ -1,25 +1,15 @@ -= user +https://github.com/cirosantilli/linux-kernel-module-cheat#rootfs_overlay -Userland C programs used to test our kernel modules. - -`sh` programs are simpler, and installed by copying directly with an overlay. - -C programs require cross compiling, but give us more control over system calls. - -These programs can also be compiled and used on host. - -. Standalone -.. link:hello.c[] -.. link:hello_cpp.cpp[] -.. link:sched_getaffinity.c[] -.. link:usermem.c[] -... link:pagemap_dump.c[] -.. inits -.... link:sleep_forever.c[] -.... link:poweroff.c[] -.... link:init_dev_kmsg.c[] -.. link:uio_read.c[] -.. link:rand_check.c[] -.. x86_64 -... link:rdtsc.c[] -... link:ring0.c[] +. link:hello.c[] +. link:hello_cpp.cpp[] +. link:sched_getaffinity.c[] +. link:usermem.c[] +.. link:pagemap_dump.c[] +. inits +... link:sleep_forever.c[] +... link:poweroff.c[] +... link:init_dev_kmsg.c[] +. link:uio_read.c[] +. link:rand_check.c[] +. x86_64 +.. link:rdtsc.c[] diff --git a/kernel_module/user/proc_events.c b/kernel_module/user/proc_events.c index dff8bb3..5736eb8 100644 --- a/kernel_module/user/proc_events.c +++ b/kernel_module/user/proc_events.c @@ -1,8 +1,7 @@ -/* -This file is licensed under the GPL v2 (http://www.gnu.org/licenses/gpl2.txt) (some parts was originally borrowed from proc events example) - -https://stackoverflow.com/questions/6075013/detect-launching-of-programs-on-linux-platform/8255487#8255487 -*/ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#config_proc_events + * + * Adapted from: https://stackoverflow.com/questions/6075013/detect-launching-of-programs-on-linux-platform/8255487#8255487 + */ #if defined(__aarch64__) diff --git a/rootfs_overlay/pci.sh b/rootfs_overlay/qemu_edu.sh similarity index 100% rename from rootfs_overlay/pci.sh rename to rootfs_overlay/qemu_edu.sh diff --git a/rootfs_overlay/vermagic.sh b/rootfs_overlay/vermagic.sh old mode 100644 new mode 100755