aboutsummaryrefslogtreecommitdiffstats
path: root/samples/kgraft/kgraft_patcher.c
blob: c4617eccf75e16595763a39442000b4d7d2ca3fd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/*
 * kgraft_patcher -- just kick the kGraft infrastructure for test
 *
 * We patch two (arbitrarily chosen) functions at once...
 *
 *  Copyright (c) 2013-2014 SUSE
 *   Authors: Jiri Kosina
 *	      Vojtech Pavlik
 *	      Jiri Slaby
 */

/*
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/kgraft.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/capability.h>
#include <linux/ptrace.h>

#include <asm/processor.h>

/*
 * This all should be autogenerated from the patched sources
 */

#if defined(CONFIG_X86)
asmlinkage long kgr_new_sys_iopl(unsigned int level)
{
	struct pt_regs *regs = current_pt_regs();
	unsigned int old = (regs->flags >> 12) & 3;
	struct thread_struct *t = &current->thread;

	printk(KERN_DEBUG "kgr-patcher: this is a new sys_iopl()\n");

	if (level > 3)
		return -EINVAL;
	/* Trying to gain more privileges? */
	if (level > old) {
		if (!capable(CAP_SYS_RAWIO))
			return -EPERM;
	}
	regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
	t->iopl = level << 12;
	set_iopl_mask(t->iopl);

	return 0;
}
#endif

static bool kgr_new_capable(int cap)
{
	printk(KERN_DEBUG "kgr-patcher: this is a new capable()\n");

	return ns_capable(&init_user_ns, cap);
}

static void kgr_new_function(unsigned long data)
{
	pr_info("kgr-patcher: %s\n", __func__);
}

static struct kgr_patch patch = {
	.name = "sample_patcher",
	.owner = THIS_MODULE,
	.patches = {
#if defined(CONFIG_X86)
		KGR_PATCH(SyS_iopl, kgr_new_sys_iopl),
#endif
		KGR_PATCH(capable, kgr_new_capable),
		KGR_PATCH_OBJ(unknown_function, kgr_new_function, "unknown_module"),
		KGR_PATCH_END
	}
};

static int __init kgr_patcher_init(void)
{
	return kgr_patch_kernel(&patch);
}

static void __exit kgr_patcher_cleanup(void)
{
	kgr_patch_remove(&patch);
}

module_init(kgr_patcher_init);
module_exit(kgr_patcher_cleanup);

MODULE_LICENSE("GPL");