mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-23 02:05:57 +01:00
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
This commit is contained in:
56
README.adoc
56
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:
|
||||
** <<edu>>
|
||||
** <<qemu-edu>>
|
||||
* added in link:https://github.com/cirosantilli/qemu[our fork of QEMU]:
|
||||
** <<pci_min>>
|
||||
** <<platform_device>>
|
||||
@@ -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 <<graphic-mode,non graphic mode>>, 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 <<rdtsc>>: 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 <<m5-readfile>>
|
||||
** `data/9p`: see <<9p>>
|
||||
** `data/gem5/<variant>`: see: <<gem5-build-variants>>
|
||||
* `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>`: arch specific outputs
|
||||
*** `out/<arch>/buildroot`: standard Buildroot output
|
||||
|
||||
@@ -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[]
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
/* https://github.com/cirosantilli/linux-kernel-module-cheat#file-operations */
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/errno.h> /* EFAULT */
|
||||
#include <linux/fs.h> /* file_operations */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
/* https://github.com/cirosantilli/linux-kernel-module-cheat#pci_min */
|
||||
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
/*
|
||||
ARM only.
|
||||
*/
|
||||
/* https://github.com/cirosantilli/linux-kernel-module-cheat#pmccntr */
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/errno.h> /* EFAULT */
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
/* https://github.com/cirosantilli/linux-kernel-module-cheat#qemu-edu */
|
||||
|
||||
#include <linux/cdev.h> /* cdev_ */
|
||||
#include <linux/fs.h>
|
||||
#include <linux/init.h>
|
||||
@@ -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 <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
@@ -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;
|
||||
|
||||
@@ -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[]
|
||||
|
||||
@@ -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__)
|
||||
|
||||
|
||||
0
rootfs_overlay/vermagic.sh
Normal file → Executable file
0
rootfs_overlay/vermagic.sh
Normal file → Executable file
Reference in New Issue
Block a user