polished the code, removed german comments, fixed minor bugs and adjusted readme
This commit is contained in:
@@ -6,11 +6,13 @@ This kernel module counts all executed syscalls using the `sys_enter` tracepoint
|
||||
Counting can be paused by setting the module's `enabled` parameter to `0`.
|
||||
|
||||
## Usage
|
||||
1. Copy the files
|
||||
Make sure you're running a modern kernel version (4.x+, tested on 7.0.9) on an x86_64 system with mounted debugfs
|
||||
1. Clone the repo
|
||||
1. Install the _kernel headers_ using your package manager
|
||||
1. Comment out `#define USE_ATOMICS` if you'd rather use spinlocks
|
||||
1. Run `sudo make install` to compile and load the module
|
||||
1. Run `sudo make test` to view the module's debugfs output via the included script
|
||||
1. Run `sudo make test` to view the module's debugfs output via the included Scripts
|
||||
or view raw output at `/sys/kernel/debug/syscall_counter`
|
||||
1. Run `echo 0 | sudo tee /sys/module/syscall_counter/parameters/enabled` to pause counting (`echo 1` to resume)
|
||||
|
||||
## Scripts
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ fi
|
||||
|
||||
FILE=/sys/kernel/debug/syscall_counter
|
||||
if [[ -f $FILE ]]; then
|
||||
watch -t -n 0.001 "cat ${FILE} | sort -nr -k2"
|
||||
watch -t -n 0.001 "cat ${FILE} | sort -nr -k1"
|
||||
else
|
||||
echo "[!] $FILE not found, is the module loaded?"
|
||||
fi
|
||||
|
||||
+25
-29
@@ -1,15 +1,16 @@
|
||||
/**
|
||||
* Mit Hilfe von Kernel-Tracepoints Syscalls zählen.
|
||||
* Count kernel syscalls using the sys_enter tracepoint
|
||||
* and expose at debugfs.
|
||||
*
|
||||
* Kompilieren: make
|
||||
* Laden: sudo make install
|
||||
* Testen: cat /sys/kernel/debug/syscall_counter
|
||||
* sudo make test
|
||||
* Entladen: sudo make uninstall
|
||||
* Kernel-Log: sudo dmesg -w
|
||||
* compile: make all
|
||||
* load: sudo make install
|
||||
* test: cat /sys/kernel/debug/syscall_counter
|
||||
* or sudo make test
|
||||
* unload: sudo make uninstall
|
||||
* kernel-log: sudo dmesg -w
|
||||
*
|
||||
* Autor: Magnus Küderli
|
||||
* Lizenz: GPL
|
||||
* Author: Magnus Küderli
|
||||
* License: GPL
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
@@ -28,14 +29,20 @@
|
||||
|
||||
|
||||
// === OPTIONS ===
|
||||
|
||||
// alternative to spinlocks with less performance loss
|
||||
#define USE_ATOMICS
|
||||
|
||||
// header generated by ./gen_syscall_names.sh called in make
|
||||
// optional because it wasnt provided by default
|
||||
#define WANT_SYSCALL_NAMES
|
||||
|
||||
// === === === ===
|
||||
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Magnus Küderli");
|
||||
MODULE_DESCRIPTION("Count the number of syscalls per type and expose the results via debugfs.");
|
||||
|
||||
#ifdef WANT_SYSCALL_NAMES
|
||||
# include "syscall_names.h"
|
||||
# define MAX_SYSCALLS SYSCALL_MAX_ID
|
||||
@@ -44,11 +51,6 @@
|
||||
#endif
|
||||
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Magnus Küderli");
|
||||
MODULE_DESCRIPTION("Count the number of syscalls per type and expose the results via debugfs.");
|
||||
|
||||
|
||||
// === Parameter ===
|
||||
static bool enabled = true;
|
||||
|
||||
@@ -121,12 +123,12 @@ static void probe_sys_enter(void *data, struct pt_regs *regs, long id)
|
||||
id >= MAX_SYSCALLS ||
|
||||
id < 0
|
||||
) {
|
||||
printk(KERN_INFO "Probe recieved syscall id out of bounds\n");
|
||||
printk_ratelimited(KERN_INFO "Probe recieved syscall id out of bounds\n");
|
||||
// id out of bounds;
|
||||
return;
|
||||
}
|
||||
|
||||
// overflow is not realistic (~> 500 years on busy sys)
|
||||
// overflow is not realistic (~> 500 years on a busy sys)
|
||||
#ifndef USE_ATOMICS
|
||||
unsigned long flags;
|
||||
|
||||
@@ -143,11 +145,6 @@ static void probe_sys_enter(void *data, struct pt_regs *regs, long id)
|
||||
|
||||
static int syscall_counter_show(struct seq_file *m, void *v)
|
||||
{
|
||||
/*
|
||||
seq_printf(m, "Systemaufruf-Zähler:\n");
|
||||
seq_printf(m, "--------------------\n");
|
||||
seq_printf(m, "Nr Anzahl Name\n");
|
||||
*/
|
||||
for (long id = 0; id < MAX_SYSCALLS; id++) {
|
||||
#ifdef WANT_SYSCALL_NAMES
|
||||
char const * const name = syscall_name(id);
|
||||
@@ -156,14 +153,13 @@ static int syscall_counter_show(struct seq_file *m, void *v)
|
||||
#endif
|
||||
|
||||
#ifndef USE_ATOMICS
|
||||
spin_lock(&syscalls_lock);
|
||||
spin_lock_irqsav(&syscalls_lock);
|
||||
unsigned long value = syscalls[id];
|
||||
spin_unlock(&syscalls_lock);
|
||||
spin_unlock_irqrestore(&syscalls_lock);
|
||||
#else
|
||||
unsigned long value = atomic64_read(&syscalls[id]);
|
||||
#endif
|
||||
// ohne name, da Header fehlt
|
||||
seq_printf(m, "%-4ld %-8lu %s\n", id, value, name);
|
||||
seq_printf(m, "%-8lu %s [%ld]\n", value, name, id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -187,7 +183,7 @@ static void lookup_sys_enter_tp(struct tracepoint *tp, void *tp_ptr) {
|
||||
|
||||
static int find_sys_enter_tp(struct tracepoint **tp_ptr)
|
||||
{
|
||||
*tp_ptr = NULL; // setzt tp auf NULL
|
||||
*tp_ptr = NULL; // set tp to NULL
|
||||
|
||||
for_each_kernel_tracepoint(lookup_sys_enter_tp, tp_ptr);
|
||||
|
||||
@@ -214,7 +210,7 @@ static int register_tp(void)
|
||||
tp,
|
||||
probe_sys_enter,
|
||||
NULL, // data (inp to probe funct)
|
||||
0 // prio (0 is highest)
|
||||
TRACEPOINT_DEFAULT_PRIO
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
@@ -227,7 +223,7 @@ static void unregister_tp(void)
|
||||
NULL
|
||||
);
|
||||
|
||||
tracepoint_synchronize_unregister(); // gegen use-after-free, invalide mem zugriffe nach entladen
|
||||
tracepoint_synchronize_unregister(); // stops use-after-frees & invalid mem access after unloading
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user