mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-28 04:24:26 +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 &
|
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.
|
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?
|
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
|
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
|
==== Count boot instructions
|
||||||
|
|
||||||
* https://www.quora.com/How-many-instructions-does-a-typical-Linux-kernel-boot-take
|
* 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.
|
`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.
|
* 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
|
=== 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
|
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:
|
For the more complex interfaces, we focus on simplified educational devices, either:
|
||||||
|
|
||||||
* present in the QEMU upstream:
|
* present in the QEMU upstream:
|
||||||
** <<edu>>
|
** <<qemu-edu>>
|
||||||
* added in link:https://github.com/cirosantilli/qemu[our fork of QEMU]:
|
* added in link:https://github.com/cirosantilli/qemu[our fork of QEMU]:
|
||||||
** <<pci_min>>
|
** <<pci_min>>
|
||||||
** <<platform_device>>
|
** <<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.
|
Probe already does a MMIO write, which generates an IRQ and tests everything.
|
||||||
|
|
||||||
[[edu]]
|
[[qemu-edu]]
|
||||||
===== QEMU edu PCI device
|
===== QEMU edu PCI device
|
||||||
|
|
||||||
Small upstream educational 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
|
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:
|
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
|
* 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:
|
Works because we add to our default QEMU CLI:
|
||||||
|
|
||||||
@@ -6164,7 +6198,7 @@ c
|
|||||||
And in QEMU:
|
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:
|
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
|
==== 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
|
./build -kg && ./run -E '/rdtsc.out;m5 exit;' -g
|
||||||
./gem5-stat
|
./gem5-stat
|
||||||
@@ -7463,7 +7499,7 @@ See also:
|
|||||||
|
|
||||||
===== pmccntr
|
===== 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/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
|
* 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/readfile`: see <<m5-readfile>>
|
||||||
** `data/9p`: see <<9p>>
|
** `data/9p`: see <<9p>>
|
||||||
** `data/gem5/<variant>`: see: <<gem5-build-variants>>
|
** `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`: 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>`: arch specific outputs
|
||||||
*** `out/<arch>/buildroot`: standard Buildroot output
|
*** `out/<arch>/buildroot`: standard Buildroot output
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
= kernel_module
|
https://github.com/cirosantilli/linux-kernel-module-cheat#directory-structure
|
||||||
|
|
||||||
Our kernel modules!
|
|
||||||
|
|
||||||
. Asynchronous
|
. Asynchronous
|
||||||
.. link:irq.c[]
|
.. link:irq.c[]
|
||||||
@@ -9,7 +7,3 @@ Our kernel modules!
|
|||||||
.. link:timer.c[]
|
.. link:timer.c[]
|
||||||
.. link:work_from_work.c[]
|
.. link:work_from_work.c[]
|
||||||
.. link:workqueue_cheat.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/debugfs.h>
|
||||||
#include <linux/errno.h> /* EFAULT */
|
#include <linux/errno.h> /* EFAULT */
|
||||||
#include <linux/fs.h> /* file_operations */
|
#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.
|
* NOTE: This example is works on x86 and powerpc.
|
||||||
* Here's a sample kernel module showing the use of kprobes to dump a
|
* 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/cdev.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
/*
|
/* https://github.com/cirosantilli/linux-kernel-module-cheat#pmccntr */
|
||||||
ARM only.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
#include <linux/errno.h> /* EFAULT */
|
#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/cdev.h> /* cdev_ */
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
/*
|
/* https://github.com/cirosantilli/linux-kernel-module-cheat#config_fortify_source */
|
||||||
https://www.reddit.com/r/hacking/comments/8h4qxk/what_a_buffer_overflow_in_the_linux_kernel_looks/
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.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)
|
static int myinit(void)
|
||||||
{
|
{
|
||||||
|
/* Missing terminaing NUL '\0'. */
|
||||||
char buf[] = {'p', 'w', 'n'};
|
char buf[] = {'p', 'w', 'n'};
|
||||||
pr_info("%llu\n", (long long unsigned)strlen(buf));
|
pr_info("%llu\n", (long long unsigned)strlen(buf));
|
||||||
return 0;
|
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.
|
. link:hello.c[]
|
||||||
|
. link:hello_cpp.cpp[]
|
||||||
`sh` programs are simpler, and installed by copying directly with an overlay.
|
. link:sched_getaffinity.c[]
|
||||||
|
. link:usermem.c[]
|
||||||
C programs require cross compiling, but give us more control over system calls.
|
.. link:pagemap_dump.c[]
|
||||||
|
. inits
|
||||||
These programs can also be compiled and used on host.
|
... link:sleep_forever.c[]
|
||||||
|
... link:poweroff.c[]
|
||||||
. Standalone
|
... link:init_dev_kmsg.c[]
|
||||||
.. link:hello.c[]
|
. link:uio_read.c[]
|
||||||
.. link:hello_cpp.cpp[]
|
. link:rand_check.c[]
|
||||||
.. link:sched_getaffinity.c[]
|
. x86_64
|
||||||
.. link:usermem.c[]
|
.. link:rdtsc.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[]
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
/*
|
/* https://github.com/cirosantilli/linux-kernel-module-cheat#config_proc_events
|
||||||
This file is licensed under the GPL v2 (http://www.gnu.org/licenses/gpl2.txt) (some parts was originally borrowed from proc events example)
|
*
|
||||||
|
* Adapted from: https://stackoverflow.com/questions/6075013/detect-launching-of-programs-on-linux-platform/8255487#8255487
|
||||||
https://stackoverflow.com/questions/6075013/detect-launching-of-programs-on-linux-platform/8255487#8255487
|
*/
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(__aarch64__)
|
#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