Compare commits

...

58 Commits
v0.9.4 ... main

Author SHA1 Message Date
Solar Designer 3760e0e1bd Fix support for RHEL 9.0
This was very briefly broken with the previous commit
2023-11-08 19:50:58 +01:00
Adam_pi3 310e85d19c Add support for RHEL 8.8
A new 'text_poke_loc' was backported to RHEL 8.8+. This commit brings
the support for such kernels as well as addresses the #295 problem.
2023-11-08 19:39:30 +01:00
Solar Designer ea1454c28d README: More complete "Build requirements" 2023-10-25 22:56:34 +02:00
Solar Designer d5077fde52 RPM:
- Use weak-modules if available so that on RHEL and its rebuilds the same LKRG
  package build works across different kABI-compatible kernel revisions/builds

- Drop 32-bit x86 from ExclusiveArch since recent RHEL lacks such kernel-devel
2023-10-25 22:28:13 +02:00
Adam_pi3 ee41d81599 kINT: Fix synchronization problem
The reported problem with integrity verification on ARM64 (#269)
is a result of a very tight race condition with tracepoints.
Changes which simplify synchronization with JUMP_LABEL engine:
f98da1b17c
affected differently ARM64 platform which made such race possible.
However, potentially the same race problem may exist on x86 and
this commit fixes it and should address #269
2023-10-25 14:56:11 +02:00
Adam_pi3 687c4790cd
kINT: P_LKRG_JUMP_LABEL_STEXT_DEBUG: bump log level
... for better debuggability. If non standard P_LKRG_JUMP_LABEL_STEXT_DEBUG
is enabled, it means that LKRG is being actively debugged.
In that case, we want to avoid unnecessary noise.
2023-10-24 09:46:15 +00:00
Vitaly Chikunov 617cc87a40 CI: mainline: Change base URL
https://kernel.ubuntu.com/~kernel-ppa/mainline/daily/ reporting:
  <title>301 Moved Permanently</title>
  <p>The document has moved <a
  href="https://kernel.ubuntu.com/mainline/daily/">here</a>.</p>

Fixes: https://github.com/lkrg-org/lkrg/issues/292
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
2023-10-12 15:29:03 +02:00
Vitaly Chikunov 73840d7b91 CI: mkosi: Fix mainline boot on Ubuntu mantic
Ubuntu removed 'systemd-gpt-auto-generator' from systemd_253.5-1ubuntu5,
causing dracut to be unable to find the root partition without
assistance. It appears that specifying the root label could be a good
solution.

Fixes: https://github.com/lkrg-org/lkrg/issues/287
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
2023-09-20 15:33:02 +02:00
Solar Designer 91d3da9ece RPM: Use kernel build directory corresponding to kernel-devel 2023-09-14 22:09:33 +02:00
Solar Designer 5dc5cfea1f LKRG 0.9.7 2023-09-14 04:38:28 +02:00
Solar Designer db35e0e207 Add RPM spec file for Red Hat'ish distros 2023-09-14 03:00:43 +02:00
Solar Designer 5cfc92c0a3 CHANGES, README: Update with major changes since 0.9.6 2023-09-11 01:03:23 +02:00
Vitaly Chikunov 544479d704 CI: Update workflows to use latest versions of the actions
This should fix the warning:

  The following actions uses node12 which is deprecated and will be
  forced to run on node16: actions/checkout@v2. For more info:
  https://github.blog/changelog/2023-06-13-github-actions-all-actions-will-run-on-node16-instead-of-node12-by-default/

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
2023-08-26 11:46:31 +02:00
Vitaly Chikunov 1ab0d2e983 CI: Change openSUSE URLs to their official docker registry
Message on https://hub.docker.com/_/opensuse/

  DEPRECATION NOTICE
  These images were removed in favor of the opensuse/leap and
  opensuse/tumbleweed images provided and maintained by the openSUSE
  Project release team.

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
2023-08-25 19:52:21 +02:00
Vitaly Chikunov 69e682b37b CI: Fix docker build on opensuse/tumbleweed
This now requires gawk installed.

Error message:

  make -C /lib/modules/6.4.11-1-default/build M=/__w/lkrg/lkrg modules
  /bin/sh: line 1: awk: command not found
  make[2]: *** [/usr/src/linux-6.4.11-1/scripts/Makefile.build:262: /__w/lkrg/lkrg/lkrg.mod] Error 127
  make[2]: *** Deleting file '/__w/lkrg/lkrg/lkrg.mod'
  make[2]: *** Waiting for unfinished jobs....
    CC [M]  /__w/lkrg/lkrg/src/modules/ksyms/p_resolve_ksym.o
  /usr/src/linux-6.4.11-1/scripts/check-local-export: line 25: awk: command not found
  /usr/src/linux-6.4.11-1/scripts/check-local-export: nm failed
  make[2]: *** [/usr/src/linux-6.4.11-1/scripts/Makefile.build:253: /__w/lkrg/lkrg/src/modules/ksyms/p_resolve_ksym.o] Error 143
  make[2]: *** Deleting file '/__w/lkrg/lkrg/src/modules/ksyms/p_resolve_ksym.o'
  make[1]: *** [../../../linux-6.4.11-1/Makefile:2049: /__w/lkrg/lkrg] Error 2
  make: *** [Makefile💯 all] Error 2

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
2023-08-25 19:52:21 +02:00
Vitaly Chikunov 47191f9b29 CI: mkosi-mainline: Workaround 'dpkg: error: dpkg frontend lock'
Mkosi's own dracut hook, which is triggered from `dpkg -i`, calls
`dpkg-reconfigure` causing dpkg frontend lock conflict. But `initrd.img`
is generated correctly. Workaround by ignoring `dpkg-reconfigure` errors
in the hook.

  dpkg: error: dpkg frontend lock was locked by another process with pid 5
  Note: removing the lock file is always wrong, can damage the locked area
  and the entire system. See <https://wiki.debian.org/Teams/Dpkg/FAQ#db-lock>.
  run-parts: /etc/kernel/postinst.d/zz-systemd-boot exited with return code 2

Link: https://github.com/lkrg-org/lkrg/issues/283
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
2023-08-03 12:30:14 +02:00
Solar Designer 55d28c9f23 Stop using register_sysctl_table()
This is needed for post-6.4 kernels.

Fixes #280
2023-07-15 19:45:48 -08:00
Valentin Obst a78f3e5f3c README: Add remark about lkrg-bootup.sh to DKMS section 2023-07-11 14:23:20 +02:00
Valentin Obst 0f13b59d09 make bootup scripts independent of cwd, add usage and root checks 2023-07-11 14:23:20 +02:00
Solar Designer 64adf26f22 LICENSE, debian/copyright: Correct copyright years 2023-07-10 20:42:55 +02:00
Patrick Schleizer 563dc9a09c Update lkrg-dkms.lintian-overrides for Debian bookworm 2023-06-13 00:55:58 +00:00
Patrick Schleizer 306c430aa7 Update copyright 2023-06-13 00:55:08 +00:00
fluidog 001768de0c Simplify the use of P_SYM_INIT() 2023-05-19 14:09:29 +02:00
Adam_pi3 3d8e52e90b
Add support for Linux kernel post-6.3
Linux kernel post-6.3 modified the 'struct module' and introduced a new
substructure describing module's memory layout. Additionally, the logic for
dynamic debug (ddebug) has been modified and some of the functions which LKRG
uses are no longer exported. This commit adopts to these post-6.3 changed and
addresses #267
2023-05-03 00:47:51 +00:00
Solar Designer f37b478d25 p_exploit_detection.c: Add static keywords to ease code review 2023-03-19 15:18:55 +01:00
Vladimir D. Seleznev eaf8347646 RHEL 9.2 5.14.0-248.el9 aarch64: rename stackframe to unwind_state 2023-02-11 06:39:24 +00:00
RageLtMan ef52dec6e1 Add UMH modprobe path for Arch Linux init context
Address #258 by adding /usr/bin/modprobe to the UMH allow-list.
2023-02-03 06:48:33 +00:00
Adam_pi3 0e46fc41a5
Add support for RHEL 9.1
Starting from kernel 5.14.0-162.12.1 (RHEL 9.1), a new 'text_poke_loc'
structure is used. This commit brings the support for such kernels as
well as addresses the #256 problem
2023-02-02 03:03:35 +00:00
Solar Designer 0fdb556076 kINT: P_LKRG_JUMP_LABEL_STEXT_DEBUG: Fix sign extension bug 2023-01-30 22:40:20 +01:00
Vitaly Chikunov 87159cd74a CI: Use latest usable mkosi v14
Main (and only) branch of mkosi is switching to bleeding edge systemd
tools which are not available on Ubuntu we are testing on. Instead of
migrating off mkosi to something else, we can still use some previously
working tag such as `v14'.

Fixes: https://github.com/lkrg-org/lkrg/issues/253
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
2022-12-25 00:51:26 +01:00
Solar Designer 2481b3e2dd LKRG 0.9.6 2022-12-14 17:05:39 +01:00
Solar Designer 2ab926d202 CHANGES: Document the new kretprobe test 2022-12-09 19:07:56 +01:00
Adam_pi3 26f36ed495 Add a kprobe verification functionality
Add a new logic to the integrity verification routine verifying if the
kprobes are enabled and correctly run.
This commit makes kprobe verification functionality as an independent
module invoked by integrity verification routine as well as during
initialization to make sure kprobes are enabled and run as intended
(otherwise, initialization fails).
2022-12-04 21:31:22 +01:00
Solar Designer 7db7483880 CHANGES, README: Update with major changes since 0.9.5 2022-11-22 19:22:23 +01:00
Adam_pi3 1fc5312223 Add synchronization logic around sysctl interface
This commit fixes the race problem between 2+ concurrent sysctl updates.
It is part of the work related to #204
2022-11-19 19:55:46 +01:00
redp 2cd2c2bc00 add get_kprobe_maxactive to remaining kprobes
Co-authored-by: Solar Designer <solar@openwall.com>
2022-11-10 21:58:02 +01:00
redp 6736d568dc kretprobes.maxactive should depend on number of cores
Co-authored-by: Solar Designer <solar@openwall.com>
2022-11-10 21:58:02 +01:00
Solar Designer 3f7af09f5b UMH: Allow /usr/libexec/abrt-hook-ccpp for older Red Hat distros 2022-11-10 21:57:48 +01:00
Solar Designer fc3545696b pINT: Make the real_cred check in p_cmp_tasks() unconditional
Fixes #240
2022-11-05 18:39:49 +01:00
Adam_pi3 ad03367344 Add support for new RHEL8.6+ kernels
Starting from RHEL8.6 4.18.0-372.32.1.el8_6 kernel struct text_poke_loc
is not exported and we need to correctly take this into account.
Previous RHEL8.6 kernels did not hide this structure so we need to find
some ways to disinguish them. We do it in this commit and it should fix #236
2022-11-05 18:38:12 +01:00
Vladimir D. Seleznev a4e5c00f13 Add support for Kernel 5.19+ for aarch64
Since Linux Kernel 5.19 struct stackframe has been renamed to struct
unwind_state for arm64:

torvalds/linux@e9d75a0ba8
2022-11-05 14:15:44 +01:00
Vladimir D. Seleznev 8fbdbda372 Add support for RHEL 9.2 kernel
Reported-by: Alexey Gladkov <legion@altlinux.ru>
Signed-off-by: Vladimir D. Seleznev <vseleznv@altlinux.org>
2022-10-31 21:24:05 +01:00
Solar Designer 4da9ded1a2 CI: Re-enable AArch64 test, but without BTI 2022-10-29 16:06:17 +02:00
Solar Designer f32f627950 Simplify our get_random_long() wrapper (only used with old kernels)
Fixes #234
2022-10-17 22:20:20 +02:00
Solar Designer 11553ec0df Notifiers: Fix typo in the value of P_M_SS_MORE_OFTEN_RATE
Noticed by Jason A. Donenfeld
2022-10-17 22:20:20 +02:00
Solar Designer 2241a32231 Don't depend on get_random_int(), which Linux 6.1+ dropped
Fixes #233
2022-10-17 22:20:20 +02:00
Adam_pi3 717137dbd2
Remove IOMMU verification on kernel 5.19+
IOMMU table infrastructure was removed by this commit
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=78013eaadf696d2105982abb4018fbae394ca08f

which breaks the way how LKRG could verify it.
This commit skips the IOMMU verification starting from kernels 5.19+
and fixes #226
2022-09-25 00:09:01 +00:00
mrl5 d7f079baa1 fix: umh - allow openrc cgroup release agent [#230]
closes #230
2022-09-11 03:34:53 +00:00
Vitaly Chikunov b56b8758af CI: mkosi: Restore loading LKRG module from initrd
For (non-grub) BLS boot - install generated by Dracut initrd into
systemd-boot loader entry.

Man pages for curious details: systemd-boot(7), bootctl(1),
kernel-install(8).

Link: https://github.com/lkrg-org/lkrg/pull/228#issuecomment-1235403740
Fixes: db42541 ("CI: mkosi: Do not assume grub is installed")
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
2022-09-04 13:41:59 +02:00
Vitaly Chikunov db42541477 CI: mkosi: Do not assume grub is installed
mkosi' "--boot-protocols is deprecated and has no effect anymore", thus
do not assume we will be booting using grub/bios.

Fixes: https://github.com/lkrg-org/lkrg/issues/227
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
2022-09-02 13:41:33 +02:00
Solar Designer ff18ec6856 LKRG 0.9.5 2022-08-01 13:28:28 +02:00
Solar Designer 333ae0774e Revert "Logging: Use KERN_EMERG in place of KERN_CRIT"
This reverts commit dfb60a6eb2.
2022-08-01 13:13:25 +02:00
Solar Designer c58cb52145 Simplify the new logic supporting OverlayFS 2022-07-29 10:35:23 -07:00
Solar Designer 9dd2a8d3f7 CI: Enable CodeQL for all branches (not just main) 2022-07-29 10:35:23 -07:00
Adam_pi3 6f3627e32c Rework the logic supporting OverlayFS/docker
The original logic was hooking 'ovl_create_or_link' function but it could be
inlined. This commit changes it by hooking 'ovl_dentry_is_whiteout' when
possible.

Fixes #215
2022-07-29 13:50:45 +02:00
Solar Designer dfb60a6eb2 Logging: Use KERN_EMERG in place of KERN_CRIT
Fixes #222
2022-07-28 16:30:23 -07:00
Solar Designer e773798649 kINT: Support variable length jump labels also for 5.10.133+
Extends b8ff7abcd0
Extends fb9e272f7d
Fixes #221
2022-07-28 16:30:23 -07:00
Vitaly Chikunov 09a156a53e CI: Remove EOL'ed Ubuntu releases
Impish is started to fail, because it's EOL'ed at July 14, 2022.
Hirsute is EOL'ed at January 20, 2022, but it started to fail only
recently.

Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
2022-07-27 19:43:16 +02:00
94 changed files with 853 additions and 458 deletions

View File

@ -22,19 +22,19 @@ jobs:
run: dnf install -y kernel-devel kernel gcc make elfutils-libelf-devel
- image: alt:sisyphus
run: apt-get update; apt-get install -y kernel-headers-modules-un-def gcc make libelf-devel
- image: opensuse/tumbleweed
run: zypper -n install -y gcc make kernel-default-devel
- image: opensuse/leap
run: zypper -n install -y gcc make kernel-default-devel
- image: registry.opensuse.org/opensuse/tumbleweed
run: zypper -n install -y gcc make kernel-default-devel awk
- image: registry.opensuse.org/opensuse/leap
run: zypper -n install -y gcc make kernel-default-devel tar gzip
container:
image: ${{ matrix.image }}
options: --security-opt seccomp=unconfined
steps:
- uses: actions/checkout@v1
- run: cat /etc/os-release
- run: ${{ matrix.run }}
- uses: actions/checkout@v3
- run: make -j$(nproc) KERNELRELEASE=$(cd /lib/modules; ls)
# vim: sw=4

View File

@ -13,10 +13,7 @@ name: "CodeQL"
on:
push:
branches: [ main ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ main ]
schedule:
- cron: '33 3 * * 6'
@ -39,7 +36,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL

View File

@ -22,15 +22,15 @@ jobs:
fail-fast: false
matrix:
include:
- image: arm64v8/ubuntu:impish
- image: arm64v8/ubuntu:jammy
packages: libelf-dev linux-headers-generic
- image: arm32v7/alt:latest
packages: elfutils kernel-headers-modules-std-def
- image: i386/ubuntu:bionic
packages: libelf-dev linux-headers-generic
steps:
- uses: docker/setup-qemu-action@v1
- uses: actions/checkout@v1
- uses: docker/setup-qemu-action@v2
- uses: actions/checkout@v3
- name: Create Dockerfile
run: |
cat <<EOF >Dockerfile

View File

@ -11,13 +11,13 @@ jobs:
# - args: image=i386/ubuntu:bionic
# qemu=qemu-system-i386
# install: qemu-system-x86
#
# - args: image=arm64v8/ubuntu:impish
# opts="-M virt,gic-version=3 -cpu max"
# console=ttyAMA0
# root=/dev/vda
# qemu=qemu-system-aarch64
# install: qemu-system-arm
- args: image=arm64v8/ubuntu:jammy
opts="-M virt,gic-version=3 -cpu cortex-a57"
console=ttyAMA0
root=/dev/vda
qemu=qemu-system-aarch64
install: qemu-system-arm
# It's possible to use: opts="-M raspi2b" dtb=bcm2709-rpi-2-b.dtb root=/dev/mmcblk0
# but since power-off is unreliable anyway (until QEMU 6.2) use simpler virt machine.
@ -30,14 +30,14 @@ jobs:
install: qemu-system-arm
steps:
- uses: docker/setup-qemu-action@v1
- uses: docker/setup-qemu-action@v2
- run: sudo apt-get update
# It's possible to update QEMU to (6.0) on focal (ubuntu-20.04) with
# add-apt-repository ppa:canonical-server/server-backports
# but this is still not enough to boot & power-off raspi2b properly.
- run: sudo apt-get install -y qemu-utils e2fsprogs expect ${{ matrix.install }}
- uses: actions/checkout@v1
- uses: actions/checkout@v3
- name: Enable LKRG debugging options
run: |
sed -i '/P_LKRG_JUMP_LABEL_STEXT_DEBUG/s/\/\///' src/modules/print_log/p_lkrg_print_log.h

View File

@ -11,17 +11,16 @@ jobs:
release:
- bionic
- focal
- hirsute
- jammy
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- run: sudo apt-get update
- run: sudo apt-get install -y debootstrap qemu-system-x86 systemd-container expect
- name: Install mkosi from git
# Native focal package seems to be too old (v5) and not even
# able to build images properly.
run: |
sudo python3 -m pip install git+https://github.com/systemd/mkosi.git
sudo python3 -m pip install git+https://github.com/systemd/mkosi.git@v14
sudo sed -i 's/linux-generic/linux-virtual/' /usr/local/lib/python*/dist-packages/mkosi/__init__.py
sudo rm -f /dev/kvm
echo /usr/local/bin >> $GITHUB_PATH

View File

@ -11,15 +11,16 @@ jobs:
if: ${{ github.repository == 'lkrg-org/lkrg' || github.event_name != 'schedule' }}
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- run: sudo apt-get update
- run: sudo apt-get install -y debootstrap qemu-system-x86 systemd-container expect sysvbanner
- name: Install mkosi from git
# Native focal package seems to be too old (v5) and not even
# able to build images properly.
run: |
sudo python3 -m pip install git+https://github.com/systemd/mkosi.git
sudo python3 -m pip install git+https://github.com/systemd/mkosi.git@v14
sudo sed -i 's/linux-generic/linux-virtual/' /usr/local/lib/python*/dist-packages/mkosi/__init__.py
sudo sed -i 's/dpkg-reconfigure dracut/&||:/' /usr/local/lib/python*/dist-packages/mkosi/resources/dpkg-reconfigure-dracut.install
sudo rm -f /dev/kvm
echo /usr/local/bin >> $GITHUB_PATH

View File

@ -8,6 +8,7 @@
#
baseurl="https://kernel.ubuntu.com/~kernel-ppa"
baseurl="https://kernel.ubuntu.com"
for listurl in \
"$baseurl/mainline/daily/" \
"$baseurl/mainline/"

48
CHANGES
View File

@ -1,3 +1,51 @@
The following major changes have been made since LKRG 0.9.7:
*) RPM spec file improvements to make it work or properly fail in a wider set
of circumstances, and to use the "weak-modules" script if available so that
on RHEL and its rebuilds the same LKRG package build works across different
kABI-compatible kernel revisions/builds
*) More complete documentation of the build requirements
The following major changes have been made between LKRG 0.9.6 and 0.9.7:
*) Support new mainline kernels 6.4 to 6.5.x, and hopefully beyond
*) Support new RHEL 9.1 and 9.2 kernels, and hopefully beyond
*) Add RPM spec file for Red Hat'ish distros (usable via "rpmbuild -tb" on our
release tarball)
*) Add Arch Linux's /usr/bin/modprobe path to usermodehelper allow list
*) Bootup script changes
*) Continuous Integration updates
The following major changes have been made between LKRG 0.9.5 and 0.9.6:
*) Support new mainline kernels 6.1-rc*, 6.1, and hopefully beyond
*) Support kernels 5.19 and beyond on AArch64
*) Support new RHEL 8.6 update and RHEL 8.7 kernels
*) Support new CentOS Stream 9 aka upcoming RHEL 9.2 kernels
*) Add a couple of distros' default pathnames to usermodehelper allow list
*) Validate tasks' real UIDs/GIDs even when effective ones pass validation
(previously, this check was normally bypassed as an optimization)
*) Add synchronization logic around sysctl updates and other module (un)loads
(previously, some concurrent events of this sort could lead to a crash on
attempting to write to our read-only page)
*) Test whether kretprobes work correctly at LKRG loading time and re-test
periodically (previously, LKRG would only detect disabling of kretprobes
after it's loaded, and only indirectly - through kernel code hash changes)
*) Set kretprobes' maxactive based on actual number of possible logical CPUs
(previously, we used a hard-coded value, which would more likely result in
missed hook function invocations on systems with more CPUs)
*) Continuous Integration updates, including testing on AArch64
The following major changes have been made between LKRG 0.9.4 and 0.9.5:
*) Support new longterm kernels 5.10.133+
*) Rework the logic supporting OverlayFS (notably used by Docker) to support
a wider variety of kernel versions and builds
The following major changes have been made between LKRG 0.9.3 and 0.9.4:
*) Support new longterm kernels 5.15.40+

View File

@ -1,7 +1,7 @@
Linux Kernel Runtime Guard (LKRG)
Copyright (c) 2015-2022 Adam 'pi3' Zabrocki
Copyright (c) 2015-2023 Adam 'pi3' Zabrocki
Copyright (c) 2020-2022 Mariusz Zaborski
Copyright (c) 2020-2022 Solar Designer
Copyright (c) 2020-2023 Solar Designer
scripts/copy-builtin.sh, scripts/add-exports.sh
Copyright (c) 2021-2022 RageLtMan

View File

@ -31,6 +31,7 @@ $(TARGET)-objs += src/modules/ksyms/p_resolve_ksym.o \
src/modules/hashing/p_lkrg_fast_hash.o \
src/modules/comm_channel/p_comm_channel.o \
src/modules/integrity_timer/p_integrity_timer.o \
src/modules/integrity_timer/verify_kprobes/p_verify_kprobes.o \
src/modules/kmod/p_kmod.o \
src/modules/database/CPU.o \
src/modules/database/arch/x86/p_x86_metadata.o \
@ -82,7 +83,7 @@ $(TARGET)-objs += src/modules/ksyms/p_resolve_ksym.o \
src/modules/exploit_detection/syscalls/__x32/p_x32_sys_keyctl/p_x32_sys_keyctl.o \
src/modules/exploit_detection/syscalls/override/p_override_creds/p_override_creds.o \
src/modules/exploit_detection/syscalls/override/p_revert_creds/p_revert_creds.o \
src/modules/exploit_detection/syscalls/override/overlayfs/p_ovl_create_or_link/p_ovl_create_or_link.o \
src/modules/exploit_detection/syscalls/override/overlayfs/p_ovl_override_sync/p_ovl_override_sync.o \
src/modules/exploit_detection/syscalls/pCFI/p_mark_inode_dirty/p_mark_inode_dirty.o \
src/modules/exploit_detection/syscalls/pCFI/p_schedule/p_schedule.o \
src/modules/exploit_detection/syscalls/pCFI/p___queue_work/p___queue_work.o \

42
README
View File

@ -9,7 +9,7 @@ on top of a wide range of mainline and distros' kernels, without needing to
patch those. We currently support kernel versions ranging from as far back as
RHEL7's (and its many clones/revisions) and Ubuntu 16.04's to latest mainline
and distros' kernels. We've tested this revision of LKRG with Linux kernels
up to and including 5.19-rc*.
up to and including 6.5, and slightly beyond.
LKRG currently supports the x86-64, 32-bit x86, AArch64 (ARM64), and 32-bit ARM
CPU architectures.
@ -33,9 +33,9 @@ like the below:
wget https://www.openwall.com/signatures/openwall-offline-signatures.asc
gpg --import openwall-offline-signatures.asc
wget https://lkrg.org/download/lkrg-0.9.4.tar.gz.sign
wget https://lkrg.org/download/lkrg-0.9.4.tar.gz
gpg --verify lkrg-0.9.4.tar.gz.sign lkrg-0.9.4.tar.gz
wget https://lkrg.org/download/lkrg-0.9.7.tar.gz.sign
wget https://lkrg.org/download/lkrg-0.9.7.tar.gz
gpg --verify lkrg-0.9.7.tar.gz.sign lkrg-0.9.7.tar.gz
Please preserve the GnuPG key above and also use it to verify future releases,
which will most likely work in a similar manner.
@ -53,19 +53,22 @@ To build LKRG, you will need the following software:
- GNU make
- A C compiler (ideally, the same that was used to build the kernel itself)
- GCC, ideally the same version of it that was used to build the kernel itself
(some people manage with clang, but this is unsupported, so expect issues)
- libelf, including its "development" sub-package, in case your target kernel
was built with CONFIG_UNWINDER_ORC=y
- A kernel build directory corresponding to the Linux kernel image the module
is to run on. For example, under Debian and Ubuntu, each linux-image package
containing a kernel binary has a corresponding linux-headers package with the
required build infrastructure, which you can install with:
is to run on.
sudo apt-get install linux-headers-$(uname -r)
For example, under Debian and Ubuntu you can install all of these with:
Red Hat'ish (e.g. RHEL, CentOS, Fedora) distributions call this package
kernel-devel, which you can install with:
sudo apt-get install make gcc libelf-dev linux-headers-$(uname -r)
sudo yum install kernel-devel
and under Red Hat'ish distributions (e.g. RHEL, CentOS, Fedora) with:
sudo yum install make gcc elfutils-libelf-devel kernel-devel
(For documentation purposes, we prefix commands requiring root access with
"sudo", but you may of course run them as root by different means.)
@ -176,12 +179,12 @@ What this means in effect is that on kernel upgrades the module is rebuilt.
You can install LKRG using DKMS as well. For instance, on Red Hat'ish
distributions after following the shared download instructions above:
sudo tar -xzf lkrg-0.9.4.tar.gz -C /usr/src/
sudo tar -xzf lkrg-0.9.7.tar.gz -C /usr/src/
sudo dnf update -y
sudo dnf install kernel-devel dkms openssl
sudo dkms add -m lkrg -v 0.9.4
sudo dkms build -m lkrg -v 0.9.4
sudo dkms install -m lkrg -v 0.9.4
sudo dkms add -m lkrg -v 0.9.7
sudo dkms build -m lkrg -v 0.9.7
sudo dkms install -m lkrg -v 0.9.7
The only difference on other distributions should be the installation of the
kernel headers, the DKMS utility, and OpenSSL. Install the headers for the
@ -193,11 +196,12 @@ You can then query the status with:
If everything is right, you should get similar output to the following:
lkrg/0.9.4, 5.18.9-200.fc36.x86_64, x86_64: installed
lkrg/0.9.7, 5.18.9-200.fc36.x86_64, x86_64: installed
Please refer to the previous two sections for how to start the LKRG service or
have it started on system bootup. If you wish to use the unit/init file, you
must install it manually.
must install it manually, e.g., by running the `lkrg-bootup.sh` script
located under `scripts/bootup/` with the `install` subcommand (as root).
Uninstalling
@ -211,7 +215,7 @@ while you're in the top level source code directory of the installed version.
If you installed using DKMS, you'd uninstall with:
sudo dkms remove -m lkrg/0.9.4 --all
sudo dkms remove -m lkrg/0.9.7 --all
You can also use the following command to temporarily stop the LKRG service
without uninstalling it, for systemd:

18
debian/changelog vendored
View File

@ -1,3 +1,21 @@
lkrg (0.9.7-1) unstable; urgency=medium
* New upstream release.
-- Solar Designer <solar@openwall.com> Thu, 14 Sep 2023 05:00:00 +0200
lkrg (0.9.6-1) unstable; urgency=medium
* New upstream release.
-- Solar Designer <solar@openwall.com> Wed, 14 Dec 2022 17:00:00 +0100
lkrg (0.9.5-1) unstable; urgency=medium
* New upstream release.
-- Solar Designer <solar@openwall.com> Mon, 1 Aug 2022 13:15:00 +0200
lkrg (0.9.4-1) unstable; urgency=medium
* New upstream release.

10
debian/copyright vendored
View File

@ -4,9 +4,9 @@ Upstream-Contact: Adam 'pi3' Zabrocki <pi3@pi3.com.pl>
Source: https://lkrg.org
Files: *
Copyright: 2015-2021 Adam 'pi3' Zabrocki <pi3@pi3.com.pl>
2020-2021 Mariusz Zaborski
2020 Solar Designer
Copyright: 2015-2023 Adam 'pi3' Zabrocki <pi3@pi3.com.pl>
2020-2022 Mariusz Zaborski
2020-2023 Solar Designer
License: GPL-2.0
Files: debian/*
@ -14,12 +14,12 @@ Copyright: 2020-2021 Mikhail Morfikov <mmorfikov@gmail.com>
License: GPL-2.0
Files: scripts/copy-builtin.sh
Copyright: 2021 RageLtMan
Copyright: 2021-2022 RageLtMan
License: GPL-2.0
Files: mkosi.*
.github/workflows/*
Copyright: 2021 Vitaly Chikunov
Copyright: 2021-2022 Vitaly Chikunov
License: GPL-2.0
License: GPL-2.0

View File

@ -1 +1 @@
lkrg-dkms: repeated-path-segment src usr/src/lkrg-*/src/
lkrg-dkms: repeated-path-segment src [usr/src/lkrg-*/src/]

View File

@ -1,5 +1,5 @@
PACKAGE_NAME="lkrg"
PACKAGE_VERSION="0.9.4"
PACKAGE_VERSION="0.9.7"
#BUILT_MODULE_LOCATION[0]="output"
BUILT_MODULE_NAME[0]="lkrg"
DEST_MODULE_LOCATION[0]="/updates/dkms"

80
lkrg.spec Normal file
View File

@ -0,0 +1,80 @@
%define kmod_headers_version %(rpm -qa kernel-devel | sed 's/^kernel-devel-//' | sort -r | head -1)
%define module_dir /lib/modules/%kmod_headers_version/extra
%global debug_package %nil
Summary: Linux Kernel Runtime Guard (LKRG)
Name: lkrg
Version: 0.9.7
Release: 3%{?dist}
License: GPLv2
URL: https://lkrg.org
Source: https://lkrg.org/download/%name-%version.tar.gz
ExclusiveArch: x86_64 %arm32 %arm64
BuildRequires: make, gcc, elfutils-libelf-devel, kernel, kernel-devel
BuildRoot: /override/%name-%version
%description
LKRG performs runtime integrity checking of the Linux kernel and detection of
security vulnerability exploits against the kernel.
As controversial as this concept is, LKRG attempts to post-detect and
hopefully promptly respond to unauthorized modifications to the running Linux
kernel (integrity checking) or to credentials such as user IDs of the running
processes (exploit detection). For process credentials, LKRG attempts to
detect the exploit and take action before the kernel would grant access (such
as open a file) based on the unauthorized credentials.
%prep
%setup -q
%build
make %{?_smp_mflags} KERNELRELEASE=%kmod_headers_version
%install
rm -rf %buildroot
install -D -p -m 644 lkrg.ko %buildroot%module_dir/lkrg.ko
install -D -p -m 644 scripts/bootup/systemd/lkrg.service %buildroot%_unitdir/lkrg.service
install -D -p -m 644 scripts/bootup/lkrg.conf %buildroot%_sysconfdir/sysctl.d/01-lkrg.conf
%posttrans
if [ -e %_sbindir/weak-modules ]; then
echo %module_dir/lkrg.ko | %_sbindir/weak-modules --verbose --add-modules --no-initramfs
else
%sbindir/depmod -a
fi
echo 'To start LKRG please use: systemctl start lkrg'
echo 'To enable LKRG on bootup please use: systemctl enable lkrg'
%preun
%systemd_preun lkrg.service
%postun
if [ -e %_sbindir/weak-modules ]; then
echo %module_dir/lkrg.ko | %_sbindir/weak-modules --verbose --remove-modules --no-initramfs
fi
%systemd_postun_with_restart lkrg.service
%files
%defattr(-,root,root)
%doc CHANGES CONCEPTS LICENSE PATREONS PERFORMANCE README
%module_dir/*
%_unitdir/*
%_sysconfdir/sysctl.d/*
%changelog
* Tue Oct 24 2023 Solar Designer <solar@openwall.com> 0.9.7-3
- Use weak-modules if available so that on RHEL and its rebuilds the same LKRG
package build works across different kABI-compatible kernel revisions/builds
- Drop 32-bit x86 from ExclusiveArch since recent RHEL lacks such kernel-devel
* Thu Sep 14 2023 Solar Designer <solar@openwall.com> 0.9.7-2
- Use kernel build directory corresponding to the kernel-devel package, not to
the currently running kernel
- "BuildRequires: kernel" for the /lib/modules/* directory
- "BuildRequires: elfutils-libelf-devel" to support CONFIG_UNWINDER_ORC=y
* Thu Sep 14 2023 Solar Designer <solar@openwall.com> 0.9.7-1
- Wrote this rough RPM spec file for Red Hat'ish distros, seems to work fine on
RHEL 7, 8, 9 rebuilds, but is only reliable when there's exactly one
kernel-devel package installed at build time and it exactly matches the target
kernel version.

View File

@ -11,11 +11,9 @@ Release=hirsute
[Output]
Bootable=yes
# 'no_timer_check' is old workaround to intermittent apic kernel panic in qemu.
KernelCommandLine=no_timer_check panic=-1 oops=panic panic_on_warn softlockup_panic=1 ignore_loglevel
# Simplest way of installing initrd is without unified kernel image,
# which requires bios (grub) boot.
KernelCommandLine=no_timer_check panic=-1 oops=panic panic_on_warn softlockup_panic=1 ignore_loglevel root=LABEL=root
# Separate initrd for possible debugging.
WithUnifiedKernelImages=no
BootProtocols=bios
[Partitions]
# 2G was not enough for build with mainline kernels installs.

View File

@ -11,10 +11,28 @@ if test -x /usr/bin/dracut; then
banner postinst >&2
# Register our module in kmod database.
depmod -a $KERNELRELEASE
# Install module into (and force load early in) initrd.
dracut --force --force-drivers lkrg /boot/initrd.img-$KERNELRELEASE $KERNELRELEASE
# Delete default cmdline which contains 'quiet splash' to see full boot log.
sed -i /GRUB_CMDLINE_LINUX_DEFAULT/d /etc/default/grub
update-grub
# Install module into (and force its load early in) initrd.
# Add lkrg by default for any dracut invocation w/o requirement of
# passing '--force-drivers lkrg' command line option.
echo 'force_drivers+=" lkrg "' > /etc/dracut.conf.d/31-lkrg.conf
dracut --force /boot/initrd.img-$KERNELRELEASE $KERNELRELEASE
if [ -d /boot/loader/entries ]; then
# Install into systemd-boot loader.
# Because we pass INITRD argument to kernel-install, this will
# skip calling dracut (saving time, because it would regenerate
# ALL images) by mkosi hooks, but this will not delete old
# 'initrd' file from its boot entry, which is not big deal.
# Boot entry itself will not be duplicated.
kernel-install add $KERNELRELEASE /boot/vmlinuz-$KERNELRELEASE /boot/initrd.img-$KERNELRELEASE
fi
if [ -e /etc/default/grub ]; then
# Delete default cmdline which contains 'quiet splash' to see full boot log.
sed -i /GRUB_CMDLINE_LINUX_DEFAULT/d /etc/default/grub
update-grub
fi
fi
exit 0

View File

@ -6,14 +6,27 @@
# - Adam 'pi3' Zabrocki (http://pi3.com.pl)
##
P_LKRG_SYSTEMD="scripts/bootup/systemd/lkrg-systemd.sh"
P_LKRG_OPENRC="scripts/bootup/openrc/lkrg-openrc.sh"
set -eu
P_SCRIPT_DIR="$(dirname "$0")"
P_LKRG_SYSTEMD="${P_SCRIPT_DIR}/systemd/lkrg-systemd.sh"
P_LKRG_OPENRC="${P_SCRIPT_DIR}/openrc/lkrg-openrc.sh"
P_RED='\033[0;31m'
P_GREEN='\033[0;32m'
P_WHITE='\033[1;37m'
P_NC='\033[0m' # No Color
if [ $# -ne 1 ]; then
echo "Usage: $0 (install|uninstall)" >&2
exit 1
fi
if [ "$(id -u)" -ne 0 ]; then
echo "Please run as root." >&2
exit 1
fi
echo -e " ${P_GREEN}[*] ${P_WHITE}Executing LKRG's bootup installation script${P_NC}"
case "`readlink -e /proc/1/exe`" in

View File

@ -7,8 +7,11 @@
# - Jakub 'mrl5' Kołodziejczak (https://github.com/mrl5)
##
set -eu
P_SYSCTL_DIR="/etc/sysctl.d"
P_INITD_DIR="/etc/init.d"
P_SCRIPT_DIR="$(dirname "$0")"
RUNLEVEL="boot"
@ -18,6 +21,16 @@ P_WHITE='\033[1;37m'
P_YL='\033[1;33m'
P_NC='\033[0m' # No Color
if [ $# -ne 1 ]; then
echo "Usage: $0 (install|uninstall)" >&2
exit 1
fi
if [ "$(id -u)" -ne 0 ]; then
echo "Please run as root." >&2
exit 1
fi
echo -e " ${P_GREEN}[+] ${P_WHITE}OpenRC detected${P_NC}"
if [ "$1" == "install" ]; then
@ -26,7 +39,7 @@ if [ "$1" == "install" ]; then
exit 1
else
echo -e " ${P_GREEN}Installing ${P_YL}lkrg${P_GREEN} file under ${P_YL}$P_INITD_DIR${P_GREEN} directory${P_NC}"
install -pm 755 -o root -g root scripts/bootup/openrc/lkrg "$P_INITD_DIR/lkrg"
install -pm 755 -o root -g root "${P_SCRIPT_DIR}/lkrg" "$P_INITD_DIR/lkrg"
echo -e " ${P_GREEN}To start ${P_YL}lkrg${P_GREEN} please use: ${P_YL}/etc/init.d/lkrg start${P_NC}"
echo -e " ${P_GREEN}To enable ${P_YL}lkrg${P_GREEN} on bootup please use: ${P_YL}rc-update add lkrg ${RUNLEVEL}${P_NC}"
fi
@ -34,7 +47,7 @@ if [ "$1" == "install" ]; then
echo -e " ${P_YL}01-lkrg.conf${P_GREEN} is already installed, skipping${P_NC}"
else
echo -e " ${P_GREEN}Installing ${P_YL}01-lkrg.conf${P_GREEN} file under ${P_YL}$P_SYSCTL_DIR${P_GREEN} directory${P_NC}"
install -pm 644 -o root -g root scripts/bootup/lkrg.conf "$P_SYSCTL_DIR/01-lkrg.conf"
install -pm 644 -o root -g root "${P_SCRIPT_DIR}/../lkrg.conf" "$P_SYSCTL_DIR/01-lkrg.conf"
fi
elif [ "$1" == "uninstall" ]; then
echo -e " ${P_GREEN}Stopping ${P_YL}lkrg${P_NC}"
@ -43,7 +56,7 @@ elif [ "$1" == "uninstall" ]; then
rc-update del lkrg ${RUNLEVEL}
echo -e " ${P_GREEN}Deleting ${P_YL}lkrg${P_GREEN} file from ${P_YL}$P_SYSTEMD_DIR${P_GREEN} directory${P_NC}"
rm "$P_INITD_DIR/lkrg"
if cmp -s "$P_SYSCTL_DIR/01-lkrg.conf" scripts/bootup/lkrg.conf; then
if cmp -s "$P_SYSCTL_DIR/01-lkrg.conf" "${P_SCRIPT_DIR}/../lkrg.conf"; then
echo -e " ${P_GREEN}Deleting unmodified ${P_YL}01-lkrg.conf${P_GREEN} file from ${P_YL}$P_SYSCTL_DIR${P_GREEN} directory${P_NC}"
rm "$P_SYSCTL_DIR/01-lkrg.conf"
elif [ -e "$P_SYSCTL_DIR/01-lkrg.conf" ]; then

View File

@ -6,8 +6,11 @@
# - Adam 'pi3' Zabrocki (http://pi3.com.pl)
##
set -eu
P_SYSCTL_DIR="/etc/sysctl.d"
P_SYSTEMD_DIR="/etc/systemd/system"
P_SCRIPT_DIR="$(dirname "$0")"
P_RED='\033[0;31m'
@ -16,6 +19,16 @@ P_WHITE='\033[1;37m'
P_YL='\033[1;33m'
P_NC='\033[0m' # No Color
if [ $# -ne 1 ]; then
echo "Usage: $0 (install|uninstall)" >&2
exit 1
fi
if [ "$(id -u)" -ne 0 ]; then
echo "Please run as root." >&2
exit 1
fi
echo -e " ${P_GREEN}[+] ${P_WHITE}Systemd detected${P_NC}"
if [ "$1" == "install" ]; then
@ -24,7 +37,7 @@ if [ "$1" == "install" ]; then
exit 1
else
echo -e " ${P_GREEN}Installing ${P_YL}lkrg.service${P_GREEN} file under ${P_YL}$P_SYSTEMD_DIR${P_GREEN} directory${P_NC}"
install -pm 644 -o root -g root scripts/bootup/systemd/lkrg.service "$P_SYSTEMD_DIR/lkrg.service"
install -pm 644 -o root -g root "${P_SCRIPT_DIR}/lkrg.service" "${P_SYSTEMD_DIR}/lkrg.service"
echo -e " ${P_GREEN}To start ${P_YL}lkrg.service${P_GREEN} please use: ${P_YL}systemctl start lkrg${P_NC}"
echo -e " ${P_GREEN}To enable ${P_YL}lkrg.service${P_GREEN} on bootup please use: ${P_YL}systemctl enable lkrg.service${P_NC}"
fi
@ -32,7 +45,7 @@ if [ "$1" == "install" ]; then
echo -e " ${P_YL}01-lkrg.conf${P_GREEN} is already installed, skipping${P_NC}"
else
echo -e " ${P_GREEN}Installing ${P_YL}01-lkrg.conf${P_GREEN} file under ${P_YL}$P_SYSCTL_DIR${P_GREEN} directory${P_NC}"
install -pm 644 -o root -g root scripts/bootup/lkrg.conf "$P_SYSCTL_DIR/01-lkrg.conf"
install -pm 644 -o root -g root "${P_SCRIPT_DIR}/../lkrg.conf" "${P_SYSCTL_DIR}/01-lkrg.conf"
fi
elif [ "$1" == "uninstall" ]; then
echo -e " ${P_GREEN}Stopping ${P_YL}lkrg.service${P_NC}"
@ -41,7 +54,7 @@ elif [ "$1" == "uninstall" ]; then
systemctl disable lkrg.service
echo -e " ${P_GREEN}Deleting ${P_YL}lkrg.service${P_GREEN} file from ${P_YL}$P_SYSTEMD_DIR${P_GREEN} directory${P_NC}"
rm "$P_SYSTEMD_DIR/lkrg.service"
if cmp -s "$P_SYSCTL_DIR/01-lkrg.conf" scripts/bootup/lkrg.conf; then
if cmp -s "$P_SYSCTL_DIR/01-lkrg.conf" "${P_SCRIPT_DIR}/../lkrg.conf"; then
echo -e " ${P_GREEN}Deleting unmodified ${P_YL}01-lkrg.conf${P_GREEN} file from ${P_YL}$P_SYSCTL_DIR${P_GREEN} directory${P_NC}"
rm "$P_SYSCTL_DIR/01-lkrg.conf"
elif [ -e "$P_SYSCTL_DIR/01-lkrg.conf" ]; then

View File

@ -138,15 +138,6 @@ static int p_sysctl_profile_enforce(struct ctl_table *p_table, int p_write,
void __user *p_buffer, size_t *p_len, loff_t *p_pos);
struct ctl_table p_lkrg_sysctl_base[] = {
{
.procname = "lkrg",
.mode = 0600,
.child = p_lkrg_sysctl_table,
},
{ }
};
struct ctl_table p_lkrg_sysctl_table[] = {
{
.procname = "kint_validate",
@ -1265,7 +1256,7 @@ static int p_sysctl_profile_enforce(struct ctl_table *p_table, int p_write,
int p_register_comm_channel(void) {
if ( (p_sysctl_handle = register_sysctl_table(p_lkrg_sysctl_base)) == NULL) {
if ( (p_sysctl_handle = register_sysctl("lkrg", p_lkrg_sysctl_table)) == NULL) {
return P_LKRG_GENERAL_ERROR;
}

View File

@ -136,9 +136,12 @@ static void p_cpu_rehash(const char *onoffline) {
if (hash_from_kernel_rodata() != P_LKRG_SUCCESS) {
p_print_log(P_LOG_FAULT, "CPU %s: Can't get hash from _rodata", onoffline);
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,19,0)
if (hash_from_iommu_table() != P_LKRG_SUCCESS) {
p_print_log(P_LOG_FAULT, "CPU %s: Can't get hash from IOMMU table", onoffline);
}
#endif
/* Now recalculate modules, again some macros are different now ! */
/* OK, now recalculate hashes again! */

View File

@ -36,8 +36,6 @@ static struct kretprobe p_ftrace_enable_sysctl_kretprobe = {
.handler = p_ftrace_enable_sysctl_ret,
.entry_handler = p_ftrace_enable_sysctl_entry,
.data_size = sizeof(struct p_ftrace_enable_sysctl_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};
notrace int p_ftrace_enable_sysctl_entry(struct kretprobe_instance *p_ri, struct pt_regs *p_regs) {
@ -58,6 +56,7 @@ int p_install_ftrace_enable_sysctl_hook(void) {
int p_tmp;
p_ftrace_enable_sysctl_kretprobe.maxactive = p_get_kprobe_maxactive();
if ( (p_tmp = register_kretprobe(&p_ftrace_enable_sysctl_kretprobe)) != 0) {
p_print_log(P_LOG_FATAL, "[kretprobe] register_kretprobe() for <%s> failed! [err=%d]",
p_ftrace_enable_sysctl_kretprobe.kp.symbol_name,

View File

@ -36,8 +36,6 @@ static struct kretprobe p_ftrace_modify_all_code_kretprobe = {
.handler = p_ftrace_modify_all_code_ret,
.entry_handler = p_ftrace_modify_all_code_entry,
.data_size = sizeof(struct p_ftrace_modify_all_code_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};
/*
@ -209,11 +207,12 @@ int p_install_ftrace_modify_all_code_hook(void) {
int p_tmp;
P_SYM_INIT(ftrace_lock, struct mutex *)
P_SYM_INIT(ftrace_rec_iter_start, struct ftrace_rec_iter *(*)(void))
P_SYM_INIT(ftrace_rec_iter_next, struct ftrace_rec_iter *(*)(struct ftrace_rec_iter *))
P_SYM_INIT(ftrace_rec_iter_record, struct dyn_ftrace *(*)(struct ftrace_rec_iter *))
P_SYM_INIT(ftrace_lock)
P_SYM_INIT(ftrace_rec_iter_start)
P_SYM_INIT(ftrace_rec_iter_next)
P_SYM_INIT(ftrace_rec_iter_record)
p_ftrace_modify_all_code_kretprobe.maxactive = p_get_kprobe_maxactive();
if ( (p_tmp = register_kretprobe(&p_ftrace_modify_all_code_kretprobe)) != 0) {
p_print_log(P_LOG_FATAL, "[kretprobe] register_kretprobe() for <%s> failed! [err=%d]",
p_ftrace_modify_all_code_kretprobe.kp.symbol_name,

View File

@ -36,8 +36,6 @@ static struct kretprobe p_arch_jump_label_transform_kretprobe = {
.handler = p_arch_jump_label_transform_ret,
.entry_handler = p_arch_jump_label_transform_entry,
.data_size = sizeof(struct p_arch_jump_label_transform_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};
@ -202,6 +200,7 @@ int p_install_arch_jump_label_transform_hook(void) {
p_lkrg_counter_lock_init(&p_jl_lock);
p_arch_jump_label_transform_kretprobe.maxactive = p_get_kprobe_maxactive();
if ( (p_tmp = register_kretprobe(&p_arch_jump_label_transform_kretprobe)) != 0) {
p_print_log(P_LOG_FATAL, "[kretprobe] register_kretprobe() for <%s> failed! [err=%d]",
p_arch_jump_label_transform_kretprobe.kp.symbol_name,

View File

@ -42,8 +42,6 @@ static struct kretprobe p_arch_jump_label_transform_apply_kretprobe = {
.handler = p_arch_jump_label_transform_apply_ret,
.entry_handler = p_arch_jump_label_transform_apply_entry,
.data_size = sizeof(struct p_arch_jump_label_transform_apply_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};
@ -72,14 +70,17 @@ notrace int p_arch_jump_label_transform_apply_entry(struct kretprobe_instance *p
for (p_jl_batch_nr = 0; p_cnt < p_nr; p_cnt++) {
p_tmp = (p_text_poke_loc *)&P_SYM(p_tp_vec)[p_jl_batch_nr*sizeof(p_text_poke_loc)];
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0) || \
defined(P_LKRG_KERNEL_RHEL_VAR_LEN_JUMP_LABEL)
if ( (p_tmp->opcode == CALL_INSN_OPCODE
|| p_tmp->opcode == JMP32_INSN_OPCODE
|| p_tmp->opcode == INT3_INSN_OPCODE
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) || \
defined(P_LKRG_KERNEL_RHEL_VAR_LEN_JUMP_LABEL)
|| p_tmp->opcode == RET_INSN_OPCODE
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 14, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 14, 0) || \
defined(P_LKRG_KERNEL_RHEL_VAR_LEN_JUMP_LABEL)
|| p_tmp->opcode == JMP8_INSN_OPCODE
#endif
) &&
@ -101,7 +102,8 @@ notrace int p_arch_jump_label_transform_apply_entry(struct kretprobe_instance *p
#endif
p_jl_batch_addr[p_jl_batch_nr++] =
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0) || \
defined(P_LKRG_KERNEL_RHEL_VAR_LEN_JUMP_LABEL)
(unsigned long)p_tmp->rel_addr +
(unsigned long)p_db.kernel_stext.p_addr;
#else
@ -245,8 +247,8 @@ int p_install_arch_jump_label_transform_apply_hook(void) {
int p_tmp;
P_SYM_INIT(tp_vec, struct text_poke_loc **)
P_SYM_INIT(tp_vec_nr, int *)
P_SYM_INIT(tp_vec)
P_SYM_INIT(tp_vec_nr)
// DEBUG
p_debug_log(P_LOG_DEBUG, "<p_install_arch_jump_label_transform_apply_hook> "
@ -254,6 +256,7 @@ int p_install_arch_jump_label_transform_apply_hook(void) {
(unsigned long)P_SYM(p_tp_vec),
(unsigned long)P_SYM(p_tp_vec_nr));
p_arch_jump_label_transform_apply_kretprobe.maxactive = p_get_kprobe_maxactive();
if ( (p_tmp = register_kretprobe(&p_arch_jump_label_transform_apply_kretprobe)) != 0) {
p_print_log(P_LOG_FATAL, "[kretprobe] register_kretprobe() for <%s> failed! [err=%d]",
p_arch_jump_label_transform_apply_kretprobe.kp.symbol_name,

View File

@ -36,12 +36,22 @@
#ifndef P_LKRG_CI_ARCH_JUMP_LABEL_TRANSFORM_APPLY_H
#define P_LKRG_CI_ARCH_JUMP_LABEL_TRANSFORM_APPLY_H
#include <asm/linkage.h> /* for ASM_RET */
#if defined(RHEL_RELEASE_CODE) && defined(DISP32_SIZE)
#define P_LKRG_KERNEL_RHEL_VAR_LEN_JUMP_LABEL 1
#endif
/*
* This needs to be extended to other LTS or active branches if and
* when they receive the variable length JUMP_LABEL feature backport
*/
* This can be extended to other LTS or active branches if and when they
* receive the variable length JUMP_LABEL feature backport, although the
* addition of ASM_RET is part of the same change set and thus our check
* for it hopefully makes the specific kernel version checks redundant.
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0) || \
(LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0) && LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 40))
(LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0) && LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 40)) || \
(LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) && LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 133)) || \
defined(ASM_RET)
#define P_LKRG_KERNEL_HAS_VAR_LEN_JUMP_LABEL 1
#else
#define P_LKRG_KERNEL_HAS_VAR_LEN_JUMP_LABEL 0
@ -49,8 +59,12 @@
#include <asm/text-patching.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)
#if !P_LKRG_KERNEL_HAS_VAR_LEN_JUMP_LABEL
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) || \
defined(P_LKRG_KERNEL_RHEL_VAR_LEN_JUMP_LABEL)
#if !P_LKRG_KERNEL_HAS_VAR_LEN_JUMP_LABEL || \
(defined(P_LKRG_KERNEL_RHEL_VAR_LEN_JUMP_LABEL) && \
(RHEL_RELEASE_CODE == RHEL_RELEASE_VERSION(9,0) || \
RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8,8)))
typedef struct _p_text_poke_loc {
s32 rel_addr; /* addr := _stext + rel_addr */
s32 rel32;

View File

@ -30,8 +30,6 @@ static struct kretprobe p_arch_static_call_transform_kretprobe = {
.handler = p_arch_static_call_transform_ret,
.entry_handler = p_arch_static_call_transform_entry,
.data_size = sizeof(struct p_arch_static_call_transform_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};
static unsigned long p_tracepoint_tmp_text;
@ -270,6 +268,7 @@ int p_install_arch_static_call_transform_hook(void) {
p_lkrg_counter_lock_init(&p_static_call_spinlock);
p_arch_static_call_transform_kretprobe.maxactive = p_get_kprobe_maxactive();
if ( (p_tmp = register_kretprobe(&p_arch_static_call_transform_kretprobe)) != 0) {
p_print_log(P_LOG_FATAL, "[kretprobe] register_kretprobe() for <%s> failed! [err=%d]",
p_arch_static_call_transform_kretprobe.kp.symbol_name,

View File

@ -40,7 +40,7 @@ void p_dump_CPU_metadata(void *_p_arg) {
int p_register_arch_metadata(void) {
P_SYM_INIT(core_kernel_text, int (*)(unsigned long))
P_SYM_INIT(core_kernel_text)
#ifdef P_LKRG_RUNTIME_CODE_INTEGRITY_SWITCH_IDT_H

View File

@ -32,8 +32,6 @@ static struct kretprobe p_switch_idt_kretprobe = {
.handler = p_switch_idt_ret,
.entry_handler = p_switch_idt_entry,
.data_size = sizeof(struct p_switch_idt_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};
@ -65,6 +63,7 @@ int p_install_switch_idt_hook(void) {
int p_tmp;
p_switch_idt_kretprobe.maxactive = p_get_kprobe_maxactive();
if ( (p_tmp = register_kretprobe(&p_switch_idt_kretprobe)) != 0) {
p_print_log(P_LOG_ISSUE, "[kretprobe] register_kretprobe() for <%s> failed! [err=%d]",
p_switch_idt_kretprobe.kp.symbol_name,

View File

@ -111,13 +111,11 @@ int hash_from_kernel_rodata(void) {
return P_LKRG_SUCCESS;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,19,0)
int hash_from_iommu_table(void) {
#ifdef CONFIG_X86
unsigned long p_tmp = 0;
#endif
#ifdef CONFIG_X86
p_db.kernel_iommu_table.p_addr = (unsigned long *)P_SYM(p_kallsyms_lookup_name)("__iommu_table");
p_tmp = (unsigned long)P_SYM(p_kallsyms_lookup_name)("__iommu_table_end");
@ -151,6 +149,7 @@ int hash_from_iommu_table(void) {
return P_LKRG_SUCCESS;
}
#endif
uint64_t hash_from_CPU_data(p_CPU_metadata_hash_mem *p_arg) {
@ -190,8 +189,9 @@ int p_create_database(void) {
memset(&p_db,0,sizeof(p_hash_database));
P_SYM_INIT(jump_label_mutex, struct mutex *)
P_SYM_INIT(text_mutex, struct mutex *)
P_SYM_INIT(jump_label_mutex)
P_SYM_INIT(text_mutex)
P_SYM_INIT(tracepoints_mutex)
/*
* First gather information about CPUs in the system - CRITICAL !!!
@ -288,12 +288,13 @@ int p_create_database(void) {
p_db.kernel_rodata.p_addr = NULL;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,19,0)
if (hash_from_iommu_table() != P_LKRG_SUCCESS) {
p_print_log(P_LOG_ISSUE, "IOMMU table can't be found (skipping)");
p_db.kernel_iommu_table.p_hash = p_db.kernel_iommu_table.p_size = 0;
p_db.kernel_iommu_table.p_addr = NULL;
}
#endif
#if defined(CONFIG_OPTPROBES)
P_SYM(p_wait_for_kprobe_optimizer)();

View File

@ -169,7 +169,9 @@ typedef struct p_hash_database {
char *kernel_stext_copy; // copy of .text
#endif
p_hash_mem_block kernel_rodata; // .rodata
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,19,0)
p_hash_mem_block kernel_iommu_table; // IOMMU table
#endif
p_hash_mem_block kernel_ex_table; // Exception tale
struct p_jump_label p_jump_label; // *_JUMP_LABEL state during modification
@ -183,7 +185,9 @@ extern struct notifier_block p_cpu_notifier;
int hash_from_ex_table(void);
int hash_from_kernel_stext(void);
int hash_from_kernel_rodata(void);
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,19,0)
int hash_from_iommu_table(void);
#endif
static inline void p_text_section_lock(void) {
@ -201,6 +205,7 @@ static inline void p_text_section_lock(void) {
mutex_lock(P_SYM(p_module_mutex));
while (mutex_is_locked(P_SYM(p_jump_label_mutex)))
schedule();
mutex_lock(P_SYM(p_tracepoints_mutex));
#if defined(P_LKRG_CI_ARCH_STATIC_CALL_TRANSFORM_H)
do {
p_lkrg_counter_lock_lock(&p_static_call_spinlock, &p_text_flags);
@ -221,6 +226,7 @@ static inline void p_text_section_unlock(void) {
#if defined(P_LKRG_CI_ARCH_STATIC_CALL_TRANSFORM_H)
p_lkrg_counter_lock_val_dec(&p_static_call_spinlock);
#endif
mutex_unlock(P_SYM(p_tracepoints_mutex));
/* Release the 'module_mutex' */
mutex_unlock(P_SYM(p_module_mutex));
#if defined(CONFIG_DYNAMIC_FTRACE)

View File

@ -18,10 +18,10 @@
#include "../../p_lkrg_main.h"
struct p_ed_global_variables p_ed_guard_globals;
unsigned long p_global_off_cookie;
unsigned long p_global_cnt_cookie;
static unsigned long p_global_off_cookie;
static unsigned long p_global_cnt_cookie;
struct kmem_cache *p_ed_wq_valid_cache = NULL;
struct kmem_cache *p_ed_pcfi_cache = NULL;
static struct kmem_cache *p_ed_pcfi_cache = NULL;
unsigned long p_pcfi_CPU_flags;
@ -298,19 +298,22 @@ static const struct p_functions_hooks {
NULL,
0
},
#if P_OVL_OVERRIDE_SYNC_MODE
/* OverlayFS
*
* OverlayFS might not be installed in that system - it is not critical
* scenario. If OverlayFS is installed, used but not found (unlikely)
* in worst case, we might have FP. Continue...
*/
{ "ovl_create_or_link",
p_install_ovl_create_or_link_hook,
p_uninstall_ovl_create_or_link_hook,
{
P_OVL_OVERRIDE_SYNC_FUNC,
p_install_ovl_override_sync_hook,
p_uninstall_ovl_override_sync_hook,
0,
"Can't hook 'ovl_create_or_link' function. This is expected when OverlayFS is not used.",
"Can't hook '" P_OVL_OVERRIDE_SYNC_FUNC "'. This is expected when OverlayFS is not used.",
1
},
#endif
/* pCFI */
{ "pcfi_mark_inode_dirty",
p_install_pcfi_mark_inode_dirty_hook,
@ -383,7 +386,7 @@ static void p_ed_wq_valid_cache_delete(void) {
}
}
notrace void p_dump_creds(struct p_cred *p_where, const struct cred *p_from) {
static notrace void p_dump_creds(struct p_cred *p_where, const struct cred *p_from) {
/* Get reference to cred */
get_cred(p_from);
@ -419,7 +422,7 @@ notrace void p_dump_creds(struct p_cred *p_where, const struct cred *p_from) {
}
#if defined(CONFIG_SECCOMP)
notrace void p_dump_seccomp(struct p_seccomp *p_sec, struct task_struct *p_task, char p_force) {
static notrace void p_dump_seccomp(struct p_seccomp *p_sec, struct task_struct *p_task, char p_force) {
P_SYM(p_get_seccomp_filter)(p_task);
p_sec->sec.mode = p_task->seccomp.mode; // Mode
@ -444,7 +447,7 @@ notrace void p_dump_seccomp(struct p_seccomp *p_sec, struct task_struct *p_task,
#endif
#if defined(P_VERIFY_ADDR_LIMIT)
notrace static inline unsigned long p_get_addr_limit(struct task_struct *p_task) {
static notrace inline unsigned long p_get_addr_limit(struct task_struct *p_task) {
/* X86(-64)*/
#if defined(CONFIG_X86)
@ -497,7 +500,7 @@ notrace void p_verify_addr_limit(struct p_ed_process *p_orig, struct task_struct
}
#if defined(P_VERIFY_ADDR_LIMIT)
notrace static inline void p_dump_addr_limit(mm_segment_t *p_addr_limit, struct task_struct *p_task) {
static notrace inline void p_dump_addr_limit(mm_segment_t *p_addr_limit, struct task_struct *p_task) {
#if defined(CONFIG_X86)
p_addr_limit->seg =
#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64)
@ -556,10 +559,10 @@ notrace void p_update_ed_process(struct p_ed_process *p_source, struct task_stru
}
#ifdef P_LKRG_TASK_OFF_DEBUG
struct p_lkrg_debug_off_flag_callers {
static const struct {
char p_id;
char *p_name;
const char *p_name;
} p_debug_off_flag_callers[] = {
@ -593,7 +596,7 @@ struct p_lkrg_debug_off_flag_callers {
{ 27, "p_sys_keyctl_ret" },
{ 28, "p_sys_request_key_entry" },
{ 29, "p_sys_request_key_ret" },
{ 30, "p_ovl_create_or_link_ret" },
{ 30, "p_ovl_override_sync_ret" },
{ 31, "p_override_creds_entry" },
{ 32, "p_revert_creds_ret" },
{ 33, "p_seccomp_entry" },
@ -629,10 +632,10 @@ struct p_lkrg_debug_off_flag_callers {
};
struct p_lkrg_debug_off_flag_action {
static const struct {
char p_id;
char *p_name;
const char *p_name;
} p_debug_off_flag_action[] = {
@ -875,7 +878,7 @@ notrace void p_debug_off_flag_reset(struct p_ed_process *p_source, unsigned int
}
}
notrace void p_debug_off_flag_dump_ring_buffer(struct p_ed_process *p_source) {
static notrace void p_debug_off_flag_dump_ring_buffer(struct p_ed_process *p_source) {
unsigned int p_tmp;
@ -963,7 +966,7 @@ static inline void p_ed_is_off_off(struct p_ed_process *p_source, long p_val, in
}
}
inline void p_validate_off_flag(struct p_ed_process *p_source, long p_val, int *p_ret) {
static inline void p_validate_off_flag(struct p_ed_process *p_source, long p_val, int *p_ret) {
if (likely(p_val == p_global_cnt_cookie))
return;
@ -977,14 +980,19 @@ inline void p_validate_off_flag(struct p_ed_process *p_source, long p_val, int *
p_ed_is_off_off(p_source, p_val, p_ret);
}
notrace int p_verify_ovl_create_or_link(struct p_ed_process *p_source) {
#if P_OVL_OVERRIDE_SYNC_MODE
notrace int p_verify_ovl_override_sync(struct p_ed_process *p_source) {
register unsigned long p_off = p_source->p_ed_task.p_off ^ p_global_off_cookie; // Decode
p_validate_off_flag(p_source,p_off,NULL); // Validate
#if P_OVL_OVERRIDE_SYNC_MODE == 2
return p_off == 3 * p_global_cnt_cookie;
#else
return p_off == 2 * p_global_cnt_cookie;
#endif
}
#endif
notrace void p_ed_is_off_off_wrap(struct p_ed_process *p_source) {
@ -1204,7 +1212,7 @@ static unsigned int p_iterate_lkrg_tasks_paranoid(void) {
return p_ret;
}
int p_cmp_creds(struct p_cred *p_orig, const struct cred *p_current_cred, struct task_struct *p_current, char p_opt) {
static int p_cmp_creds(struct p_cred *p_orig, const struct cred *p_current_cred, struct task_struct *p_current, char p_opt) {
int p_ret = 0;
@ -1346,8 +1354,7 @@ static int p_cmp_tasks(struct p_ed_process *p_orig, struct task_struct *p_curren
}
p_ret += p_cmp_creds(&p_orig->p_ed_task.p_cred, p_current_cred, p_current, 0x1);
if (p_ret)
p_ret += p_cmp_creds(&p_orig->p_ed_task.p_real_cred, p_current_real_cred, p_current, 0x1);
p_ret += p_cmp_creds(&p_orig->p_ed_task.p_real_cred, p_current_real_cred, p_current, 0x1);
/* Namespaces */
P_CMP_PTR(p_orig->p_ed_task.p_nsproxy, p_current->nsproxy, P_NS_ESCAPE "nsproxy")
@ -1640,7 +1647,12 @@ int p_ed_enforce_pcfi(struct task_struct *p_task, struct p_ed_process *p_orig, s
struct stack_frame p_frame;
#endif
#elif defined(CONFIG_ARM64)
# if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,19,0)) \
|| (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(9,2))
struct unwind_state p_frame;
# else
struct stackframe p_frame;
# endif
#elif defined(CONFIG_ARM)
struct stackframe p_frame;
const void *p_sp = (const void *)thread_saved_sp(p_task);
@ -1965,22 +1977,22 @@ int p_exploit_detection_init(void) {
goto p_exploit_detection_init_out;
}
P_SYM_INIT(__kernel_text_address, int (*)(unsigned long))
P_SYM_INIT(mm_find_pmd, pmd_t *(*)(struct mm_struct *, unsigned long))
P_SYM_INIT(__kernel_text_address)
P_SYM_INIT(mm_find_pmd)
#if defined(CONFIG_SECCOMP)
P_SYM_INIT(get_seccomp_filter, void (*)(struct task_struct *))
P_SYM_INIT(get_seccomp_filter)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,9,0)
#define p___put_seccomp_filter p_put_seccomp_filter
P_SYM_INIT(__put_seccomp_filter, void (*)(struct seccomp_filter *))
P_SYM_INIT(__put_seccomp_filter)
#else
P_SYM_INIT(put_seccomp_filter, void (*)(struct task_struct *))
P_SYM_INIT(put_seccomp_filter)
#endif
#endif
#ifdef CONFIG_SECURITY_SELINUX
#if (!defined(RHEL_RELEASE_CODE) && LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)) || \
(defined(RHEL_RELEASE_CODE) && RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8, 3))
P_SYM_INIT(selinux_enabled, int *)
P_SYM_INIT(selinux_enabled)
#endif
// SELinux information
#ifdef P_SELINUX_VERIFY

View File

@ -362,7 +362,7 @@ struct p_ed_global_variables {
/* Namespaces */
#include "syscalls/p_sys_setns/p_sys_setns.h"
/* OverlayFS */
#include "syscalls/override/overlayfs/p_ovl_create_or_link/p_ovl_create_or_link.h"
#include "syscalls/override/overlayfs/p_ovl_override_sync/p_ovl_override_sync.h"
/* pCFI */
#include "syscalls/pCFI/p_mark_inode_dirty/p_mark_inode_dirty.h"
#include "syscalls/pCFI/p_schedule/p_schedule.h"
@ -388,8 +388,10 @@ void p_ed_validate_off_flag_wrap(struct p_ed_process *p_source);
void p_set_ed_process_override_on(struct p_ed_process *p_source);
void p_set_ed_process_override_off(struct p_ed_process *p_source);
void p_reset_ed_flags(struct p_ed_process *p_source);
#if P_OVL_OVERRIDE_SYNC_MODE
/* For OverlayFS */
int p_verify_ovl_create_or_link(struct p_ed_process *p_source);
int p_verify_ovl_override_sync(struct p_ed_process *p_source);
#endif
int p_validate_task_f(void *p_arg);
@ -417,30 +419,6 @@ void p_debug_off_flag_override_off(struct p_ed_process *p_source, unsigned int p
void p_debug_off_flag_override_on(struct p_ed_process *p_source, unsigned int p_id, struct pt_regs *p_regs);
#endif
#ifdef P_LKRG_CUSTOM_GET_RANDOM_LONG
static DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], p_get_random_int_hash);
static inline unsigned long get_random_long(void) {
__u32 *p_hash;
__u32 p_random_int_secret;
unsigned long p_ret;
if (arch_get_random_long(&p_ret))
return p_ret;
get_random_bytes(&p_random_int_secret, sizeof(p_random_int_secret));
p_hash = get_cpu_var(p_get_random_int_hash);
p_hash[0] += current->pid + jiffies + get_cycles();
md5_transform(p_hash, &p_random_int_secret);
p_ret = *(unsigned long *)p_hash;
put_cpu_var(p_get_random_int_hash);
return p_ret;
}
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,3,0)
#define p_force_sig(sig) force_sig((sig))
#else

View File

@ -22,7 +22,7 @@
int p_selinux_state_init(void) {
P_SYM_INIT(selinux_state, struct p_selinux_state *)
P_SYM_INIT(selinux_state)
p_selinux_state_update();
return P_LKRG_SUCCESS;
@ -45,7 +45,7 @@ int p_selinux_state_enforcing(void) {
#else
int p_selinux_state_init(void) {
P_SYM_INIT(selinux_enforcing, int *)
P_SYM_INIT(selinux_enforcing)
p_selinux_state_update();
return P_LKRG_SUCCESS;

View File

@ -32,8 +32,6 @@ static struct kretprobe p_x32_sys_keyctl_kretprobe = {
.handler = p_x32_sys_keyctl_ret,
.entry_handler = p_x32_sys_keyctl_entry,
.data_size = sizeof(struct p_x32_sys_keyctl_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -28,8 +28,6 @@ static struct kretprobe p_cap_task_prctl_kretprobe = {
.handler = p_cap_task_prctl_ret,
.entry_handler = p_cap_task_prctl_entry,
.data_size = sizeof(struct p_cap_task_prctl_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -28,8 +28,6 @@ static struct kretprobe p_sys_capset_kretprobe = {
.handler = p_sys_capset_ret,
.entry_handler = p_sys_capset_entry,
.data_size = sizeof(struct p_sys_capset_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -35,8 +35,6 @@ static struct kretprobe p_compat_sys_add_key_kretprobe = {
.handler = p_compat_sys_add_key_ret,
.entry_handler = p_compat_sys_add_key_entry,
.data_size = sizeof(struct p_compat_sys_add_key_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -35,8 +35,6 @@ static struct kretprobe p_compat_sys_capset_kretprobe = {
.handler = p_compat_sys_capset_ret,
.entry_handler = p_compat_sys_capset_entry,
.data_size = sizeof(struct p_compat_sys_capset_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -30,8 +30,6 @@ static struct kretprobe p_compat_sys_keyctl_kretprobe = {
.handler = p_compat_sys_keyctl_ret,
.entry_handler = p_compat_sys_keyctl_entry,
.data_size = sizeof(struct p_compat_sys_keyctl_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -35,8 +35,6 @@ static struct kretprobe p_compat_sys_request_key_kretprobe = {
.handler = p_compat_sys_request_key_ret,
.entry_handler = p_compat_sys_request_key_entry,
.data_size = sizeof(struct p_compat_sys_request_key_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -34,8 +34,6 @@ static struct kretprobe p_security_bprm_committed_creds_kretprobe = {
.handler = p_security_bprm_committed_creds_ret,
.entry_handler = NULL,
.data_size = sizeof(struct p_security_bprm_committed_creds_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -36,8 +36,6 @@ static struct kretprobe p_security_bprm_committing_creds_kretprobe = {
.handler = p_security_bprm_committing_creds_ret,
.entry_handler = p_security_bprm_committing_creds_entry,
.data_size = sizeof(struct p_security_bprm_committing_creds_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -28,8 +28,6 @@ static struct kretprobe p_key_change_session_keyring_kretprobe = {
.handler = p_key_change_session_keyring_ret,
.entry_handler = p_key_change_session_keyring_entry,
.data_size = sizeof(struct p_key_change_session_keyring_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -28,8 +28,6 @@ static struct kretprobe p_sys_add_key_kretprobe = {
.handler = p_sys_add_key_ret,
.entry_handler = p_sys_add_key_entry,
.data_size = sizeof(struct p_sys_add_key_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -28,8 +28,6 @@ static struct kretprobe p_sys_keyctl_kretprobe = {
.handler = p_sys_keyctl_ret,
.entry_handler = p_sys_keyctl_entry,
.data_size = sizeof(struct p_sys_keyctl_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -28,8 +28,6 @@ static struct kretprobe p_sys_request_key_kretprobe = {
.handler = p_sys_request_key_ret,
.entry_handler = p_sys_request_key_entry,
.data_size = sizeof(struct p_sys_request_key_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -1,78 +0,0 @@
/*
* pi3's Linux kernel Runtime Guard
*
* Component:
* - Intercept 'ovl_create_or_link' function
*
* Notes:
* - We are maintianing Red-Black tree of pid's for Exploit Detection feature.
* When process calls 'ovl_create_or_link', we need to correctly handle
* this situation and adjust 'off' flag
*
* Caveats:
* - None
*
* Timeline:
* - Created: 28.III.2019
*
* Author:
* - Adam 'pi3' Zabrocki (http://pi3.com.pl)
*
*/
#include "../../../../../../p_lkrg_main.h"
char p_ovl_create_or_link_kretprobe_state = 0;
static struct kretprobe p_ovl_create_or_link_kretprobe = {
.kp.symbol_name = "ovl_create_or_link",
.handler = p_ovl_create_or_link_ret,
.entry_handler = p_ovl_create_or_link_entry,
.data_size = sizeof(struct p_ovl_create_or_link_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};
void p_reinit_ovl_create_or_link_kretprobe(void) {
memset(&p_ovl_create_or_link_kretprobe,0x0,sizeof(struct kretprobe));
p_ovl_create_or_link_kretprobe.kp.symbol_name = "ovl_create_or_link";
p_ovl_create_or_link_kretprobe.handler = p_ovl_create_or_link_ret;
p_ovl_create_or_link_kretprobe.entry_handler = p_ovl_create_or_link_entry;
p_ovl_create_or_link_kretprobe.data_size = sizeof(struct p_ovl_create_or_link_data);
p_ovl_create_or_link_kretprobe.maxactive = 40;
}
int p_ovl_create_or_link_entry(struct kretprobe_instance *p_ri, struct pt_regs *p_regs) {
return 0;
}
notrace int p_ovl_create_or_link_ret(struct kretprobe_instance *ri, struct pt_regs *p_regs) {
struct p_ed_process *p_tmp;
unsigned long p_flags;
if (p_is_ed_task(current)) {
// Update process
p_tasks_write_lock(&p_flags);
if ( (p_tmp = p_find_ed_by_pid(task_pid_nr(current))) != NULL) {
if (p_verify_ovl_create_or_link(p_tmp)) {
#ifdef P_LKRG_TASK_OFF_DEBUG
p_debug_off_flag_override_on(p_tmp, 30, p_regs);
#endif
p_set_ed_process_override_on(p_tmp);
}
}
p_ed_validate_current();
p_ed_enforce_pcfi(current, p_tmp, p_regs);
p_tasks_write_unlock(&p_flags);
}
return 0;
}
GENERATE_INSTALL_FUNC(ovl_create_or_link)

View File

@ -1,39 +0,0 @@
/*
* pi3's Linux kernel Runtime Guard
*
* Component:
* - Intercept 'ovl_create_or_link' function
*
* Notes:
* - We are maintianing Red-Black tree of pid's for Exploit Detection feature.
* When process calls 'ovl_create_or_link', we need to correctly handle
* this situation and adjust 'off' flag
*
* Caveats:
* - None
*
* Timeline:
* - Created: 28.III.2019
*
* Author:
* - Adam 'pi3' Zabrocki (http://pi3.com.pl)
*
*/
#ifndef P_LKRG_EXPLOIT_DETECTION_OVL_CREATE_OR_LINK_H
#define P_LKRG_EXPLOIT_DETECTION_OVL_CREATE_OR_LINK_H
/* per-instance private data */
struct p_ovl_create_or_link_data {
ktime_t entry_stamp;
};
extern char p_ovl_create_or_link_kretprobe_state;
int p_ovl_create_or_link_ret(struct kretprobe_instance *ri, struct pt_regs *p_regs);
int p_ovl_create_or_link_entry(struct kretprobe_instance *p_ri, struct pt_regs *p_regs);
int p_install_ovl_create_or_link_hook(int p_isra);
void p_uninstall_ovl_create_or_link_hook(void);
void p_reinit_ovl_create_or_link_kretprobe(void);
#endif

View File

@ -0,0 +1,82 @@
/*
* pi3's Linux kernel Runtime Guard
*
* Component:
* - Intercept 'ovl_dentry_is_whiteout' function which is called by
* 'ovl_create_or_link'.
*
* Notes:
* - We are maintianing Red-Black tree of pid's for Exploit Detection feature.
* When process calls 'ovl_create_or_link', we need to correctly handle
* this situation and adjust 'off' flag
*
* Caveats:
* - Originally, 'ovl_create_or_link' function was hooked.
* Due the fact it is declared with 'static' keyword, it may be inlined.
*
* Timeline:
* - Modified: 27.VII.2022
* - Created: 28.III.2019
*
* Author:
* - Adam 'pi3' Zabrocki (http://pi3.com.pl)
*
*/
#include "../../../../../../p_lkrg_main.h"
#if P_OVL_OVERRIDE_SYNC_MODE
char p_ovl_override_sync_kretprobe_state = 0;
static struct kretprobe p_ovl_override_sync_kretprobe = {
.kp.symbol_name = P_OVL_OVERRIDE_SYNC_FUNC,
.handler = p_ovl_override_sync_ret,
.entry_handler = p_ovl_override_sync_entry,
.data_size = sizeof(struct p_ovl_override_sync_data),
};
void p_reinit_ovl_override_sync_kretprobe(void) {
memset(&p_ovl_override_sync_kretprobe,0x0,sizeof(struct kretprobe));
p_ovl_override_sync_kretprobe.kp.symbol_name = P_OVL_OVERRIDE_SYNC_FUNC;
p_ovl_override_sync_kretprobe.handler = p_ovl_override_sync_ret;
p_ovl_override_sync_kretprobe.entry_handler = p_ovl_override_sync_entry;
p_ovl_override_sync_kretprobe.data_size = sizeof(struct p_ovl_override_sync_data);
p_ovl_override_sync_kretprobe.maxactive = p_get_kprobe_maxactive();
}
int p_ovl_override_sync_entry(struct kretprobe_instance *p_ri, struct pt_regs *p_regs) {
return 0;
}
notrace int p_ovl_override_sync_ret(struct kretprobe_instance *ri, struct pt_regs *p_regs) {
struct p_ed_process *p_tmp;
unsigned long p_flags;
if (p_is_ed_task(current)) {
// Update process
p_tasks_write_lock(&p_flags);
if ( (p_tmp = p_find_ed_by_pid(task_pid_nr(current))) != NULL) {
if (p_verify_ovl_override_sync(p_tmp)) {
#ifdef P_LKRG_TASK_OFF_DEBUG
p_debug_off_flag_override_on(p_tmp, 30, p_regs);
#endif
p_set_ed_process_override_on(p_tmp);
}
}
p_ed_validate_current();
p_ed_enforce_pcfi(current, p_tmp, p_regs);
p_tasks_write_unlock(&p_flags);
}
return 0;
}
GENERATE_INSTALL_FUNC(ovl_override_sync)
#endif

View File

@ -0,0 +1,58 @@
/*
* pi3's Linux kernel Runtime Guard
*
* Component:
* - Intercept 'ovl_dentry_is_whiteout' function which is called by
* 'ovl_create_or_link'.
*
* Notes:
* - We are maintianing Red-Black tree of pid's for Exploit Detection feature.
* When process calls 'ovl_create_or_link', we need to correctly handle
* this situation and adjust 'off' flag
*
* Caveats:
* - Originally, 'ovl_create_or_link' function was hooked.
* Due the fact it is declared with 'static' keyword, it may be inlined.
*
* Timeline:
* - Modified: 27.VII.2022
* - Created: 28.III.2019
*
* Author:
* - Adam 'pi3' Zabrocki (http://pi3.com.pl)
*
*/
#ifndef P_LKRG_EXPLOIT_DETECTION_OVL_OVERRIDE_SYNC_H
#define P_LKRG_EXPLOIT_DETECTION_OVL_OVERRIDE_SYNC_H
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 179) && LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) || \
(defined(RHEL_RELEASE_CODE) && RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(7, 4))
#define P_OVL_OVERRIDE_SYNC_MODE 2
#define P_OVL_OVERRIDE_SYNC_FUNC "ovl_dentry_is_whiteout"
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)
/* Between 4.7 and 4.9, the 'ovl_dentry_is_whiteout' function does not exist */
#define P_OVL_OVERRIDE_SYNC_MODE 1
#define P_OVL_OVERRIDE_SYNC_FUNC "ovl_create_or_link"
#else
#define P_OVL_OVERRIDE_SYNC_MODE 0
#endif
#if P_OVL_OVERRIDE_SYNC_MODE
/* per-instance private data */
struct p_ovl_override_sync_data {
ktime_t entry_stamp;
};
extern char p_ovl_override_sync_kretprobe_state;
int p_ovl_override_sync_ret(struct kretprobe_instance *ri, struct pt_regs *p_regs);
int p_ovl_override_sync_entry(struct kretprobe_instance *p_ri, struct pt_regs *p_regs);
int p_install_ovl_override_sync_hook(int p_isra);
void p_uninstall_ovl_override_sync_hook(void);
void p_reinit_ovl_override_sync_kretprobe(void);
#endif
#endif

View File

@ -29,8 +29,6 @@ static struct kretprobe p_override_creds_kretprobe = {
.handler = p_override_creds_ret,
.entry_handler = p_override_creds_entry,
.data_size = sizeof(struct p_override_creds_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -28,8 +28,6 @@ static struct kretprobe p_revert_creds_kretprobe = {
.handler = p_revert_creds_ret,
.entry_handler = p_revert_creds_entry,
.data_size = sizeof(struct p_revert_creds_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -28,8 +28,6 @@ static struct kretprobe p_pcfi___queue_work_kretprobe = {
.handler = p_pcfi___queue_work_ret,
.entry_handler = p_pcfi___queue_work_entry,
.data_size = sizeof(struct p_pcfi___queue_work_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};
/*

View File

@ -28,8 +28,6 @@ static struct kretprobe p_pcfi_lookup_fast_kretprobe = {
.handler = p_pcfi_lookup_fast_ret,
.entry_handler = p_pcfi_lookup_fast_entry,
.data_size = sizeof(struct p_pcfi_lookup_fast_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};
/*

View File

@ -28,8 +28,6 @@ static struct kretprobe p_pcfi_mark_inode_dirty_kretprobe = {
.handler = p_pcfi_mark_inode_dirty_ret,
.entry_handler = p_pcfi_mark_inode_dirty_entry,
.data_size = sizeof(struct p_pcfi_mark_inode_dirty_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};
/*

View File

@ -28,8 +28,6 @@ static struct kretprobe p_pcfi_schedule_kretprobe = {
.handler = p_pcfi_schedule_ret,
.entry_handler = p_pcfi_schedule_entry,
.data_size = sizeof(struct p_pcfi_schedule_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};
/*

View File

@ -32,8 +32,6 @@ static struct kretprobe p_call_usermodehelper_kretprobe = {
.handler = p_call_usermodehelper_ret,
.entry_handler = p_call_usermodehelper_entry,
.data_size = sizeof(struct p_call_usermodehelper_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};
static const char * const p_umh_global[] = {
@ -44,6 +42,7 @@ static const char * const p_umh_global[] = {
"/bin/true",
"/etc/acpi/events/RadioPower.sh",
"/etc/acpi/wireless-rtl-ac-dc-power.sh",
"/lib/rc/sh/cgroup-release-agent.sh",
"/lib/systemd/systemd-cgroups-agent",
"/lib/systemd/systemd-coredump",
"/sbin/bridge-stp",
@ -61,8 +60,10 @@ static const char * const p_umh_global[] = {
"/sbin/tomoyo-init",
"/sbin/v86d",
"/system/bin/start",
"/usr/bin/modprobe",
"/usr/lib/systemd/systemd-cgroups-agent",
"/usr/lib/systemd/systemd-coredump",
"/usr/libexec/abrt-hook-ccpp",
"/usr/sbin/eppfpga",
"/usr/sbin/modprobe",
"/usr/share/apport/apport",

View File

@ -29,8 +29,6 @@ static struct kretprobe p_call_usermodehelper_exec_kretprobe = {
.handler = p_call_usermodehelper_exec_ret,
.entry_handler = p_call_usermodehelper_exec_entry,
.data_size = sizeof(struct p_call_usermodehelper_exec_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};
int p_call_usermodehelper_exec_entry(struct kretprobe_instance *p_ri, struct pt_regs *p_regs) {

View File

@ -28,8 +28,6 @@ static struct kretprobe p_capable_kretprobe = {
.handler = p_capable_ret,
.entry_handler = p_capable_entry,
.data_size = sizeof(struct p_capable_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};
/*

View File

@ -29,8 +29,6 @@ static struct kretprobe p_do_exit_kretprobe = {
.handler = p_do_exit_ret,
.entry_handler = p_do_exit_entry,
.data_size = sizeof(struct p_do_exit_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -46,8 +46,6 @@ static struct kretprobe p_generic_permission_kretprobe = {
.handler = p_generic_permission_ret,
.entry_handler = p_generic_permission_entry,
.data_size = sizeof(struct p_generic_permission_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};
/*

View File

@ -20,12 +20,23 @@
#include "../../../p_lkrg_main.h"
// to setup kretprobes maxactive
int p_get_kprobe_maxactive(void) {
/*
* Linux default is up to max(10, 2*num_possible_cpus()) so far.
* LKRG old default was 40. Let's use max of these all.
*/
return max_t(unsigned int, 40, 2*num_possible_cpus());
}
int p_install_hook(struct kretprobe *kretprobe, char *state, int p_isra) {
int p_ret;
const char *p_name = kretprobe->kp.symbol_name;
struct p_isra_argument p_isra_arg;
kretprobe->maxactive = p_get_kprobe_maxactive();
if ( (p_ret = register_kretprobe(kretprobe)) < 0) {
if (p_isra && p_ret == -22) {
p_print_log(P_LOG_ISSUE, "[kretprobe] register_kretprobe() for <%s> failed! [err=%d]",

View File

@ -21,6 +21,7 @@
#ifndef P_LKRG_EXPLOIT_DETECTION_INSTALL_H
#define P_LKRG_EXPLOIT_DETECTION_INSTALL_H
int p_get_kprobe_maxactive(void);
int p_install_hook(struct kretprobe *kretprobe, char *state, int p_isra);
void p_uninstall_hook(struct kretprobe *kretprobe, char *state);

View File

@ -29,8 +29,6 @@ static struct kretprobe p_scm_send_kretprobe = {
.handler = p_scm_send_ret,
.entry_handler = p_scm_send_entry,
.data_size = sizeof(struct p_scm_send_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -32,8 +32,6 @@ static struct kretprobe p_seccomp_kretprobe = {
.handler = p_seccomp_ret,
.entry_handler = p_seccomp_entry,
.data_size = sizeof(struct p_seccomp_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};
/*

View File

@ -28,8 +28,6 @@ static struct kretprobe p_security_ptrace_access_kretprobe = {
.handler = p_security_ptrace_access_ret,
.entry_handler = p_security_ptrace_access_entry,
.data_size = sizeof(struct p_security_ptrace_access_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};
int p_security_ptrace_access_entry(struct kretprobe_instance *p_ri, struct pt_regs *p_regs) {

View File

@ -30,8 +30,6 @@ static struct kretprobe p_sel_write_enforce_kretprobe = {
.handler = p_sel_write_enforce_ret,
.entry_handler = p_sel_write_enforce_entry,
.data_size = sizeof(struct p_sel_write_enforce_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};
/*

View File

@ -28,8 +28,6 @@ static struct kretprobe p_set_current_groups_kretprobe = {
.handler = p_set_current_groups_ret,
.entry_handler = p_set_current_groups_entry,
.data_size = sizeof(struct p_set_current_groups_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -28,8 +28,6 @@ static struct kretprobe p_sys_setfsgid_kretprobe = {
.handler = p_sys_setfsgid_ret,
.entry_handler = p_sys_setfsgid_entry,
.data_size = sizeof(struct p_sys_setfsgid_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -28,8 +28,6 @@ static struct kretprobe p_sys_setfsuid_kretprobe = {
.handler = p_sys_setfsuid_ret,
.entry_handler = p_sys_setfsuid_entry,
.data_size = sizeof(struct p_sys_setfsuid_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -28,8 +28,6 @@ static struct kretprobe p_sys_setgid_kretprobe = {
.handler = p_sys_setgid_ret,
.entry_handler = p_sys_setgid_entry,
.data_size = sizeof(struct p_sys_setgid_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -28,8 +28,6 @@ static struct kretprobe p_sys_setns_kretprobe = {
.handler = p_sys_setns_ret,
.entry_handler = p_sys_setns_entry,
.data_size = sizeof(struct p_sys_setns_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -28,8 +28,6 @@ static struct kretprobe p_sys_setregid_kretprobe = {
.handler = p_sys_setregid_ret,
.entry_handler = p_sys_setregid_entry,
.data_size = sizeof(struct p_sys_setregid_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -28,8 +28,6 @@ static struct kretprobe p_sys_setresgid_kretprobe = {
.handler = p_sys_setresgid_ret,
.entry_handler = p_sys_setresgid_entry,
.data_size = sizeof(struct p_sys_setresgid_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -28,8 +28,6 @@ static struct kretprobe p_sys_setresuid_kretprobe = {
.handler = p_sys_setresuid_ret,
.entry_handler = p_sys_setresuid_entry,
.data_size = sizeof(struct p_sys_setresuid_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -28,8 +28,6 @@ static struct kretprobe p_sys_setreuid_kretprobe = {
.handler = p_sys_setreuid_ret,
.entry_handler = p_sys_setreuid_entry,
.data_size = sizeof(struct p_sys_setreuid_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -28,8 +28,6 @@ static struct kretprobe p_sys_setuid_kretprobe = {
.handler = p_sys_setuid_ret,
.entry_handler = p_sys_setuid_entry,
.data_size = sizeof(struct p_sys_setuid_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -32,8 +32,6 @@ static struct kretprobe p_sys_unshare_kretprobe = {
.handler = p_sys_unshare_ret,
.entry_handler = p_sys_unshare_entry,
.data_size = sizeof(struct p_sys_unshare_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -29,8 +29,6 @@ static struct kretprobe p_wake_up_new_task_kretprobe = {
.handler = p_wake_up_new_task_ret,
.entry_handler = p_wake_up_new_task_entry,
.data_size = sizeof(struct p_wake_up_new_task_data),
/* Probe up to 40 instances concurrently. */
.maxactive = 40,
};

View File

@ -211,6 +211,12 @@ void p_check_integrity(struct work_struct *p_work) {
p_tmp_hash = hash_from_CPU_data(p_tmp_cpus);
p_read_cpu_unlock();
/* Verify kprobes now */
if (lkrg_verify_kprobes()) {
/* I'm hacked! ;( */
p_hack_check++;
}
p_text_section_lock();
/*
@ -274,8 +280,8 @@ void p_check_integrity(struct work_struct *p_work) {
if (p_db.kernel_stext.p_hash != p_tmp_hash) {
#if defined(P_LKRG_JUMP_LABEL_STEXT_DEBUG)
char *p_str1 = (unsigned char *)p_db.kernel_stext.p_addr;
char *p_str2 = (unsigned char *)p_db.kernel_stext_copy;
unsigned char *p_str1 = (unsigned char *)p_db.kernel_stext.p_addr;
unsigned char *p_str2 = (unsigned char *)p_db.kernel_stext_copy;
char p_eh_buf[0x100];
#endif
/* We detected core kernel .text corruption - we are hacked and can't recover */
@ -285,7 +291,7 @@ void p_check_integrity(struct work_struct *p_work) {
for (p_tmp = 0; p_tmp < p_db.kernel_stext.p_size; p_tmp++) {
if (p_str2[p_tmp] != p_str1[p_tmp]) {
sprint_symbol_no_offset(p_eh_buf,(unsigned long)((unsigned long)p_db.kernel_stext.p_addr+(unsigned long)p_tmp));
p_print_log(P_LOG_WATCH, "copy[0x%x] vs now[0x%x] offset[%d | 0x%x] symbol[%s]",
p_print_log(P_LOG_ISSUE, "copy[0x%x] vs now[0x%x] offset[%d | 0x%x] symbol[%s]",
p_str2[p_tmp],
p_str1[p_tmp],
p_tmp,
@ -322,6 +328,7 @@ void p_check_integrity(struct work_struct *p_work) {
p_db.kernel_rodata.p_hash, p_tmp_hash);
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,19,0)
/*
* Checking memory block:
* "__iommu_table"
@ -343,6 +350,7 @@ void p_check_integrity(struct work_struct *p_work) {
p_print_log(P_LOG_WATCH, "IOMMU table hash expected 0x%llx vs. actual 0x%llx",
p_db.kernel_iommu_table.p_hash, p_tmp_hash);
}
#endif
/*
* Checking this kernel modules integrity.

View File

@ -18,6 +18,9 @@
#ifndef P_LKRG_INTEGRITY_TIMER_H
#define P_LKRG_INTEGRITY_TIMER_H
/* Submodule for verifying kprobes */
#include "verify_kprobes/p_verify_kprobes.h"
#define p_alloc_offload() kmem_cache_alloc(p_offload_cache, GFP_ATOMIC)
#define p_free_offload(name) kmem_cache_free(p_offload_cache, (void *)(name))

View File

@ -0,0 +1,74 @@
/*
* pi3's Linux kernel Runtime Guard
*
* Component:
* - Integrity verification kprobe verification submodule
*
* Notes:
* - Verify if kprobes are enabled and correctly run
*
* Timeline:
* - Created: 30.XI.2022
*
* Author:
* - Adam 'pi3' Zabrocki (http://pi3.com.pl)
*
*/
#include "../../../p_lkrg_main.h"
static int p_lkrg_dummy_entry(struct kretprobe_instance *p_ri, struct pt_regs *p_regs);
static int p_lkrg_dummy_ret(struct kretprobe_instance *ri, struct pt_regs *p_regs);
static char p_lkrg_dummy_kretprobe_state = 0;
static struct kretprobe p_lkrg_dummy_kretprobe = {
.kp.symbol_name = "lkrg_dummy",
.handler = p_lkrg_dummy_ret,
.entry_handler = p_lkrg_dummy_entry,
};
__attribute__((optimize(0)))
noinline int lkrg_dummy(int arg) {
p_debug_log(P_LOG_DEBUG,
"[lkrg_dummy] Argument value: [%d]\n",arg);
/*
* TODO:
* We can verify integrity of the internal kprobe structures here
*/
return arg+1;
}
int lkrg_verify_kprobes(void) {
int p_ret = 0, ret = -1;
/* Verify kprobes now */
if ( (ret = lkrg_dummy(0)) != 3) {
/* I'm hacked! ;( */
p_print_log(P_LOG_ALERT, "DETECT: Kprobes: Don't work as intended (disabled?)");
p_ret = -1;
}
p_print_log(P_LOG_WATCH, "lkrg_dummy returned %d vs. expected 3",ret);
return p_ret;
}
static int p_lkrg_dummy_entry(struct kretprobe_instance *p_ri, struct pt_regs *p_regs) {
p_regs_set_arg1(p_regs, p_regs_get_arg1(p_regs) + 1);
return 0;
}
static int p_lkrg_dummy_ret(struct kretprobe_instance *ri, struct pt_regs *p_regs) {
p_regs_set_ret(p_regs, p_regs_get_ret(p_regs) + 1);
return 0;
}
GENERATE_INSTALL_FUNC(lkrg_dummy)

View File

@ -0,0 +1,26 @@
/*
* pi3's Linux kernel Runtime Guard
*
* Component:
* - Integrity verification kprobe verification submodule
*
* Notes:
* - Verify if kprobes are enabled and correctly run
*
* Timeline:
* - Created: 2.XII.2022
*
* Author:
* - Adam 'pi3' Zabrocki (http://pi3.com.pl)
*
*/
#ifndef P_LKRG_INTEGRITY_VERIFY_KPROBES_H
#define P_LKRG_INTEGRITY_VERIFY_KPROBES_H
int lkrg_verify_kprobes(void);
int p_install_lkrg_dummy_hook(int p_isra);
void p_uninstall_lkrg_dummy_hook(void);
#endif

View File

@ -28,19 +28,19 @@
int p_kmod_init(void) {
#if defined(CONFIG_DYNAMIC_DEBUG)
P_SYM_INIT(ddebug_tables, struct list_head *)
P_SYM_INIT(ddebug_lock, struct mutex *)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0)
P_SYM_INIT(ddebug_remove_module, int(*)(const char *))
P_SYM_INIT(ddebug_tables)
P_SYM_INIT(ddebug_lock)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0) && LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0)
P_SYM_INIT(ddebug_remove_module)
#endif
#endif
P_SYM_INIT(modules, struct list_head *)
P_SYM_INIT(module_kset, struct kset **)
P_SYM_INIT(modules)
P_SYM_INIT(module_kset)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,12,0)
P_SYM_INIT(module_mutex, struct mutex *)
P_SYM_INIT(find_module, struct module* (*)(const char *))
P_SYM_INIT(module_mutex)
P_SYM_INIT(find_module)
#else
P_SYM(p_module_mutex) = (struct mutex *)&module_mutex;
P_SYM(p_find_module) = (struct module* (*)(const char *))find_module;
@ -50,7 +50,7 @@ int p_kmod_init(void) {
p_debug_log(P_LOG_DEBUG, "<p_kmod_init> "
#if defined(CONFIG_DYNAMIC_DEBUG)
"p_ddebug_tables[0x%lx] p_ddebug_lock[0x%lx] "
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0) && LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0)
"p_ddebug_remove_module[0x%lx]"
#endif
#endif
@ -59,7 +59,7 @@ int p_kmod_init(void) {
#if defined(CONFIG_DYNAMIC_DEBUG)
(unsigned long)P_SYM(p_ddebug_tables),
(unsigned long)P_SYM(p_ddebug_lock),
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0) && LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0)
(unsigned long)P_SYM(p_ddebug_remove_module),
#endif
#endif

View File

@ -249,7 +249,8 @@ p_module_event_notifier_activity_out:
void p_verify_module_live(struct module *p_mod) {
if (p_ovl_create_or_link_kretprobe_state) {
#if P_OVL_OVERRIDE_SYNC_MODE
if (p_ovl_override_sync_kretprobe_state) {
/* We do not need to do anything for now */
return;
}
@ -268,9 +269,9 @@ void p_verify_module_live(struct module *p_mod) {
P_CTRL(p_kint_validate) = 0;
p_lkrg_close_rw();
/* Try to install the hook */
if (p_install_ovl_create_or_link_hook(1)) {
if (p_install_ovl_override_sync_hook(1)) {
p_print_log(P_LOG_FAULT,
"OverlayFS is being loaded but LKRG can't hook 'ovl_create_or_link' function. "
"OverlayFS is being loaded but LKRG can't hook '" P_OVL_OVERRIDE_SYNC_FUNC "'. "
"It is very likely that LKRG will produce false positives. Please reload LKRG.");
}
/* Done */
@ -278,11 +279,13 @@ void p_verify_module_live(struct module *p_mod) {
P_CTRL(p_kint_validate) = p_tmp_val;
p_lkrg_close_rw();
}
#endif
}
void p_verify_module_going(struct module *p_mod) {
if (!p_ovl_create_or_link_kretprobe_state) {
#if P_OVL_OVERRIDE_SYNC_MODE
if (!p_ovl_override_sync_kretprobe_state) {
/* We do not need to do anything for now */
return;
}
@ -300,13 +303,15 @@ void p_verify_module_going(struct module *p_mod) {
P_CTRL(p_kint_validate) = 0;
p_lkrg_close_rw();
/* Try to uninstall the hook */
p_uninstall_ovl_create_or_link_hook();
p_reinit_ovl_create_or_link_kretprobe();
p_uninstall_ovl_override_sync_hook();
p_reinit_ovl_override_sync_kretprobe();
/* Done */
p_lkrg_open_rw();
P_CTRL(p_kint_validate) = p_tmp_val;
p_lkrg_close_rw();
}
#endif
}
void p_register_module_notifier(void) {

View File

@ -34,7 +34,8 @@ static int p_netevent_notifier(struct notifier_block *p_nb, unsigned long p_val,
static int p_inet6addr_notifier(struct notifier_block *p_nb, unsigned long p_val, void *p_data);
#endif
static int p_inetaddr_notifier(struct notifier_block *p_nb, unsigned long p_val, void *p_data);
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,16,0)
#if defined(CONFIG_PROFILING) && LINUX_VERSION_CODE < KERNEL_VERSION(5,16,0) \
&& (!defined(RHEL_RELEASE_CODE) || (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(9,2)))
static int p_taskfree_notifier(struct notifier_block *p_nb, unsigned long p_val, void *p_data);
static int p_profile_event_exit_notifier(struct notifier_block *p_nb, unsigned long p_val, void *p_data);
static int p_profile_event_munmap_notifier(struct notifier_block *p_nb, unsigned long p_val, void *p_data);
@ -81,7 +82,8 @@ static struct notifier_block p_inetaddr_notifier_nb = {
.notifier_call = p_inetaddr_notifier,
};
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,16,0)
#if defined(CONFIG_PROFILING) && LINUX_VERSION_CODE < KERNEL_VERSION(5,16,0) \
&& (!defined(RHEL_RELEASE_CODE) || (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(9,2)))
static struct notifier_block p_taskfree_notifier_nb = {
.notifier_call = p_taskfree_notifier,
};
@ -123,7 +125,8 @@ void p_register_notifiers(void) {
register_inet6addr_notifier(&p_inet6addr_notifier_nb);
#endif
register_inetaddr_notifier(&p_inetaddr_notifier_nb);
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,16,0)
#if defined(CONFIG_PROFILING) && LINUX_VERSION_CODE < KERNEL_VERSION(5,16,0) \
&& (!defined(RHEL_RELEASE_CODE) || (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(9,2)))
task_handoff_register(&p_taskfree_notifier_nb);
profile_event_register(PROFILE_TASK_EXIT, &p_profile_event_exit_notifier_nb);
profile_event_register(PROFILE_MUNMAP, &p_profile_event_munmap_notifier_nb);
@ -198,7 +201,8 @@ static int p_inetaddr_notifier(struct notifier_block *p_nb, unsigned long p_val,
return 0;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,16,0)
#if defined(CONFIG_PROFILING) && LINUX_VERSION_CODE < KERNEL_VERSION(5,16,0) \
&& (!defined(RHEL_RELEASE_CODE) || (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(9,2)))
static int p_taskfree_notifier(struct notifier_block *p_nb, unsigned long p_val, void *p_data) {
/* 0.01% */
@ -260,7 +264,8 @@ void p_deregister_notifiers(void) {
unregister_inet6addr_notifier(&p_inet6addr_notifier_nb);
#endif
unregister_inetaddr_notifier(&p_inetaddr_notifier_nb);
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,16,0)
#if defined(CONFIG_PROFILING) && LINUX_VERSION_CODE < KERNEL_VERSION(5,16,0) \
&& (!defined(RHEL_RELEASE_CODE) || (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(9,2)))
task_handoff_unregister(&p_taskfree_notifier_nb);
profile_event_unregister(PROFILE_TASK_EXIT, &p_profile_event_exit_notifier_nb);
profile_event_unregister(PROFILE_MUNMAP, &p_profile_event_munmap_notifier_nb);

View File

@ -33,10 +33,14 @@
#define P_M_MORE_OFTEN_RATE 4294967 /* 0.1% */
#define P_S_MORE_OFTEN_RATE 2147483 /* 0.05% */
#define P_SS_MORE_OFTEN_RATE 429496 /* 0.01% */
#define P_M_SS_MORE_OFTEN_RATE 21474 /* 0.005% */
#define P_M_SS_MORE_OFTEN_RATE 214748 /* 0.005% */
#define P_S_SS_MORE_OFTEN_RATE 42949 /* 0.001% */
#define P_CHECK_RANDOM(x) (get_random_int() <= x)
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)
#define get_random_u32 get_random_int
#endif
#define P_CHECK_RANDOM(x) (get_random_u32() <= x)
#define P_TRY_OFFLOAD_NOTIFIER(rate, where) \
do { \

View File

@ -76,7 +76,9 @@ static struct p_addr_name {
P_LKRG_DEBUG_RULE(hash_from_ex_table),
P_LKRG_DEBUG_RULE(hash_from_kernel_stext),
P_LKRG_DEBUG_RULE(hash_from_kernel_rodata),
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,19,0)
P_LKRG_DEBUG_RULE(hash_from_iommu_table),
#endif
P_LKRG_DEBUG_RULE(hash_from_CPU_data),
P_LKRG_DEBUG_RULE(p_create_database),
P_LKRG_DEBUG_RULE(p_register_notifiers),
@ -123,7 +125,9 @@ static struct p_addr_name {
P_LKRG_DEBUG_RULE_KPROBE(p_sys_setfsgid),
P_LKRG_DEBUG_RULE_KPROBE(p_call_usermodehelper_exec),
P_LKRG_DEBUG_RULE_KPROBE(p_set_current_groups),
P_LKRG_DEBUG_RULE_KPROBE(p_ovl_create_or_link),
#if P_OVL_OVERRIDE_SYNC_MODE
P_LKRG_DEBUG_RULE_KPROBE(p_ovl_override_sync),
#endif
P_LKRG_DEBUG_RULE_KPROBE(p_revert_creds),
P_LKRG_DEBUG_RULE_KPROBE(p_override_creds),
P_LKRG_DEBUG_RULE_KPROBE(p_security_bprm_committing_creds),

View File

@ -25,6 +25,8 @@
#ifndef P_LKRG_WRAPPER_H
#define P_LKRG_WRAPPER_H
extern struct mutex p_ro_page_mutex;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
static inline void p_set_uid(kuid_t *p_arg, unsigned int p_val) {
@ -86,7 +88,21 @@ static inline unsigned int p_get_gid(const kgid_t *p_from) {
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 6)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0)
static inline void *p_module_core(struct module *p_mod) {
return p_mod->mem[MOD_TEXT].base;
}
static inline unsigned int p_init_text_size(struct module *p_mod) {
return p_mod->mem[MOD_INIT_TEXT].size;
}
static inline unsigned int p_core_text_size(struct module *p_mod) {
return p_mod->mem[MOD_TEXT].size;
}
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 6)
#if defined(CONFIG_GRKERNSEC)
@ -175,7 +191,37 @@ static inline struct static_key *p_jump_entry_key(const struct jump_entry *entry
#if defined(CONFIG_DYNAMIC_DEBUG)
static inline int p_ddebug_remove_module(const char *p_name) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 1, 0)
/*
* Starting from the following commit:
* https://github.com/torvalds/linux/commit/7deabd67498869640c937c9bd83472574b7dea0b
*
* 'ddebug_remove_module' is not exported anymore and defined as 'static'.
* However, we can implement the same logic by hand.
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0)
struct p_ddebug_table {
struct list_head link, maps;
const char *mod_name;
unsigned int num_ddebugs;
struct _ddebug *ddebugs;
};
struct p_ddebug_table *dt, *nextdt;
int p_ret = -ENOENT;
list_for_each_entry_safe(dt, nextdt, P_SYM(p_ddebug_tables), link) {
if (dt->mod_name == p_name) {
list_del_init(&dt->link);
kfree(dt);
p_ret = 0;
break;
}
}
return p_ret;
#elif LINUX_VERSION_CODE < KERNEL_VERSION(5, 1, 0)
return ddebug_remove_module(p_name);
@ -197,10 +243,11 @@ static inline int p_ddebug_remove_module(const char *p_name) {
#ifdef CONFIG_X86
#if defined(CONFIG_X86_64)
/*
* Get
*/
#if defined(CONFIG_X86_64)
static inline unsigned long p_regs_get_arg1(struct pt_regs *p_regs) {
return p_regs->di;
}
@ -246,10 +293,51 @@ static inline unsigned long p_syscall_get_arg2(struct pt_regs *p_regs) {
#else
return p_regs_get_arg2(p_regs);
#endif
}
/*
* Set
*/
static inline void p_regs_set_arg1(struct pt_regs *p_regs, unsigned long p_val) {
p_regs->di = p_val;
}
static inline void p_regs_set_arg2(struct pt_regs *p_regs, unsigned long p_val) {
p_regs->si = p_val;
}
static inline void p_regs_set_ip(struct pt_regs *p_regs, unsigned long p_val) {
p_regs->ip = p_val;
}
static inline void p_regs_set_ret(struct pt_regs *p_regs, unsigned long p_val) {
p_regs->ax = p_val;
}
/*
* Syscalls
*/
static inline void p_syscall_set_arg1(struct pt_regs *p_regs, unsigned long p_val) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,17,0) && defined(CONFIG_ARCH_HAS_SYSCALL_WRAPPER)
p_regs_set_arg1((struct pt_regs *)p_regs_get_arg1(p_regs), p_val);
#else
p_regs_set_arg1(p_regs, p_val);
#endif
}
static inline void p_syscall_set_arg2(struct pt_regs *p_regs, unsigned long p_val) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,17,0) && defined(CONFIG_ARCH_HAS_SYSCALL_WRAPPER)
p_regs_set_arg2((struct pt_regs *)p_regs_get_arg1(p_regs), p_val);
#else
p_regs_set_arg2(p_regs, p_val);
#endif
}
#else
/*
* Get
*/
static inline unsigned long p_regs_get_arg1(struct pt_regs *p_regs) {
return p_regs->ax;
}
@ -301,47 +389,9 @@ static inline unsigned long p_syscall_get_arg2(struct pt_regs *p_regs) {
#endif
}
#endif
/*
* Set
*/
#if defined(CONFIG_X86_64)
static inline void p_regs_set_arg1(struct pt_regs *p_regs, unsigned long p_val) {
p_regs->di = p_val;
}
static inline void p_regs_set_arg2(struct pt_regs *p_regs, unsigned long p_val) {
p_regs->si = p_val;
}
static inline void p_regs_set_ip(struct pt_regs *p_regs, unsigned long p_val) {
p_regs->ip = p_val;
}
/*
* Syscalls
*/
static inline void p_syscall_set_arg1(struct pt_regs *p_regs, unsigned long p_val) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,17,0) && defined(CONFIG_ARCH_HAS_SYSCALL_WRAPPER)
p_regs_set_arg1((struct pt_regs *)p_regs_get_arg1(p_regs), p_val);
#else
p_regs_set_arg1(p_regs, p_val);
#endif
}
static inline void p_syscall_set_arg2(struct pt_regs *p_regs, unsigned long p_val) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,17,0) && defined(CONFIG_ARCH_HAS_SYSCALL_WRAPPER)
p_regs_set_arg2((struct pt_regs *)p_regs_get_arg1(p_regs), p_val);
#else
p_regs_set_arg2(p_regs, p_val);
#endif
}
#else
static inline void p_regs_set_arg1(struct pt_regs *p_regs, unsigned long p_val) {
p_regs->ax = p_val;
}
@ -358,6 +408,10 @@ static inline void p_regs_set_ip(struct pt_regs *p_regs, unsigned long p_val) {
p_regs->ip = p_val;
}
static inline void p_regs_set_ret(struct pt_regs *p_regs, unsigned long p_val) {
p_regs->ax = p_val;
}
/*
* Syscalls
*/
@ -455,6 +509,8 @@ static inline void p_lkrg_open_rw(void) {
unsigned long p_flags;
mutex_lock(&p_ro_page_mutex);
// preempt_disable();
barrier();
p_set_memory_rw((unsigned long)P_CTRL_ADDR,1);
@ -472,6 +528,8 @@ static inline void p_lkrg_close_rw(void) {
p_set_memory_ro((unsigned long)P_CTRL_ADDR,1);
barrier();
// preempt_enable(); //_no_resched();
mutex_unlock(&p_ro_page_mutex);
}
/* ARM */
@ -542,6 +600,10 @@ static inline void p_regs_set_ip(struct pt_regs *p_regs, unsigned long p_val) {
p_regs->ARM_pc = p_val;
}
static inline void p_regs_set_ret(struct pt_regs *p_regs, unsigned long p_val) {
p_regs->ARM_r0 = p_val;
}
/*
* Syscalls
*/
@ -587,6 +649,8 @@ static inline void p_lkrg_open_rw(void) {
unsigned long p_flags;
mutex_lock(&p_ro_page_mutex);
preempt_disable();
barrier();
p_set_memory_rw((unsigned long)P_CTRL_ADDR,1);
@ -604,6 +668,8 @@ static inline void p_lkrg_close_rw(void) {
p_set_memory_ro((unsigned long)P_CTRL_ADDR,1);
barrier();
preempt_enable(); //_no_resched();
mutex_unlock(&p_ro_page_mutex);
}
/* ARM64 */
@ -674,6 +740,10 @@ static inline void p_regs_set_ip(struct pt_regs *p_regs, unsigned long p_val) {
p_regs->pc = p_val;
}
static inline void p_regs_set_ret(struct pt_regs *p_regs, unsigned long p_val) {
p_regs->regs[0] = p_val;
}
/*
* Syscalls
*/
@ -741,6 +811,8 @@ static inline void p_lkrg_open_rw(void) {
unsigned long p_flags;
mutex_lock(&p_ro_page_mutex);
preempt_disable();
barrier();
p_set_memory_rw((unsigned long)P_CTRL_ADDR,1);
@ -758,6 +830,8 @@ static inline void p_lkrg_close_rw(void) {
p_set_memory_ro((unsigned long)P_CTRL_ADDR,1);
barrier();
preempt_enable(); //_no_resched();
mutex_unlock(&p_ro_page_mutex);
}
#endif

View File

@ -45,6 +45,8 @@ static enum cpuhp_state p_hot_cpus;
#endif
unsigned int p_attr_init = 0;
DEFINE_MUTEX(p_ro_page_mutex);
p_ro_page p_ro __p_lkrg_read_only = {
#if !defined(CONFIG_ARM) && (!defined(P_KERNEL_AGGRESSIVE_INLINING) && defined(CONFIG_X86))
@ -407,17 +409,38 @@ static int __init p_lkrg_register(void) {
p_parse_module_params();
P_SYM(p_find_me) = THIS_MODULE;
P_SYM_INIT(freeze_processes, int (*)(void))
P_SYM_INIT(thaw_processes, void (*)(void))
/*
* Verify if kprobes run as intended
*/
/* Register kprobes hooks necessary to verify kprobes itself */
if (p_install_lkrg_dummy_hook(0)) {
p_print_log(P_LOG_FATAL, "Can't hook 'lkrg_dummy'");
return P_LKRG_GENERAL_ERROR;
}
/* Verify kprobes now */
if (lkrg_verify_kprobes()) {
/*
* Kprobes does not work as intended.
* LKRG can't function without it, stop initialization!
*/
p_print_log(P_LOG_FATAL, "Can't continue initialization without working kprobes");
p_uninstall_lkrg_dummy_hook();
return P_LKRG_GENERAL_ERROR;
}
P_SYM_INIT(freeze_processes)
P_SYM_INIT(thaw_processes)
#if defined(CONFIG_X86) && LINUX_VERSION_CODE >= KERNEL_VERSION(5,8,0)
P_SYM_INIT(native_write_cr4, void (*)(unsigned long))
P_SYM_INIT(native_write_cr4)
#endif
#ifdef P_LKRG_UNEXPORTED_MODULE_ADDRESS
P_SYM_INIT(__module_address, struct module *(*)(unsigned long))
P_SYM_INIT(__module_text_address, struct module *(*)(unsigned long))
P_SYM_INIT(__module_address)
P_SYM_INIT(__module_text_address)
#endif
#if defined(CONFIG_OPTPROBES)
P_SYM_INIT(wait_for_kprobe_optimizer, void (*)(void))
P_SYM_INIT(wait_for_kprobe_optimizer)
#endif
// Freeze all non-kernel processes
@ -477,22 +500,22 @@ static int __init p_lkrg_register(void) {
p_cpu = 1;
#if !defined(CONFIG_ARM64)
P_SYM_INIT(flush_tlb_all, void (*)(void))
P_SYM_INIT(flush_tlb_all)
#endif
#if defined(P_KERNEL_AGGRESSIVE_INLINING)
P_SYM_INIT(set_memory_ro, int (*)(unsigned long, int))
P_SYM_INIT(set_memory_rw, int (*)(unsigned long, int))
P_SYM_INIT(set_memory_ro)
P_SYM_INIT(set_memory_rw)
#if defined(CONFIG_ARM64)
P_SYM_INIT(set_memory_valid, int (*)(unsigned long, int, int))
P_SYM_INIT(set_memory_valid)
#endif
#else
#if defined(CONFIG_X86)
P_SYM_INIT(change_page_attr_set_clr, int (*)(unsigned long *, int, pgprot_t, pgprot_t, int, int, struct page **))
P_SYM_INIT(change_page_attr_set_clr)
#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64)
P_SYM_INIT(change_memory_common, int (*)(unsigned long, int, pgprot_t, pgprot_t))
P_SYM_INIT(change_memory_common)
#else
p_print_log(P_LOG_FATAL, "Unsupported platform");
p_ret = P_LKRG_GENERAL_ERROR;
@ -546,6 +569,7 @@ p_main_error:
p_unregister_arch_metadata();
p_offload_cache_delete();
p_deregister_module_notifier();
p_uninstall_lkrg_dummy_hook();
if (p_db.p_CPU_metadata_array) {
p_kzfree(p_db.p_CPU_metadata_array);
p_db.p_CPU_metadata_array = NULL;
@ -608,7 +632,7 @@ static void __exit p_lkrg_deregister(void) {
p_unregister_arch_metadata();
p_offload_cache_delete();
p_deregister_module_notifier();
p_uninstall_lkrg_dummy_hook();
if (p_db.p_CPU_metadata_array)
p_kzfree(p_db.p_CPU_metadata_array);

View File

@ -73,9 +73,11 @@
#if ( (LINUX_VERSION_CODE < KERNEL_VERSION(4,4,72)) && \
(!(defined(RHEL_RELEASE_CODE)) || \
RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7, 4)))
#define P_LKRG_CUSTOM_GET_RANDOM_LONG
/* We use md5_transform() in our custom get_random_long() */
#include <linux/cryptohash.h>
static inline unsigned long get_random_long(void) {
unsigned long p_ret;
get_random_bytes(&p_ret, sizeof(p_ret));
return p_ret;
}
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,10,0)
@ -235,12 +237,13 @@ typedef struct _p_lkrg_global_symbols_structure {
pmd_t *(*p_mm_find_pmd)(struct mm_struct *mm, unsigned long address);
struct mutex *p_jump_label_mutex;
struct mutex *p_text_mutex;
struct mutex *p_tracepoints_mutex;
struct text_poke_loc **p_tp_vec;
int *p_tp_vec_nr;
#if defined(CONFIG_DYNAMIC_DEBUG)
struct list_head *p_ddebug_tables;
struct mutex *p_ddebug_lock;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0) && LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0)
int (*p_ddebug_remove_module)(const char *p_name);
#endif
#endif
@ -317,8 +320,8 @@ extern p_ro_page p_ro;
#define P_CTRL(p_field) p_ro.p_lkrg_global_ctrl.ctrl.p_field
#define P_CTRL_ADDR &p_ro.p_lkrg_global_ctrl
#define P_SYM_INIT(sym, type) \
if (!(P_SYM(p_ ## sym) = (type)P_SYM(p_kallsyms_lookup_name)(#sym))) { \
#define P_SYM_INIT(sym) \
if (!(P_SYM(p_ ## sym) = (typeof(P_SYM(p_ ## sym)))P_SYM(p_kallsyms_lookup_name)(#sym))) { \
p_print_log(P_LOG_FATAL, "Can't find '" #sym "'"); \
goto p_sym_error; \
}