162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * livepatch-sample.c - Kernel Live Patching Sample Module
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2014 Seth Jennings <sjenning@redhat.com>
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <linux/module.h>
1162306a36Sopenharmony_ci#include <linux/kernel.h>
1262306a36Sopenharmony_ci#include <linux/livepatch.h>
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci/*
1562306a36Sopenharmony_ci * This (dumb) live patch overrides the function that prints the
1662306a36Sopenharmony_ci * kernel boot cmdline when /proc/cmdline is read.
1762306a36Sopenharmony_ci *
1862306a36Sopenharmony_ci * Example:
1962306a36Sopenharmony_ci *
2062306a36Sopenharmony_ci * $ cat /proc/cmdline
2162306a36Sopenharmony_ci * <your cmdline>
2262306a36Sopenharmony_ci *
2362306a36Sopenharmony_ci * $ insmod livepatch-sample.ko
2462306a36Sopenharmony_ci * $ cat /proc/cmdline
2562306a36Sopenharmony_ci * this has been live patched
2662306a36Sopenharmony_ci *
2762306a36Sopenharmony_ci * $ echo 0 > /sys/kernel/livepatch/livepatch_sample/enabled
2862306a36Sopenharmony_ci * $ cat /proc/cmdline
2962306a36Sopenharmony_ci * <your cmdline>
3062306a36Sopenharmony_ci */
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci#include <linux/seq_file.h>
3362306a36Sopenharmony_cistatic int livepatch_cmdline_proc_show(struct seq_file *m, void *v)
3462306a36Sopenharmony_ci{
3562306a36Sopenharmony_ci	seq_printf(m, "%s\n", "this has been live patched");
3662306a36Sopenharmony_ci	return 0;
3762306a36Sopenharmony_ci}
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_cistatic struct klp_func funcs[] = {
4062306a36Sopenharmony_ci	{
4162306a36Sopenharmony_ci		.old_name = "cmdline_proc_show",
4262306a36Sopenharmony_ci		.new_func = livepatch_cmdline_proc_show,
4362306a36Sopenharmony_ci	}, { }
4462306a36Sopenharmony_ci};
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_cistatic struct klp_object objs[] = {
4762306a36Sopenharmony_ci	{
4862306a36Sopenharmony_ci		/* name being NULL means vmlinux */
4962306a36Sopenharmony_ci		.funcs = funcs,
5062306a36Sopenharmony_ci	}, { }
5162306a36Sopenharmony_ci};
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_cistatic struct klp_patch patch = {
5462306a36Sopenharmony_ci	.mod = THIS_MODULE,
5562306a36Sopenharmony_ci	.objs = objs,
5662306a36Sopenharmony_ci};
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_cistatic int livepatch_init(void)
5962306a36Sopenharmony_ci{
6062306a36Sopenharmony_ci	return klp_enable_patch(&patch);
6162306a36Sopenharmony_ci}
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_cistatic void livepatch_exit(void)
6462306a36Sopenharmony_ci{
6562306a36Sopenharmony_ci}
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_cimodule_init(livepatch_init);
6862306a36Sopenharmony_cimodule_exit(livepatch_exit);
6962306a36Sopenharmony_ciMODULE_LICENSE("GPL");
7062306a36Sopenharmony_ciMODULE_INFO(livepatch, "Y");
71