-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathkgraft_patcher.c
99 lines (82 loc) · 2.24 KB
/
kgraft_patcher.c
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
98
/*
* 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/kallsyms.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
*/
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 = ¤t->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;
}
KGR_PATCHED_FUNCTION(SyS_iopl, kgr_new_sys_iopl, true);
static bool new_capable(int cap)
{
printk(KERN_DEBUG "kgr-patcher: this is a new capable()\n");
return ns_capable(&init_user_ns, cap);
}
KGR_PATCHED_FUNCTION(capable, new_capable, true);
static void new_function(unsigned long data)
{
pr_info("kgr-patcher: %s\n", __func__);
}
KGR_PATCHED_FUNCTION(unknown_function, new_function, false);
static struct kgr_patch patch = {
.patches = {
KGR_PATCH(SyS_iopl),
KGR_PATCH(capable),
KGR_PATCH(unknown_function),
KGR_PATCH_END
}
};
static int __init kgr_patcher_init(void)
{
/* removing not supported */
__module_get(THIS_MODULE);
kgr_start_patching(&patch);
return 0;
}
static void __exit kgr_patcher_cleanup(void)
{
/* extra care needs to be taken when freeing ftrace_ops->private */
pr_err("removing now buggy!\n");
}
module_init(kgr_patcher_init);
module_exit(kgr_patcher_cleanup);
MODULE_LICENSE("GPL");