mirror of https://github.com/openwall/lkrg.git
Compare commits
58 Commits
Author | SHA1 | Date |
---|---|---|
Solar Designer | 3760e0e1bd | |
Adam_pi3 | 310e85d19c | |
Solar Designer | ea1454c28d | |
Solar Designer | d5077fde52 | |
Adam_pi3 | ee41d81599 | |
Adam_pi3 | 687c4790cd | |
Vitaly Chikunov | 617cc87a40 | |
Vitaly Chikunov | 73840d7b91 | |
Solar Designer | 91d3da9ece | |
Solar Designer | 5dc5cfea1f | |
Solar Designer | db35e0e207 | |
Solar Designer | 5cfc92c0a3 | |
Vitaly Chikunov | 544479d704 | |
Vitaly Chikunov | 1ab0d2e983 | |
Vitaly Chikunov | 69e682b37b | |
Vitaly Chikunov | 47191f9b29 | |
Solar Designer | 55d28c9f23 | |
Valentin Obst | a78f3e5f3c | |
Valentin Obst | 0f13b59d09 | |
Solar Designer | 64adf26f22 | |
Patrick Schleizer | 563dc9a09c | |
Patrick Schleizer | 306c430aa7 | |
fluidog | 001768de0c | |
Adam_pi3 | 3d8e52e90b | |
Solar Designer | f37b478d25 | |
Vladimir D. Seleznev | eaf8347646 | |
RageLtMan | ef52dec6e1 | |
Adam_pi3 | 0e46fc41a5 | |
Solar Designer | 0fdb556076 | |
Vitaly Chikunov | 87159cd74a | |
Solar Designer | 2481b3e2dd | |
Solar Designer | 2ab926d202 | |
Adam_pi3 | 26f36ed495 | |
Solar Designer | 7db7483880 | |
Adam_pi3 | 1fc5312223 | |
redp | 2cd2c2bc00 | |
redp | 6736d568dc | |
Solar Designer | 3f7af09f5b | |
Solar Designer | fc3545696b | |
Adam_pi3 | ad03367344 | |
Vladimir D. Seleznev | a4e5c00f13 | |
Vladimir D. Seleznev | 8fbdbda372 | |
Solar Designer | 4da9ded1a2 | |
Solar Designer | f32f627950 | |
Solar Designer | 11553ec0df | |
Solar Designer | 2241a32231 | |
Adam_pi3 | 717137dbd2 | |
mrl5 | d7f079baa1 | |
Vitaly Chikunov | b56b8758af | |
Vitaly Chikunov | db42541477 | |
Solar Designer | ff18ec6856 | |
Solar Designer | 333ae0774e | |
Solar Designer | c58cb52145 | |
Solar Designer | 9dd2a8d3f7 | |
Adam_pi3 | 6f3627e32c | |
Solar Designer | dfb60a6eb2 | |
Solar Designer | e773798649 | |
Vitaly Chikunov | 09a156a53e |
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
48
CHANGES
|
@ -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+
|
||||
|
|
4
LICENSE
4
LICENSE
|
@ -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
|
||||
|
|
3
Makefile
3
Makefile
|
@ -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
42
README
|
@ -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:
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1 +1 @@
|
|||
lkrg-dkms: repeated-path-segment src usr/src/lkrg-*/src/
|
||||
lkrg-dkms: repeated-path-segment src [usr/src/lkrg-*/src/]
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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.
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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! */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -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]",
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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)
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 { \
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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; \
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue