8000 From 5.7 the kallsyms_lookup_name() is unexported; we work around · skamati/Linux-Kernel-Programming@7f04301 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7f04301

Browse files
committed
From 5.7 the kallsyms_lookup_name() is unexported; we work around
it by using a wrapper script to lookup and pass the addr of sched_setaffinity()
1 parent eaef3db commit 7f04301

File tree

2 files changed

+60
-13
lines changed

2 files changed

+60
-13
lines changed

ch13/2_percpu/percpu_var.c

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ MODULE_DESCRIPTION("LKP book:ch13/2_percpu: demo of using percpu variables");
3535
MODULE_LICENSE("Dual MIT/GPL");
3636
MODULE_VERSION("0.1");
3737

38+
3839
#define SHOW_CPU_CTX() do { \
3940
pr_info("*** kthread PID %d on cpu %d now ***\n",\
4041
current->pid, smp_processor_id()); \
@@ -44,7 +45,12 @@ MODULE_VERSION("0.1");
4445
#define THRD0_ITERS 3
4546
#define THRD1_ITERS 3
4647

47-
static long (*ptr_sched_setaffinity)(pid_t, const struct cpumask *);
48+
static unsigned long func_ptr;
49+
module_param(func_ptr, ulong, 0);
50+
51+
// schedsa_ptr is our function pointer to the sched_setaffinity() function
52+
unsigned long (*schedsa_ptr)(pid_t, const struct cpumask *) = NULL;
53+
4854
static struct task_struct *arr_tsk[MAX_KTHRDS];
4955

5056
/*--- The percpu variables, an integer 'pcpa' and a data structure --- */
@@ -79,12 +85,13 @@ static long set_cpuaffinity(unsigned int cpu)
7985
{
8086
struct cpumask mask;
8187
long ret = 0;
88+
8289
unsigned int euid = from_kuid(&init_user_ns, current_euid());
8390
struct cred *new;
8491

8592
/*
8693
* Not root? get root! (hey, we're in kernel mode :)
87-
* This isn't really required; we're just showing how to...
94+
* This isn't really required; we're just showing off...
8895
*/
8996
if (unlikely(euid)) {
9097
pr_info("%s(): before commit_creds(): uid=%u euid=%u\n",
@@ -109,8 +116,9 @@ static long set_cpuaffinity(unsigned int cpu)
109116
cpumask_set_cpu(cpu, &mask); // 1st param is the CPU number, not bitmask
110117
/* !HACK! sched_setaffinity() is NOT exported, we can't call it
111118
* sched_setaffinity(0, &mask); // 0 => on self
112-
* so we invoke it via it's function pointer */
113-
ret = (*ptr_sched_setaffinity)(0, &mask); // 0 => on self
119+
* so we invoke it via it's function pointer
120+
*/
121+
ret = (*schedsa_ptr)(0, &mask); // 0 => on self
114122

115123
return ret;
116124
}
@@ -190,27 +198,34 @@ static int run_kthrd(char *kname, long thrdnum)
190198
return 0;
191199
}
192200

201+
193202
static int __init init_percpu_var(void)
194203
{
195204
int ret = 0;
196205

197206
pr_info("inserted\n");
198207

199-
/* WARNING! This is considered a hack.
208+
/* !WARNING! This is considered a hack.
200209
* As sched_setaffinity() isn't exported, we don't have access to it
201-
* within this kernel module. So, here we resort to a hack: we use
202-
* kallsyms_lookup_name() (which works when CONFIG_KALLSYMS is defined)
203-
* to retrieve the function pointer, subsequently calling the function
204-
* via it's pointer (with 'C' what you do is only limited by your
205-
* imagination :). Not pedantically right, but hey, it works.
210+
* within this kernel module. So, here we resort to a hack:
211+
* a) Until 5.7, we could directly use the kallsyms_lookup_name() function
212+
* (which works when CONFIG_KALLSYMS is defined) to retrieve the function
213+
* pointer, and subsequently call the function via it's pointer (with 'C'
214+
* what you do is only limited by your imagination :).
215+
* b) From 5.7 on, the kernel devs unexported the kallsyms_lookup_name()!
216+
* (Rationale: https://lwn.net/Articles/813350/). With it gone, we now
217+
* simply use this approach: a helper script greps the kallsyms_lookup_name()
218+
* address and passes it to this module! We equate it to the exepcted
219+
* function signature - that of sched_setaffinity() - and use it.
220+
* *Not* pedantically right, but hey, it works. Don't do this in production.
206221
*/
207222
ret = -ENOSYS;
208-
ptr_sched_setaffinity = (void *)kallsyms_lookup_name("sched_setaffinity");
209-
if (!ptr_sched_setaffinity) {
223+
if (!func_ptr) {
210224
pr_warn("%s: couldn't obtain sched_setaffinity() addr via "
211-
"kallsyms_lookup_name(), aborting ...\n", OURMODNAME);
225+
"module param, aborting ...\n", OURMODNAME);
212226
return ret;
213227
}
228+
schedsa_ptr = (unsigned long (*)(pid_t pid, const struct cpumask *in_mask))func_ptr;
214229

215230
/* Dynamically allocate the percpu structures */
216231
ret = -ENOMEM;

ch13/2_percpu/run

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/bin/bash
2+
# Wrapper script to correctly load up the percpu_var.ko module.
3+
4+
# !WARNING! This is considered a hack.
5+
# As sched_setaffinity() isn't exported, we don't have access to it
6+
# within this kernel module. So, here we resort to a hack:
7+
# a) Until 5.7, we could directly use the kallsyms_lookup_name() function
8+
# (which works when CONFIG_KALLSYMS is defined) to retrieve the function
9+
# pointer, and subsequently call the function via it's pointer (with 'C'
10+
# what you do is only limited by your imagination :).
11+
# b) From 5.7 on, the kernel devs unexported the kallsyms_lookup_name()!
12+
# (Rationale: https://lwn.net/Articles/813350/). With it gone, we now
13+
# simply use this approach: a helper script greps the kallsyms_lookup_name()
14+
# address and passes it to the module! There, we equate it to the exepcted
15+
# function signature - that of sched_setaffinity() - and use it.
16+
# *Not* pedantically right, but hey, it works. Don't do this in production.
17+
#
18+
KMOD=percpu_var
19+
KFUNC=sched_setaffinity
20+
KFUNC_PTR=0x$(sudo grep -w "T ${KFUNC}" /proc/kallsyms |awk '{print $1}')
21+
[[ -z "${KFUNC_PTR}" ]] && {
22+
echo "${name}: lookup of kallsyms_lookup_name() failed, aborting..."
23+
exit 1
24+
}
25+
echo "KFUNC_PTR=${KFUNC_PTR}"
26+
27+
make clean
28+
make
29+
sudo rmmod ${KMOD} 2>/dev/null
30+
sudo dmesg -C
31+
sudo insmod ./${KMOD}.ko func_ptr=${KFUNC_PTR}
32+
sudo dmesg

0 commit comments

Comments
 (0)
0