Skip to content

Commit

Permalink
Import existing files into repository
Browse files Browse the repository at this point in the history
  • Loading branch information
donald committed Jan 25, 2022
0 parents commit 8a1b7cc
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
out
*.o
24 changes: 24 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#! /bin/bash

set -xe

releases=(
5.10.92-421 5.10.82-414 5.10.70-403 5.10.47-390 5.10.24-375
5.4.97-368 5.4.72-349 5.4.57-340 5.4.39-334
)

for release in "${releases[@]}"; do
test -d /scratch/local/linux-$release.x86_64 || (cd /scratch/local && tar xf /src/mariux/beeroot/build-archives/linux-$release.x86_64.beebuild.tar.bz2)
(
cd fix-lpp
KERNEL=/scratch/local/linux-$release.x86_64/build make clean
KERNEL=/scratch/local/linux-$release.x86_64/build make
)
ver=${release%-*} # 5.10.92
build=${release#*-} # 421
echo "release $release ver $ver build $build"
mkdir -p out/$ver.mx64.$build
cp fix-lpp/fix-lpp.ko out/$ver.mx64.$build/fix-lpp.ko
done


6 changes: 6 additions & 0 deletions fix-lpp/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
*.cmd
Module.symvers
*.ko
*.mod
*.mod.c
modules.order
7 changes: 7 additions & 0 deletions fix-lpp/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
obj-m += fix-lpp.o

all:
make -C $(KERNEL) M=$(PWD) modules

clean:
make -C $(KERNEL) M=$(PWD) clean
130 changes: 130 additions & 0 deletions fix-lpp/fix-lpp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/ftrace.h>
#include <linux/printk.h>
#include <linux/kprobes.h>
#include <linux/fs_context.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Donald Buczek <buczek@molgen.mpg.de>");
MODULE_DESCRIPTION("fix-lpp");
MODULE_VERSION("0.01");

/*
* General concept to hook a kernel function with ftrace:
*
* https://www.codeproject.com/Articles/1275114/Hooking-Linux-Kernel-Functions-Part-2-How-to-Hook
*
* Idea to hack around the no longer exported kallsyms_lookup_name with register_kprobe
* originally from AMD developers in the comments of this thread:
*
* https://lwn.net/Articles/813350/
*/

/* function signature as defined in kernel source */

typedef int legacy_parse_param_fn_type(struct fs_context *fc, struct fs_parameter *param);

static legacy_parse_param_fn_type *legacy_parse_param;
static legacy_parse_param_fn_type legacy_parse_param_wrapper;

enum legacy_fs_param {
LEGACY_FS_UNSET_PARAMS,
LEGACY_FS_MONOLITHIC_PARAMS,
LEGACY_FS_INDIVIDUAL_PARAMS,
};

struct legacy_fs_context {
char *legacy_data; /* Data page for legacy filesystems */
size_t data_size;
enum legacy_fs_param param_type;
};

static __attribute__((optimize("no-optimize-sibling-calls")))
int legacy_parse_param_wrapper(struct fs_context *fc, struct fs_parameter *param)
{
struct legacy_fs_context *ctx = fc->fs_private;
unsigned int size = ctx->data_size;
size_t len = 0;

switch (param->type) {
case fs_value_is_string:
len = 1 + param->size;
fallthrough;
case fs_value_is_flag:
len += strlen(param->key);
break;
default:
break;
}
if (size + len + 2 > PAGE_SIZE)
return invalf(fc, "VFS: Legacy: Cumulative options too large");

return legacy_parse_param(fc, param);
}

static void ftrace_callback(unsigned long ip, unsigned long parent_ip, struct ftrace_ops *ops, struct pt_regs *regs)
{
if (!within_module(parent_ip, THIS_MODULE))
regs->ip = (unsigned long)legacy_parse_param_wrapper;
}

static int get_symbol_via_kprobe(char *name, void **addr)
{
struct kprobe kp;
int err;
memset(&kp, 0, sizeof(kp));
kp.symbol_name = name;
err = register_kprobe(&kp);
if (err) {
return err;
}
*addr = kp.addr;
unregister_kprobe(&kp);
return 0;
}

static struct ftrace_ops ops = {
.func = ftrace_callback,
.flags = FTRACE_OPS_FL_SAVE_REGS|FTRACE_OPS_FL_IPMODIFY
};

static int __init fix_lpp_init(void)
{
int err;

err = get_symbol_via_kprobe("legacy_parse_param", (void **)&legacy_parse_param);
if (err) {
pr_err("fix_lpp: can't find legacy_parse_param: %d\n", err);
return(err);
}

err = ftrace_set_filter_ip(&ops, (unsigned long)legacy_parse_param, 0, 0);
if (err) {
pr_err("fix_lpp: ftrace_set_filter_ip failed: %d\n", err);
return(err);

}
err = register_ftrace_function(&ops);
if (err) {
pr_err("fix_lpp: register_ftrace_function failed: %d\n", err);
return(err);

}
pr_info("fix-lpp: installed\n");
return 0;
}

static void __exit fix_lpp_exit(void)
{
int err;
err = unregister_ftrace_function(&ops);
if (err) {
pr_err("fix_lpp: unregister_ftrace_function failed: %d\n", err);
}
pr_info("fix-lpp: removed\n");
}

module_init(fix_lpp_init);
module_exit(fix_lpp_exit);

0 comments on commit 8a1b7cc

Please sign in to comment.